Remove reflection now we are building against L

Remove reflection and update changed renamed L APIs
now that branch has L sdk.

Change-Id: I223c6528487110eb328e2e229bbcbefb701e0c20
This commit is contained in:
Kenny Guy 2014-06-12 13:00:26 +01:00
parent 9c599c2aae
commit 242bbe1b72
15 changed files with 140 additions and 396 deletions

View File

@ -36,7 +36,8 @@ LOCAL_AAPT_FLAGS := --auto-add-overlay
LOCAL_PROTOC_OPTIMIZE_TYPE := nano LOCAL_PROTOC_OPTIMIZE_TYPE := nano
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/
LOCAL_SDK_VERSION := 19 # STOPSHIP(kennyguy): change to 21 once the L SDK is baked.
LOCAL_SDK_VERSION := current
LOCAL_PACKAGE_NAME := Launcher3 LOCAL_PACKAGE_NAME := Launcher3
#LOCAL_CERTIFICATE := shared #LOCAL_CERTIFICATE := shared

View File

@ -94,7 +94,7 @@ public class AppInfo extends ItemInfo {
} }
private static int initFlags(LauncherActivityInfoCompat info) { private static int initFlags(LauncherActivityInfoCompat info) {
int appFlags = info.getApplicationFlags(); int appFlags = info.getApplicationInfo().flags;
int flags = 0; int flags = 0;
if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) { if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) {
flags |= DOWNLOADED_FLAG; flags |= DOWNLOADED_FLAG;

View File

@ -2753,8 +2753,8 @@ public class Launcher extends Activity
// Could be launching some bookkeeping activity // Could be launching some bookkeeping activity
startActivity(intent, optsBundle); startActivity(intent, optsBundle);
} else { } else {
launcherApps.startActivityForProfile(intent.getComponent(), launcherApps.startActivityForProfile(intent.getComponent(), user,
intent.getSourceBounds(), optsBundle, user); intent.getSourceBounds(), optsBundle);
} }
return true; return true;
} catch (SecurityException e) { } catch (SecurityException e) {

View File

@ -95,7 +95,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
mBuildInfo = BuildInfo.loadByName(sContext.getString(R.string.build_info_class)); mBuildInfo = BuildInfo.loadByName(sContext.getString(R.string.build_info_class));
mModel = new LauncherModel(this, mIconCache, mAppFilter); mModel = new LauncherModel(this, mIconCache, mAppFilter);
final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext); final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
launcherApps.addOnAppsChangedListener(mModel); launcherApps.addOnAppsChangedCallback(mModel);
// Register intent receivers // Register intent receivers
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
@ -128,7 +128,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
public void onTerminate() { public void onTerminate() {
sContext.unregisterReceiver(mModel); sContext.unregisterReceiver(mModel);
final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext); final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
launcherApps.removeOnAppsChangedListener(mModel); launcherApps.removeOnAppsChangedCallback(mModel);
ContentResolver resolver = sContext.getContentResolver(); ContentResolver resolver = sContext.getContentResolver();
resolver.unregisterContentObserver(mFavoritesObserver); resolver.unregisterContentObserver(mFavoritesObserver);

View File

@ -73,7 +73,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* for the Launcher. * for the Launcher.
*/ */
public class LauncherModel extends BroadcastReceiver public class LauncherModel extends BroadcastReceiver
implements LauncherAppsCompat.OnAppsChangedListenerCompat { implements LauncherAppsCompat.OnAppsChangedCallbackCompat {
static final boolean DEBUG_LOADERS = false; static final boolean DEBUG_LOADERS = false;
private static final boolean DEBUG_RECEIVER = true; // STOPSHIP(cwren) temporary for debugging private static final boolean DEBUG_RECEIVER = true; // STOPSHIP(cwren) temporary for debugging
@ -1186,28 +1186,28 @@ public class LauncherModel extends BroadcastReceiver
} }
@Override @Override
public void onPackageChanged(UserHandleCompat user, String packageName) { public void onPackageChanged(String packageName, UserHandleCompat user) {
int op = PackageUpdatedTask.OP_UPDATE; int op = PackageUpdatedTask.OP_UPDATE;
enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName },
user)); user));
} }
@Override @Override
public void onPackageRemoved(UserHandleCompat user, String packageName) { public void onPackageRemoved(String packageName, UserHandleCompat user) {
int op = PackageUpdatedTask.OP_REMOVE; int op = PackageUpdatedTask.OP_REMOVE;
enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName },
user)); user));
} }
@Override @Override
public void onPackageAdded(UserHandleCompat user, String packageName) { public void onPackageAdded(String packageName, UserHandleCompat user) {
int op = PackageUpdatedTask.OP_ADD; int op = PackageUpdatedTask.OP_ADD;
enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName },
user)); user));
} }
@Override @Override
public void onPackagesAvailable(UserHandleCompat user, String[] packageNames, public void onPackagesAvailable(String[] packageNames, UserHandleCompat user,
boolean replacing) { boolean replacing) {
if (!replacing) { if (!replacing) {
enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packageNames, enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packageNames,
@ -1226,7 +1226,7 @@ public class LauncherModel extends BroadcastReceiver
} }
@Override @Override
public void onPackagesUnavailable(UserHandleCompat user, String[] packageNames, public void onPackagesUnavailable(String[] packageNames, UserHandleCompat user,
boolean replacing) { boolean replacing) {
if (!replacing) { if (!replacing) {
enqueuePackageUpdated(new PackageUpdatedTask( enqueuePackageUpdated(new PackageUpdatedTask(

View File

@ -17,6 +17,7 @@
package com.android.launcher3.compat; package com.android.launcher3.compat;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
public abstract class LauncherActivityInfoCompat { public abstract class LauncherActivityInfoCompat {
@ -28,7 +29,7 @@ public abstract class LauncherActivityInfoCompat {
public abstract UserHandleCompat getUser(); public abstract UserHandleCompat getUser();
public abstract CharSequence getLabel(); public abstract CharSequence getLabel();
public abstract Drawable getIcon(int density); public abstract Drawable getIcon(int density);
public abstract int getApplicationFlags(); public abstract ApplicationInfo getApplicationInfo();
public abstract long getFirstInstallTime(); public abstract long getFirstInstallTime();
public abstract Drawable getBadgedIcon(int density); public abstract Drawable getBadgedIcon(int density);
} }

View File

@ -18,6 +18,7 @@ package com.android.launcher3.compat;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -75,8 +76,8 @@ public class LauncherActivityInfoCompatV16 extends LauncherActivityInfoCompat {
return d; return d;
} }
public int getApplicationFlags() { public ApplicationInfo getApplicationInfo() {
return mActivityInfo.applicationInfo.flags; return mActivityInfo.applicationInfo;
} }
public long getFirstInstallTime() { public long getFirstInstallTime() {

View File

@ -17,66 +17,44 @@
package com.android.launcher3.compat; package com.android.launcher3.compat;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.UserHandle; import android.os.UserHandle;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class LauncherActivityInfoCompatVL extends LauncherActivityInfoCompat { public class LauncherActivityInfoCompatVL extends LauncherActivityInfoCompat {
private Object mLauncherActivityInfo; private LauncherActivityInfo mLauncherActivityInfo;
private Class mLauncherActivityInfoClass;
private Method mGetComponentName;
private Method mGetUser;
private Method mGetLabel;
private Method mGetIcon;
private Method mGetApplicationFlags;
private Method mGetFirstInstallTime;
private Method mGetBadgedIcon;
LauncherActivityInfoCompatVL(Object launcherActivityInfo) { LauncherActivityInfoCompatVL(LauncherActivityInfo launcherActivityInfo) {
super(); super();
mLauncherActivityInfo = launcherActivityInfo; mLauncherActivityInfo = launcherActivityInfo;
mLauncherActivityInfoClass = ReflectUtils.getClassForName(
"android.content.pm.LauncherActivityInfo");
mGetComponentName = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getComponentName");
mGetUser = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getUser");
mGetLabel = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getLabel");
mGetIcon = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getIcon", int.class);
mGetApplicationFlags = ReflectUtils.getMethod(mLauncherActivityInfoClass,
"getApplicationFlags");
mGetFirstInstallTime = ReflectUtils.getMethod(mLauncherActivityInfoClass,
"getFirstInstallTime");
mGetBadgedIcon = ReflectUtils.getMethod(mLauncherActivityInfoClass, "getBadgedIcon",
int.class);
} }
public ComponentName getComponentName() { public ComponentName getComponentName() {
return (ComponentName) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetComponentName); return mLauncherActivityInfo.getComponentName();
} }
public UserHandleCompat getUser() { public UserHandleCompat getUser() {
return UserHandleCompat.fromUser((UserHandle) ReflectUtils.invokeMethod( return UserHandleCompat.fromUser(mLauncherActivityInfo.getUser());
mLauncherActivityInfo, mGetUser));
} }
public CharSequence getLabel() { public CharSequence getLabel() {
return (CharSequence) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetLabel); return mLauncherActivityInfo.getLabel();
} }
public Drawable getIcon(int density) { public Drawable getIcon(int density) {
return (Drawable) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetIcon, density); return mLauncherActivityInfo.getIcon(density);
} }
public int getApplicationFlags() { public ApplicationInfo getApplicationInfo() {
return (Integer) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetApplicationFlags); return mLauncherActivityInfo.getApplicationInfo();
} }
public long getFirstInstallTime() { public long getFirstInstallTime() {
return (Long) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetFirstInstallTime); return mLauncherActivityInfo.getFirstInstallTime();
} }
public Drawable getBadgedIcon(int density) { public Drawable getBadgedIcon(int density) {
return (Drawable) ReflectUtils.invokeMethod(mLauncherActivityInfo, mGetBadgedIcon, density); return mLauncherActivityInfo.getBadgedIcon(density);
} }
} }

View File

@ -39,40 +39,42 @@ public abstract class LauncherAppsCompat {
public static final String ACTION_MANAGED_PROFILE_REMOVED = public static final String ACTION_MANAGED_PROFILE_REMOVED =
"android.intent.action.MANAGED_PROFILE_REMOVED"; "android.intent.action.MANAGED_PROFILE_REMOVED";
public interface OnAppsChangedListenerCompat { public interface OnAppsChangedCallbackCompat {
void onPackageRemoved(UserHandleCompat user, String packageName); void onPackageRemoved(String packageName, UserHandleCompat user);
void onPackageAdded(UserHandleCompat user, String packageName); void onPackageAdded(String packageName, UserHandleCompat user);
void onPackageChanged(UserHandleCompat user, String packageName); void onPackageChanged(String packageName, UserHandleCompat user);
void onPackagesAvailable(UserHandleCompat user, String[] packageNames, boolean replacing); void onPackagesAvailable(String[] packageNames, UserHandleCompat user, boolean replacing);
void onPackagesUnavailable(UserHandleCompat user, String[] packageNames, boolean replacing); void onPackagesUnavailable(String[] packageNames, UserHandleCompat user, boolean replacing);
} }
protected LauncherAppsCompat() { protected LauncherAppsCompat() {
} }
private static LauncherAppsCompat sInstance;
private static Object sInstanceLock = new Object();
public static LauncherAppsCompat getInstance(Context context) { public static LauncherAppsCompat getInstance(Context context) {
// TODO change this to use api version once L gets an API number. synchronized (sInstanceLock) {
if ("L".equals(Build.VERSION.CODENAME)) { // TODO change this to use api version once L gets an API number.
Object launcherApps = context.getSystemService("launcherapps"); if (sInstance == null) {
if (launcherApps != null) { if ("L".equals(Build.VERSION.CODENAME)) {
LauncherAppsCompatVL compat = LauncherAppsCompatVL.build(context, launcherApps); sInstance = new LauncherAppsCompatVL(context);
if (compat != null) { } else {
return compat; sInstance = new LauncherAppsCompatV16(context);
} }
} }
return sInstance;
} }
// Pre L or lunacher apps service not running, or reflection failed to find something.
return new LauncherAppsCompatV16(context);
} }
public abstract List<LauncherActivityInfoCompat> getActivityList(String packageName, public abstract List<LauncherActivityInfoCompat> getActivityList(String packageName,
UserHandleCompat user); UserHandleCompat user);
public abstract LauncherActivityInfoCompat resolveActivity(Intent intent, public abstract LauncherActivityInfoCompat resolveActivity(Intent intent,
UserHandleCompat user); UserHandleCompat user);
public abstract void startActivityForProfile(ComponentName component, Rect sourceBounds, public abstract void startActivityForProfile(ComponentName component, UserHandleCompat user,
Bundle opts, UserHandleCompat user); Rect sourceBounds, Bundle opts);
public abstract void addOnAppsChangedListener(OnAppsChangedListenerCompat listener); public abstract void addOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
public abstract void removeOnAppsChangedListener(OnAppsChangedListenerCompat listener); public abstract void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
public abstract boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user); public abstract boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user);
public abstract boolean isActivityEnabledForProfile(ComponentName component, public abstract boolean isActivityEnabledForProfile(ComponentName component,
UserHandleCompat user); UserHandleCompat user);

View File

@ -39,8 +39,8 @@ public class LauncherAppsCompatV16 extends LauncherAppsCompat {
private PackageManager mPm; private PackageManager mPm;
private Context mContext; private Context mContext;
private List<OnAppsChangedListenerCompat> mListeners private List<OnAppsChangedCallbackCompat> mCallbacks
= new ArrayList<OnAppsChangedListenerCompat>(); = new ArrayList<OnAppsChangedCallbackCompat>();
private PackageMonitor mPackageMonitor; private PackageMonitor mPackageMonitor;
LauncherAppsCompatV16(Context context) { LauncherAppsCompatV16(Context context) {
@ -71,8 +71,8 @@ public class LauncherAppsCompatV16 extends LauncherAppsCompat {
return null; return null;
} }
public void startActivityForProfile(ComponentName component, Rect sourceBounds, public void startActivityForProfile(ComponentName component, UserHandleCompat user,
Bundle opts, UserHandleCompat user) { Rect sourceBounds, Bundle opts) {
Intent launchIntent = new Intent(Intent.ACTION_MAIN); Intent launchIntent = new Intent(Intent.ACTION_MAIN);
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
launchIntent.setComponent(component); launchIntent.setComponent(component);
@ -81,18 +81,18 @@ public class LauncherAppsCompatV16 extends LauncherAppsCompat {
mContext.startActivity(launchIntent, opts); mContext.startActivity(launchIntent, opts);
} }
public synchronized void addOnAppsChangedListener(OnAppsChangedListenerCompat listener) { public synchronized void addOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) {
if (listener != null && !mListeners.contains(listener)) { if (callback != null && !mCallbacks.contains(callback)) {
mListeners.add(listener); mCallbacks.add(callback);
if (mListeners.size() == 1) { if (mCallbacks.size() == 1) {
registerForPackageIntents(); registerForPackageIntents();
} }
} }
} }
public synchronized void removeOnAppsChangedListener(OnAppsChangedListenerCompat listener) { public synchronized void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) {
mListeners.remove(listener); mCallbacks.remove(callback);
if (mListeners.size() == 0) { if (mCallbacks.size() == 0) {
unregisterForPackageIntents(); unregisterForPackageIntents();
} }
} }
@ -131,8 +131,8 @@ public class LauncherAppsCompatV16 extends LauncherAppsCompat {
mContext.registerReceiver(mPackageMonitor, filter); mContext.registerReceiver(mPackageMonitor, filter);
} }
private synchronized List<OnAppsChangedListenerCompat> getListeners() { private synchronized List<OnAppsChangedCallbackCompat> getCallbacks() {
return new ArrayList<OnAppsChangedListenerCompat>(mListeners); return new ArrayList<OnAppsChangedCallbackCompat>(mCallbacks);
} }
private class PackageMonitor extends BroadcastReceiver { private class PackageMonitor extends BroadcastReceiver {
@ -151,39 +151,39 @@ public class LauncherAppsCompatV16 extends LauncherAppsCompat {
return; return;
} }
if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
for (OnAppsChangedListenerCompat listener : getListeners()) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
listener.onPackageChanged(user, packageName); callback.onPackageChanged(packageName, user);
} }
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
if (!replacing) { if (!replacing) {
for (OnAppsChangedListenerCompat listener : getListeners()) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
listener.onPackageRemoved(user, packageName); callback.onPackageRemoved(packageName, user);
} }
} }
// else, we are replacing the package, so a PACKAGE_ADDED will be sent // else, we are replacing the package, so a PACKAGE_ADDED will be sent
// later, we will update the package at this time // later, we will update the package at this time
} else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
if (!replacing) { if (!replacing) {
for (OnAppsChangedListenerCompat listener : getListeners()) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
listener.onPackageAdded(user, packageName); callback.onPackageAdded(packageName, user);
} }
} else { } else {
for (OnAppsChangedListenerCompat listener : getListeners()) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
listener.onPackageChanged(user, packageName); callback.onPackageChanged(packageName, user);
} }
} }
} }
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
for (OnAppsChangedListenerCompat listener : getListeners()) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
listener.onPackagesAvailable(user, packages, replacing); callback.onPackagesAvailable(packages, user, replacing);
} }
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
for (OnAppsChangedListenerCompat listener : getListeners()) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
listener.onPackagesUnavailable(user, packages, replacing); callback.onPackagesUnavailable(packages, user, replacing);
} }
} }
} }

