summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenny Guy <kennyguy@google.com>2014-07-28 19:20:07 +0100
committerKenny Guy <kennyguy@google.com>2014-07-30 11:21:01 +0000
commitb42c89bfb0415d2a4b1d8b7247309f15fd348974 (patch)
tree2ae889793571ea0c4dddc51230df469b5dd863d4
parent6c9eee87476411faebcfa68c82abaae86344ef91 (diff)
downloadframeworks_base-b42c89bfb0415d2a4b1d8b7247309f15fd348974.zip
frameworks_base-b42c89bfb0415d2a4b1d8b7247309f15fd348974.tar.gz
frameworks_base-b42c89bfb0415d2a4b1d8b7247309f15fd348974.tar.bz2
Add optional handler to LauncherApps callback
Allow caller to pass in handler to LauncherApps when adding a callback. Stop apps adding callbacks twice. Bug: 16401733 Change-Id: I2e192091c1b79acb905d899e96d6dacd45e561da
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/content/pm/LauncherApps.java164
2 files changed, 149 insertions, 16 deletions
diff --git a/api/current.txt b/api/current.txt
index d1ece22..a261bd6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8582,6 +8582,7 @@ package android.content.pm {
public class LauncherApps {
method public void addOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback);
+ method public void addOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback, android.os.Handler);
method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
method public boolean isActivityEnabledForProfile(android.content.ComponentName, android.os.UserHandle);
method public boolean isPackageEnabledForProfile(java.lang.String, android.os.UserHandle);
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index c95a5bf..8c37e9e 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -25,6 +25,9 @@ import android.content.pm.IOnAppsChangedListener;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -55,8 +58,8 @@ public class LauncherApps {
private ILauncherApps mService;
private PackageManager mPm;
- private List<OnAppsChangedCallback> mCallbacks
- = new ArrayList<OnAppsChangedCallback>();
+ private List<CallbackMessageHandler> mCallbacks
+ = new ArrayList<CallbackMessageHandler>();
/**
* Callbacks for package changes to this and related managed profiles.
@@ -65,6 +68,9 @@ public class LauncherApps {
/**
* Indicates that a package was removed from the specified profile.
*
+ * If a package is removed while being updated onPackageChanged will be
+ * called instead.
+ *
* @param packageName The name of the package that was removed.
* @param user The UserHandle of the profile that generated the change.
*/
@@ -73,6 +79,9 @@ public class LauncherApps {
/**
* Indicates that a package was added to the specified profile.
*
+ * If a package is added while being updated then onPackageChanged will be
+ * called instead.
+ *
* @param packageName The name of the package that was added.
* @param user The UserHandle of the profile that generated the change.
*/
@@ -80,6 +89,8 @@ public class LauncherApps {
/**
* Indicates that a package was modified in the specified profile.
+ * This can happen, for example, when the package is updated or when
+ * one or more components are enabled or disabled.
*
* @param packageName The name of the package that has changed.
* @param user The UserHandle of the profile that generated the change.
@@ -286,10 +297,21 @@ public class LauncherApps {
* @param callback The callback to add.
*/
public void addOnAppsChangedCallback(OnAppsChangedCallback callback) {
+ addOnAppsChangedCallback(callback, null);
+ }
+
+ /**
+ * Adds a callback for changes to packages in current and managed profiles.
+ *
+ * @param callback The callback to add.
+ * @param handler that should be used to post callbacks on, may be null.
+ */
+ public void addOnAppsChangedCallback(OnAppsChangedCallback callback, Handler handler) {
synchronized (this) {
if (callback != null && !mCallbacks.contains(callback)) {
- mCallbacks.add(callback);
- if (mCallbacks.size() == 1) {
+ boolean addedFirstCallback = mCallbacks.size() == 0;
+ addCallbackLocked(callback, handler);
+ if (addedFirstCallback) {
try {
mService.addOnAppsChangedListener(mAppsChangedListener);
} catch (RemoteException re) {
@@ -307,7 +329,7 @@ public class LauncherApps {
*/
public void removeOnAppsChangedCallback(OnAppsChangedCallback callback) {
synchronized (this) {
- mCallbacks.remove(callback);
+ removeCallbackLocked(callback);
if (mCallbacks.size() == 0) {
try {
mService.removeOnAppsChangedListener(mAppsChangedListener);
@@ -317,16 +339,40 @@ public class LauncherApps {
}
}
+ private void removeCallbackLocked(OnAppsChangedCallback callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("Callback cannot be null");
+ }
+ final int size = mCallbacks.size();
+ for (int i = 0; i < size; ++i) {
+ if (mCallbacks.get(i).mCallback == callback) {
+ mCallbacks.remove(i);
+ return;
+ }
+ }
+ }
+
+ private void addCallbackLocked(OnAppsChangedCallback callback, Handler handler) {
+ // Remove if already present.
+ removeCallbackLocked(callback);
+ if (handler == null) {
+ handler = new Handler();
+ }
+ CallbackMessageHandler toAdd = new CallbackMessageHandler(handler.getLooper(), callback);
+ mCallbacks.add(toAdd);
+ }
+
private IOnAppsChangedListener.Stub mAppsChangedListener = new IOnAppsChangedListener.Stub() {
@Override
- public void onPackageRemoved(UserHandle user, String packageName) throws RemoteException {
+ public void onPackageRemoved(UserHandle user, String packageName)
+ throws RemoteException {
if (DEBUG) {
Log.d(TAG, "onPackageRemoved " + user.getIdentifier() + "," + packageName);
}
synchronized (LauncherApps.this) {
- for (OnAppsChangedCallback callback : mCallbacks) {
- callback.onPackageRemoved(packageName, user);
+ for (CallbackMessageHandler callback : mCallbacks) {
+ callback.postOnPackageRemoved(packageName, user);
}
}
}
@@ -337,8 +383,8 @@ public class LauncherApps {
Log.d(TAG, "onPackageChanged " + user.getIdentifier() + "," + packageName);
}
synchronized (LauncherApps.this) {
- for (OnAppsChangedCallback callback : mCallbacks) {
- callback.onPackageChanged(packageName, user);
+ for (CallbackMessageHandler callback : mCallbacks) {
+ callback.postOnPackageChanged(packageName, user);
}
}
}
@@ -349,8 +395,8 @@ public class LauncherApps {
Log.d(TAG, "onPackageAdded " + user.getIdentifier() + "," + packageName);
}
synchronized (LauncherApps.this) {
- for (OnAppsChangedCallback callback : mCallbacks) {
- callback.onPackageAdded(packageName, user);
+ for (CallbackMessageHandler callback : mCallbacks) {
+ callback.postOnPackageAdded(packageName, user);
}
}
}
@@ -362,8 +408,8 @@ public class LauncherApps {
Log.d(TAG, "onPackagesAvailable " + user.getIdentifier() + "," + packageNames);
}
synchronized (LauncherApps.this) {
- for (OnAppsChangedCallback callback : mCallbacks) {
- callback.onPackagesAvailable(packageNames, user, replacing);
+ for (CallbackMessageHandler callback : mCallbacks) {
+ callback.postOnPackagesAvailable(packageNames, user, replacing);
}
}
}
@@ -375,10 +421,96 @@ public class LauncherApps {
Log.d(TAG, "onPackagesUnavailable " + user.getIdentifier() + "," + packageNames);
}
synchronized (LauncherApps.this) {
- for (OnAppsChangedCallback callback : mCallbacks) {
- callback.onPackagesUnavailable(packageNames, user, replacing);
+ for (CallbackMessageHandler callback : mCallbacks) {
+ callback.postOnPackagesUnavailable(packageNames, user, replacing);
}
}
}
};
+
+ private static class CallbackMessageHandler extends Handler {
+ private static final int MSG_ADDED = 1;
+ private static final int MSG_REMOVED = 2;
+ private static final int MSG_CHANGED = 3;
+ private static final int MSG_AVAILABLE = 4;
+ private static final int MSG_UNAVAILABLE = 5;
+
+ private OnAppsChangedCallback mCallback;
+
+ private static class CallbackInfo {
+ String[] packageNames;
+ String packageName;
+ boolean replacing;
+ UserHandle user;
+ }
+
+ public CallbackMessageHandler(Looper looper, OnAppsChangedCallback callback) {
+ super(looper, null, true);
+ mCallback = callback;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (mCallback == null || !(msg.obj instanceof CallbackInfo)) {
+ return;
+ }
+ CallbackInfo info = (CallbackInfo) msg.obj;
+ switch (msg.what) {
+ case MSG_ADDED:
+ mCallback.onPackageAdded(info.packageName, info.user);
+ break;
+ case MSG_REMOVED:
+ mCallback.onPackageRemoved(info.packageName, info.user);
+ break;
+ case MSG_CHANGED:
+ mCallback.onPackageChanged(info.packageName, info.user);
+ break;
+ case MSG_AVAILABLE:
+ mCallback.onPackagesAvailable(info.packageNames, info.user, info.replacing);
+ break;
+ case MSG_UNAVAILABLE:
+ mCallback.onPackagesUnavailable(info.packageNames, info.user, info.replacing);
+ break;
+ }
+ }
+
+ public void postOnPackageAdded(String packageName, UserHandle user) {
+ CallbackInfo info = new CallbackInfo();
+ info.packageName = packageName;
+ info.user = user;
+ obtainMessage(MSG_ADDED, info).sendToTarget();
+ }
+
+ public void postOnPackageRemoved(String packageName, UserHandle user) {
+ CallbackInfo info = new CallbackInfo();
+ info.packageName = packageName;
+ info.user = user;
+ obtainMessage(MSG_REMOVED, info).sendToTarget();
+ }
+
+ public void postOnPackageChanged(String packageName, UserHandle user) {
+ CallbackInfo info = new CallbackInfo();
+ info.packageName = packageName;
+ info.user = user;
+ obtainMessage(MSG_CHANGED, info).sendToTarget();
+ }
+
+ public void postOnPackagesAvailable(String[] packageNames, UserHandle user,
+ boolean replacing) {
+ CallbackInfo info = new CallbackInfo();
+ info.packageNames = packageNames;
+ info.replacing = replacing;
+ info.user = user;
+ obtainMessage(MSG_AVAILABLE, info).sendToTarget();
+ }
+
+ public void postOnPackagesUnavailable(String[] packageNames, UserHandle user,
+ boolean replacing) {
+ CallbackInfo info = new CallbackInfo();
+ info.packageNames = packageNames;
+ info.replacing = replacing;
+ info.user = user;
+ obtainMessage(MSG_UNAVAILABLE, info).sendToTarget();
+ }
+ }
}