am 3445dae3
: am 65b2561c
: Merge "Fix issue #2643754: Launcher is caching widget layouts for too long" into froyo
Merge commit '3445dae3f52fa8421e3b93496ac93c5753a43bd2' into kraken * commit '3445dae3f52fa8421e3b93496ac93c5753a43bd2': Fix issue #2643754: Launcher is caching widget layouts for too long
This commit is contained in:
@ -194,6 +194,7 @@ public final class ActivityThread {
|
|||||||
}
|
}
|
||||||
WeakReference<Resources> wr = mActiveResources.get(key);
|
WeakReference<Resources> wr = mActiveResources.get(key);
|
||||||
r = wr != null ? wr.get() : null;
|
r = wr != null ? wr.get() : null;
|
||||||
|
//if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
|
||||||
if (r != null && r.getAssets().isUpToDate()) {
|
if (r != null && r.getAssets().isUpToDate()) {
|
||||||
if (false) {
|
if (false) {
|
||||||
Slog.w(TAG, "Returning cached resources " + r + " " + resDir
|
Slog.w(TAG, "Returning cached resources " + r + " " + resDir
|
||||||
@ -1752,6 +1753,10 @@ public final class ActivityThread {
|
|||||||
Debug.getMemoryInfo(outInfo);
|
Debug.getMemoryInfo(outInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispatchPackageBroadcast(int cmd, String[] packages) {
|
||||||
|
queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||||
long nativeMax = Debug.getNativeHeapSize() / 1024;
|
long nativeMax = Debug.getNativeHeapSize() / 1024;
|
||||||
@ -1976,6 +1981,7 @@ public final class ActivityThread {
|
|||||||
public static final int SUICIDE = 130;
|
public static final int SUICIDE = 130;
|
||||||
public static final int REMOVE_PROVIDER = 131;
|
public static final int REMOVE_PROVIDER = 131;
|
||||||
public static final int ENABLE_JIT = 132;
|
public static final int ENABLE_JIT = 132;
|
||||||
|
public static final int DISPATCH_PACKAGE_BROADCAST = 133;
|
||||||
String codeToString(int code) {
|
String codeToString(int code) {
|
||||||
if (localLOGV) {
|
if (localLOGV) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
@ -2012,6 +2018,7 @@ public final class ActivityThread {
|
|||||||
case SUICIDE: return "SUICIDE";
|
case SUICIDE: return "SUICIDE";
|
||||||
case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
|
case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
|
||||||
case ENABLE_JIT: return "ENABLE_JIT";
|
case ENABLE_JIT: return "ENABLE_JIT";
|
||||||
|
case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "(unknown)";
|
return "(unknown)";
|
||||||
@ -2132,6 +2139,9 @@ public final class ActivityThread {
|
|||||||
case ENABLE_JIT:
|
case ENABLE_JIT:
|
||||||
ensureJitEnabled();
|
ensureJitEnabled();
|
||||||
break;
|
break;
|
||||||
|
case DISPATCH_PACKAGE_BROADCAST:
|
||||||
|
handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2244,7 +2254,7 @@ public final class ActivityThread {
|
|||||||
= new HashMap<String, WeakReference<PackageInfo>>();
|
= new HashMap<String, WeakReference<PackageInfo>>();
|
||||||
Display mDisplay = null;
|
Display mDisplay = null;
|
||||||
DisplayMetrics mDisplayMetrics = null;
|
DisplayMetrics mDisplayMetrics = null;
|
||||||
HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
|
final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
|
||||||
= new HashMap<ResourcesKey, WeakReference<Resources> >();
|
= new HashMap<ResourcesKey, WeakReference<Resources> >();
|
||||||
final ArrayList<ActivityRecord> mRelaunchingActivities
|
final ArrayList<ActivityRecord> mRelaunchingActivities
|
||||||
= new ArrayList<ActivityRecord>();
|
= new ArrayList<ActivityRecord>();
|
||||||
@ -2271,6 +2281,8 @@ public final class ActivityThread {
|
|||||||
}
|
}
|
||||||
PackageInfo packageInfo = ref != null ? ref.get() : null;
|
PackageInfo packageInfo = ref != null ? ref.get() : null;
|
||||||
//Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
|
//Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
|
||||||
|
//if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
|
||||||
|
// + ": " + packageInfo.mResources.getAssets().isUpToDate());
|
||||||
if (packageInfo != null && (packageInfo.mResources == null
|
if (packageInfo != null && (packageInfo.mResources == null
|
||||||
|| packageInfo.mResources.getAssets().isUpToDate())) {
|
|| packageInfo.mResources.getAssets().isUpToDate())) {
|
||||||
if (packageInfo.isSecurityViolation()
|
if (packageInfo.isSecurityViolation()
|
||||||
@ -2358,21 +2370,6 @@ public final class ActivityThread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasPackageInfo(String packageName) {
|
|
||||||
synchronized (mPackages) {
|
|
||||||
WeakReference<PackageInfo> ref;
|
|
||||||
ref = mPackages.get(packageName);
|
|
||||||
if (ref != null && ref.get() != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
ref = mResourcePackages.get(packageName);
|
|
||||||
if (ref != null && ref.get() != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityThread() {
|
ActivityThread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4054,6 +4051,31 @@ public final class ActivityThread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
|
||||||
|
boolean hasPkgInfo = false;
|
||||||
|
if (packages != null) {
|
||||||
|
for (int i=packages.length-1; i>=0; i--) {
|
||||||
|
//Slog.i(TAG, "Cleaning old package: " + packages[i]);
|
||||||
|
if (!hasPkgInfo) {
|
||||||
|
WeakReference<PackageInfo> ref;
|
||||||
|
ref = mPackages.get(packages[i]);
|
||||||
|
if (ref != null && ref.get() != null) {
|
||||||
|
hasPkgInfo = true;
|
||||||
|
} else {
|
||||||
|
ref = mResourcePackages.get(packages[i]);
|
||||||
|
if (ref != null && ref.get() != null) {
|
||||||
|
hasPkgInfo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPackages.remove(packages[i]);
|
||||||
|
mResourcePackages.remove(packages[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ContextImpl.ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
|
||||||
|
hasPkgInfo);
|
||||||
|
}
|
||||||
|
|
||||||
final void handleLowMemory() {
|
final void handleLowMemory() {
|
||||||
ArrayList<ComponentCallbacks> callbacks
|
ArrayList<ComponentCallbacks> callbacks
|
||||||
= new ArrayList<ComponentCallbacks>();
|
= new ArrayList<ComponentCallbacks>();
|
||||||
|
@ -393,6 +393,15 @@ public abstract class ApplicationThreadNative extends Binder
|
|||||||
mi.writeToParcel(reply, 0);
|
mi.writeToParcel(reply, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DISPATCH_PACKAGE_BROADCAST_TRANSACTION:
|
||||||
|
{
|
||||||
|
data.enforceInterface(IApplicationThread.descriptor);
|
||||||
|
int cmd = data.readInt();
|
||||||
|
String[] packages = data.readStringArray();
|
||||||
|
dispatchPackageBroadcast(cmd, packages);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onTransact(code, data, reply, flags);
|
return super.onTransact(code, data, reply, flags);
|
||||||
@ -806,5 +815,16 @@ class ApplicationThreadProxy implements IApplicationThread {
|
|||||||
data.recycle();
|
data.recycle();
|
||||||
reply.recycle();
|
reply.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException {
|
||||||
|
Parcel data = Parcel.obtain();
|
||||||
|
data.writeInterfaceToken(IApplicationThread.descriptor);
|
||||||
|
data.writeInt(cmd);
|
||||||
|
data.writeStringArray(packages);
|
||||||
|
mRemote.transact(DISPATCH_PACKAGE_BROADCAST_TRANSACTION, data, null,
|
||||||
|
IBinder.FLAG_ONEWAY);
|
||||||
|
data.recycle();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,33 +2277,7 @@ class ContextImpl extends Context {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void establishPackageRemovedReceiver() {
|
|
||||||
// mContext.registerReceiverInternal() winds up acquiring the
|
|
||||||
// main ActivityManagerService.this lock. If we hold our usual
|
|
||||||
// sSync global lock at the same time, we impose a required ordering
|
|
||||||
// on those two locks, which is not good for deadlock prevention.
|
|
||||||
// Use a dedicated lock around initialization of
|
|
||||||
// sPackageRemovedReceiver to avoid this.
|
|
||||||
synchronized (sPackageRemovedSync) {
|
|
||||||
if (sPackageRemovedReceiver == null) {
|
|
||||||
sPackageRemovedReceiver = new PackageRemovedReceiver();
|
|
||||||
IntentFilter filter = new IntentFilter(
|
|
||||||
Intent.ACTION_PACKAGE_REMOVED);
|
|
||||||
filter.addDataScheme("package");
|
|
||||||
mContext.registerReceiverInternal(sPackageRemovedReceiver,
|
|
||||||
filter, null, null, null);
|
|
||||||
// Register for events related to sdcard installation.
|
|
||||||
IntentFilter sdFilter = new IntentFilter();
|
|
||||||
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
|
|
||||||
mContext.registerReceiverInternal(sPackageRemovedReceiver,
|
|
||||||
sdFilter, null, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void putCachedIcon(ResourceName name, Drawable dr) {
|
private void putCachedIcon(ResourceName name, Drawable dr) {
|
||||||
establishPackageRemovedReceiver();
|
|
||||||
|
|
||||||
synchronized (sSync) {
|
synchronized (sSync) {
|
||||||
sIconCache.put(name, new WeakReference<Drawable>(dr));
|
sIconCache.put(name, new WeakReference<Drawable>(dr));
|
||||||
if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
|
if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
|
||||||
@ -2311,29 +2285,17 @@ class ContextImpl extends Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class PackageRemovedReceiver extends BroadcastReceiver {
|
static final void handlePackageBroadcast(int cmd, String[] pkgList,
|
||||||
@Override
|
boolean hasPkgInfo) {
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
String pkgList[] = null;
|
|
||||||
String action = intent.getAction();
|
|
||||||
boolean immediateGc = false;
|
boolean immediateGc = false;
|
||||||
if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
|
if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
|
||||||
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
|
|
||||||
immediateGc = true;
|
immediateGc = true;
|
||||||
} else {
|
|
||||||
Uri data = intent.getData();
|
|
||||||
if (data != null) {
|
|
||||||
String ssp = data.getSchemeSpecificPart();
|
|
||||||
if (ssp != null) {
|
|
||||||
pkgList = new String[] { ssp };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (pkgList != null && (pkgList.length > 0)) {
|
if (pkgList != null && (pkgList.length > 0)) {
|
||||||
boolean needCleanup = false;
|
boolean needCleanup = false;
|
||||||
boolean hasPkgInfo = false;
|
|
||||||
for (String ssp : pkgList) {
|
for (String ssp : pkgList) {
|
||||||
synchronized (sSync) {
|
synchronized (sSync) {
|
||||||
|
if (sIconCache.size() > 0) {
|
||||||
Iterator<ResourceName> it = sIconCache.keySet().iterator();
|
Iterator<ResourceName> it = sIconCache.keySet().iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
ResourceName nm = it.next();
|
ResourceName nm = it.next();
|
||||||
@ -2343,7 +2305,9 @@ class ContextImpl extends Context {
|
|||||||
needCleanup = true;
|
needCleanup = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it = sStringCache.keySet().iterator();
|
}
|
||||||
|
if (sStringCache.size() > 0) {
|
||||||
|
Iterator<ResourceName> it = sStringCache.keySet().iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
ResourceName nm = it.next();
|
ResourceName nm = it.next();
|
||||||
if (nm.packageName.equals(ssp)) {
|
if (nm.packageName.equals(ssp)) {
|
||||||
@ -2353,8 +2317,6 @@ class ContextImpl extends Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasPkgInfo) {
|
|
||||||
hasPkgInfo = ActivityThread.currentActivityThread().hasPackageInfo(ssp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (needCleanup || hasPkgInfo) {
|
if (needCleanup || hasPkgInfo) {
|
||||||
@ -2367,7 +2329,6 @@ class ContextImpl extends Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static final class ResourceName {
|
private static final class ResourceName {
|
||||||
final String packageName;
|
final String packageName;
|
||||||
@ -2433,8 +2394,6 @@ class ContextImpl extends Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void putCachedString(ResourceName name, CharSequence cs) {
|
private void putCachedString(ResourceName name, CharSequence cs) {
|
||||||
establishPackageRemovedReceiver();
|
|
||||||
|
|
||||||
synchronized (sSync) {
|
synchronized (sSync) {
|
||||||
sStringCache.put(name, new WeakReference<CharSequence>(cs));
|
sStringCache.put(name, new WeakReference<CharSequence>(cs));
|
||||||
}
|
}
|
||||||
@ -2698,8 +2657,6 @@ class ContextImpl extends Context {
|
|||||||
private final IPackageManager mPM;
|
private final IPackageManager mPM;
|
||||||
|
|
||||||
private static final Object sSync = new Object();
|
private static final Object sSync = new Object();
|
||||||
private static final Object sPackageRemovedSync = new Object();
|
|
||||||
private static BroadcastReceiver sPackageRemovedReceiver;
|
|
||||||
private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
|
private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
|
||||||
= new HashMap<ResourceName, WeakReference<Drawable> >();
|
= new HashMap<ResourceName, WeakReference<Drawable> >();
|
||||||
private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
|
private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
|
||||||
|
@ -100,6 +100,9 @@ public interface IApplicationThread extends IInterface {
|
|||||||
throws RemoteException;
|
throws RemoteException;
|
||||||
void setSchedulingGroup(int group) throws RemoteException;
|
void setSchedulingGroup(int group) throws RemoteException;
|
||||||
void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException;
|
void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException;
|
||||||
|
static final int PACKAGE_REMOVED = 0;
|
||||||
|
static final int EXTERNAL_STORAGE_UNAVAILABLE = 1;
|
||||||
|
void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException;
|
||||||
|
|
||||||
String descriptor = "android.app.IApplicationThread";
|
String descriptor = "android.app.IApplicationThread";
|
||||||
|
|
||||||
@ -135,4 +138,5 @@ public interface IApplicationThread extends IInterface {
|
|||||||
int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
|
int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
|
||||||
int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
|
int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
|
||||||
int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
|
int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
|
||||||
|
int DISPATCH_PACKAGE_BROADCAST_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
|
||||||
}
|
}
|
||||||
|
@ -12269,6 +12269,18 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
|
||||||
|
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
|
||||||
|
ProcessRecord r = mLruProcesses.get(i);
|
||||||
|
if (r.thread != null) {
|
||||||
|
try {
|
||||||
|
r.thread.dispatchPackageBroadcast(cmd, packages);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final int broadcastIntentLocked(ProcessRecord callerApp,
|
private final int broadcastIntentLocked(ProcessRecord callerApp,
|
||||||
String callerPackage, Intent intent, String resolvedType,
|
String callerPackage, Intent intent, String resolvedType,
|
||||||
IIntentReceiver resultTo, int resultCode, String resultData,
|
IIntentReceiver resultTo, int resultCode, String resultData,
|
||||||
@ -12315,6 +12327,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
for (String pkg : list) {
|
for (String pkg : list) {
|
||||||
forceStopPackageLocked(pkg, -1, false, true, true);
|
forceStopPackageLocked(pkg, -1, false, true, true);
|
||||||
}
|
}
|
||||||
|
sendPackageBroadcastLocked(
|
||||||
|
IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Uri data = intent.getData();
|
Uri data = intent.getData();
|
||||||
@ -12324,6 +12338,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
forceStopPackageLocked(ssp,
|
forceStopPackageLocked(ssp,
|
||||||
intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
|
intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
|
||||||
}
|
}
|
||||||
|
if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
|
||||||
|
sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
|
||||||
|
new String[] {ssp});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user