View File

@ -19,99 +19,48 @@ package com.android.launcher3.compat;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import java.lang.reflect.InvocationHandler;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
public class LauncherAppsCompatVL extends LauncherAppsCompat { public class LauncherAppsCompatVL extends LauncherAppsCompat {
private Object mLauncherApps; private LauncherApps mLauncherApps;
private Class mLauncherAppsClass;
private Class mListenerClass;
private Method mGetActivityList;
private Method mResolveActivity;
private Method mStartActivityForProfile;
private Method mAddOnAppsChangedListener;
private Method mRemoveOnAppsChangedListener;
private Method mIsPackageEnabledForProfile;
private Method mIsActivityEnabledForProfile;
private Map<OnAppsChangedListenerCompat, Object> mListeners private Map<OnAppsChangedCallbackCompat, WrappedCallback> mCallbacks
= new HashMap<OnAppsChangedListenerCompat, Object>(); = new HashMap<OnAppsChangedCallbackCompat, WrappedCallback>();
static LauncherAppsCompatVL build(Context context, Object launcherApps) { LauncherAppsCompatVL(Context context) {
LauncherAppsCompatVL compat = new LauncherAppsCompatVL(context, launcherApps);
compat.mListenerClass = ReflectUtils.getClassForName(
"android.content.pm.LauncherApps$OnAppsChangedListener");
compat.mLauncherAppsClass = ReflectUtils.getClassForName("android.content.pm.LauncherApps");
compat.mGetActivityList = ReflectUtils.getMethod(compat.mLauncherAppsClass,
"getActivityList",
String.class, UserHandle.class);
compat.mResolveActivity = ReflectUtils.getMethod(compat.mLauncherAppsClass,
"resolveActivity",
Intent.class, UserHandle.class);
compat.mStartActivityForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass,
"startActivityForProfile",
ComponentName.class, Rect.class, Bundle.class, UserHandle.class);
compat.mAddOnAppsChangedListener = ReflectUtils.getMethod(compat.mLauncherAppsClass,
"addOnAppsChangedListener", compat.mListenerClass);
compat.mRemoveOnAppsChangedListener = ReflectUtils.getMethod(compat.mLauncherAppsClass,
"removeOnAppsChangedListener", compat.mListenerClass);
compat.mIsPackageEnabledForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass,
"isPackageEnabledForProfile", String.class, UserHandle.class);
compat.mIsActivityEnabledForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass,
"isActivityEnabledForProfile", ComponentName.class, UserHandle.class);
if (compat.mListenerClass != null
&& compat.mLauncherAppsClass != null
&& compat.mGetActivityList != null
&& compat.mResolveActivity != null
&& compat.mStartActivityForProfile != null
&& compat.mAddOnAppsChangedListener != null
&& compat.mRemoveOnAppsChangedListener != null
&& compat.mIsPackageEnabledForProfile != null
&& compat.mIsActivityEnabledForProfile != null) {
return compat;
}
return null;
}
private LauncherAppsCompatVL(Context context, Object launcherApps) {
super(); super();
mLauncherApps = launcherApps; mLauncherApps = (LauncherApps) context.getSystemService("launcherapps");
} }
public List<LauncherActivityInfoCompat> getActivityList(String packageName, public List<LauncherActivityInfoCompat> getActivityList(String packageName,
UserHandleCompat user) { UserHandleCompat user) {
List<Object> list = (List<Object>) ReflectUtils.invokeMethod(mLauncherApps, List<LauncherActivityInfo> list = mLauncherApps.getActivityList(packageName,
mGetActivityList, packageName, user.getUser()); user.getUser());
if (list.size() == 0) { if (list.size() == 0) {
return Collections.EMPTY_LIST; return Collections.EMPTY_LIST;
} }
ArrayList<LauncherActivityInfoCompat> compatList = ArrayList<LauncherActivityInfoCompat> compatList =
new ArrayList<LauncherActivityInfoCompat>(list.size()); new ArrayList<LauncherActivityInfoCompat>(list.size());
for (Object info : list) { for (LauncherActivityInfo info : list) {
compatList.add(new LauncherActivityInfoCompatVL(info)); compatList.add(new LauncherActivityInfoCompatVL(info));
} }
return compatList; return compatList;
} }
public LauncherActivityInfoCompat resolveActivity(Intent intent, UserHandleCompat user) { public LauncherActivityInfoCompat resolveActivity(Intent intent, UserHandleCompat user) {
Object activity = ReflectUtils.invokeMethod(mLauncherApps, mResolveActivity, LauncherActivityInfo activity = mLauncherApps.resolveActivity(intent, user.getUser());
intent, user.getUser());
if (activity != null) { if (activity != null) {
return new LauncherActivityInfoCompatVL(activity); return new LauncherActivityInfoCompatVL(activity);
} else { } else {
@ -119,89 +68,64 @@ public class LauncherAppsCompatVL extends LauncherAppsCompat {
} }
} }
public void startActivityForProfile(ComponentName component, Rect sourceBounds, public void startActivityForProfile(ComponentName component, UserHandleCompat user,
Bundle opts, UserHandleCompat user) { Rect sourceBounds, Bundle opts) {
ReflectUtils.invokeMethod(mLauncherApps, mStartActivityForProfile, mLauncherApps.startActivityForProfile(component, user.getUser(), sourceBounds, opts);
component, sourceBounds, opts, user.getUser());
} }
public void addOnAppsChangedListener(LauncherAppsCompat.OnAppsChangedListenerCompat listener) { public void addOnAppsChangedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
Object wrappedListener = Proxy.newProxyInstance(mListenerClass.getClassLoader(), WrappedCallback wrappedCallback = new WrappedCallback(callback);
new Class[]{mListenerClass}, new WrappedListener(listener)); synchronized (mCallbacks) {
synchronized (mListeners) { mCallbacks.put(callback, wrappedCallback);
mListeners.put(listener, wrappedListener);
} }
ReflectUtils.invokeMethod(mLauncherApps, mAddOnAppsChangedListener, wrappedListener); mLauncherApps.addOnAppsChangedCallback(wrappedCallback);
} }
public void removeOnAppsChangedListener( public void removeOnAppsChangedCallback(
LauncherAppsCompat.OnAppsChangedListenerCompat listener) { LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
Object wrappedListener = null; WrappedCallback wrappedCallback = null;
synchronized (mListeners) { synchronized (mCallbacks) {
wrappedListener = mListeners.remove(listener); wrappedCallback = mCallbacks.remove(callback);
} }
if (wrappedListener != null) { if (wrappedCallback != null) {
ReflectUtils.invokeMethod(mLauncherApps, mRemoveOnAppsChangedListener, wrappedListener); mLauncherApps.removeOnAppsChangedCallback(wrappedCallback);
} }
} }
public boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user) { public boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user) {
return (Boolean) ReflectUtils.invokeMethod(mLauncherApps, mIsPackageEnabledForProfile, return mLauncherApps.isPackageEnabledForProfile(packageName, user.getUser());
packageName, user.getUser());
} }
public boolean isActivityEnabledForProfile(ComponentName component, UserHandleCompat user) { public boolean isActivityEnabledForProfile(ComponentName component, UserHandleCompat user) {
return (Boolean) ReflectUtils.invokeMethod(mLauncherApps, mIsActivityEnabledForProfile, return mLauncherApps.isActivityEnabledForProfile(component, user.getUser());
component, user.getUser());
} }
private static class WrappedListener implements InvocationHandler { private static class WrappedCallback extends LauncherApps.OnAppsChangedCallback {
private LauncherAppsCompat.OnAppsChangedListenerCompat mListener; private LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;
public WrappedListener(LauncherAppsCompat.OnAppsChangedListenerCompat listener) { public WrappedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
mListener = listener; mCallback = callback;
} }
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { public void onPackageRemoved(String packageName, UserHandle user) {
try { mCallback.onPackageRemoved(packageName, UserHandleCompat.fromUser(user));
String methodName = m.getName();
if ("onPackageRemoved".equals(methodName)) {
onPackageRemoved((UserHandle) args[0], (String) args[1]);
} else if ("onPackageAdded".equals(methodName)) {
onPackageAdded((UserHandle) args[0], (String) args[1]);
} else if ("onPackageChanged".equals(methodName)) {
onPackageChanged((UserHandle) args[0], (String) args[1]);
} else if ("onPackagesAvailable".equals(methodName)) {
onPackagesAvailable((UserHandle) args[0], (String []) args[1],
(Boolean) args[2]);
} else if ("onPackagesUnavailable".equals(methodName)) {
onPackagesUnavailable((UserHandle) args[0], (String []) args[1],
(Boolean) args[2]);
}
} finally {
return null;
}
} }
public void onPackageRemoved(UserHandle user, String packageName) { public void onPackageAdded(String packageName, UserHandle user) {
mListener.onPackageRemoved(UserHandleCompat.fromUser(user), packageName); mCallback.onPackageAdded(packageName, UserHandleCompat.fromUser(user));
} }
public void onPackageAdded(UserHandle user, String packageName) { public void onPackageChanged(String packageName, UserHandle user) {
mListener.onPackageAdded(UserHandleCompat.fromUser(user), packageName); mCallback.onPackageChanged(packageName, UserHandleCompat.fromUser(user));
} }
public void onPackageChanged(UserHandle user, String packageName) { public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
mListener.onPackageChanged(UserHandleCompat.fromUser(user), packageName); mCallback.onPackagesAvailable(packageNames, UserHandleCompat.fromUser(user), replacing);
} }
public void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing) { public void onPackagesUnavailable(String[] packageNames, UserHandle user,
mListener.onPackagesAvailable(UserHandleCompat.fromUser(user), packageNames, replacing);
}
public void onPackagesUnavailable(UserHandle user, String[] packageNames,
boolean replacing) { boolean replacing) {
mListener.onPackagesUnavailable(UserHandleCompat.fromUser(user), packageNames, mCallback.onPackagesUnavailable(packageNames, UserHandleCompat.fromUser(user),
replacing); replacing);
} }
} }

View File

@ -1,159 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.compat;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectUtils {
private static final String TAG = "LauncherReflect";
public static Class getClassForName(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
Log.e(TAG, "Couldn't find class " + className, e);
return null;
}
}
public static Method getMethod(Class clazz, String method) {
try {
return clazz.getMethod(method);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
return null;
}
}
public static Method getMethod(Class clazz, String method, Class param1) {
try {
return clazz.getMethod(method, param1);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
return null;
}
}
public static Method getMethod(Class clazz, String method, Class param1, Class param2) {
try {
return clazz.getMethod(method, param1, param2);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
return null;
}
}
public static Method getMethod(Class clazz, String method, Class param1, Class param2,
Class param3) {
try {
return clazz.getMethod(method, param1, param2, param3);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
return null;
}
}
public static Method getMethod(Class clazz, String method, Class param1, Class param2,
Class param3, Class param4) {
try {
return clazz.getMethod(method, param1, param2, param3, param4);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Couldn't find methid " + clazz.getName() + " " + method, e);
return null;
}
}
public static Object invokeMethod(Object object, Method method) {
try {
return method.invoke(object);
} catch (SecurityException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalAccessException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
}
return null;
}
public static Object invokeMethod(Object object, Method method, Object param1) {
try {
return method.invoke(object, param1);
} catch (SecurityException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalAccessException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
}
return null;
}
public static Object invokeMethod(Object object, Method method, Object param1, Object param2) {
try {
return method.invoke(object, param1, param2);
} catch (SecurityException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalAccessException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
}
return null;
}
public static Object invokeMethod(Object object, Method method, Object param1, Object param2,
Object param3) {
try {
return method.invoke(object, param1, param2, param3);
} catch (SecurityException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalAccessException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
}
return null;
}
public static Object invokeMethod(Object object, Method method, Object param1, Object param2,
Object param3, Object param4) {
try {
return method.invoke(object, param1, param2, param3, param4);
} catch (SecurityException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (IllegalAccessException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Couldn't invoke method " + method, e);
}
return null;
}
}

View File

@ -41,4 +41,5 @@ public abstract class UserManagerCompat {
public abstract long getSerialNumberForUser(UserHandleCompat user); public abstract long getSerialNumberForUser(UserHandleCompat user);
public abstract UserHandleCompat getUserForSerialNumber(long serialNumber); public abstract UserHandleCompat getUserForSerialNumber(long serialNumber);
public abstract Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user); public abstract Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user);
public abstract String getBadgedLabelForUser(String label, UserHandleCompat user);
} }

View File

@ -44,4 +44,8 @@ public class UserManagerCompatV16 extends UserManagerCompat {
public long getSerialNumberForUser(UserHandleCompat user) { public long getSerialNumberForUser(UserHandleCompat user) {
return 0; return 0;
} }
public String getBadgedLabelForUser(String label, UserHandleCompat user) {
return label;
}
} }

View File

@ -22,9 +22,8 @@ import android.graphics.drawable.Drawable;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
public class UserManagerCompatVL extends UserManagerCompatV17 { public class UserManagerCompatVL extends UserManagerCompatV17 {
@ -34,35 +33,27 @@ public class UserManagerCompatVL extends UserManagerCompatV17 {
} }
public List<UserHandleCompat> getUserProfiles() { public List<UserHandleCompat> getUserProfiles() {
Method method = ReflectUtils.getMethod(mUserManager.getClass(), "getUserProfiles"); List<UserHandle> users = mUserManager.getUserProfiles();
if (method != null) { if (users == null) {
List<UserHandle> users = (List<UserHandle>) ReflectUtils.invokeMethod( return Collections.EMPTY_LIST;
mUserManager, method);
if (users != null) {
ArrayList<UserHandleCompat> compatUsers = new ArrayList<UserHandleCompat>(
users.size());
for (UserHandle user : users) {
compatUsers.add(UserHandleCompat.fromUser(user));
}
return compatUsers;
}
} }
// Fall back to non L version. ArrayList<UserHandleCompat> compatUsers = new ArrayList<UserHandleCompat>(
return super.getUserProfiles(); users.size());
for (UserHandle user : users) {
compatUsers.add(UserHandleCompat.fromUser(user));
}
return compatUsers;
} }
public Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user) { public Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user) {
Method method = ReflectUtils.getMethod(mUserManager.getClass(), "getBadgedDrawableForUser", return mUserManager.getBadgedDrawableForUser(unbadged, user.getUser());
Drawable.class, UserHandle.class); }
if (method != null) {
Drawable d = (Drawable) ReflectUtils.invokeMethod(mUserManager, method, unbadged, public String getBadgedLabelForUser(String label, UserHandleCompat user) {
user.getUser()); if (user == null) {
if (d != null) { return label;
return d;
}
} }
// Fall back to non L version. return mUserManager.getBadgedLabelForUser(label, user.getUser());
return super.getBadgedDrawableForUser(unbadged, user);
} }
} }