LauncherAppsCompatVL.java revision 7bc272a11b701a32d2ed91277341c382cbd84aeb
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.launcher3.compat; 18 19import android.content.ComponentName; 20import android.content.Context; 21import android.content.Intent; 22import android.graphics.Rect; 23import android.os.Build; 24import android.os.Bundle; 25import android.os.UserHandle; 26 27import java.lang.reflect.InvocationHandler; 28import java.util.ArrayList; 29import java.util.Collections; 30import java.util.HashMap; 31import java.util.List; 32import java.util.Map; 33 34import java.lang.reflect.Proxy; 35import java.lang.reflect.Method; 36 37public class LauncherAppsCompatVL extends LauncherAppsCompat { 38 39 private Object mLauncherApps; 40 private Class mLauncherAppsClass; 41 private Class mListenerClass; 42 private Method mGetActivityList; 43 private Method mResolveActivity; 44 private Method mStartActivityForProfile; 45 private Method mAddOnAppsChangedListener; 46 private Method mRemoveOnAppsChangedListener; 47 private Method mIsPackageEnabledForProfile; 48 private Method mIsActivityEnabledForProfile; 49 50 private Map<OnAppsChangedListenerCompat, Object> mListeners 51 = new HashMap<OnAppsChangedListenerCompat, Object>(); 52 53 static LauncherAppsCompatVL build(Context context, Object launcherApps) { 54 LauncherAppsCompatVL compat = new LauncherAppsCompatVL(context, launcherApps); 55 56 compat.mListenerClass = ReflectUtils.getClassForName( 57 "android.content.pm.LauncherApps$OnAppsChangedListener"); 58 compat.mLauncherAppsClass = ReflectUtils.getClassForName("android.content.pm.LauncherApps"); 59 60 compat.mGetActivityList = ReflectUtils.getMethod(compat.mLauncherAppsClass, 61 "getActivityList", 62 String.class, UserHandle.class); 63 compat.mResolveActivity = ReflectUtils.getMethod(compat.mLauncherAppsClass, 64 "resolveActivity", 65 Intent.class, UserHandle.class); 66 compat.mStartActivityForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass, 67 "startActivityForProfile", 68 ComponentName.class, Rect.class, Bundle.class, UserHandle.class); 69 compat.mAddOnAppsChangedListener = ReflectUtils.getMethod(compat.mLauncherAppsClass, 70 "addOnAppsChangedListener", compat.mListenerClass); 71 compat.mRemoveOnAppsChangedListener = ReflectUtils.getMethod(compat.mLauncherAppsClass, 72 "removeOnAppsChangedListener", compat.mListenerClass); 73 compat.mIsPackageEnabledForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass, 74 "isPackageEnabledForProfile", String.class, UserHandle.class); 75 compat.mIsActivityEnabledForProfile = ReflectUtils.getMethod(compat.mLauncherAppsClass, 76 "isActivityEnabledForProfile", ComponentName.class, UserHandle.class); 77 78 if (compat.mListenerClass != null 79 && compat.mLauncherAppsClass != null 80 && compat.mGetActivityList != null 81 && compat.mResolveActivity != null 82 && compat.mStartActivityForProfile != null 83 && compat.mAddOnAppsChangedListener != null 84 && compat.mRemoveOnAppsChangedListener != null 85 && compat.mIsPackageEnabledForProfile != null 86 && compat.mIsActivityEnabledForProfile != null) { 87 return compat; 88 } 89 return null; 90 } 91 92 private LauncherAppsCompatVL(Context context, Object launcherApps) { 93 super(); 94 mLauncherApps = launcherApps; 95 } 96 97 public List<LauncherActivityInfoCompat> getActivityList(String packageName, 98 UserHandleCompat user) { 99 List<Object> list = (List<Object>) ReflectUtils.invokeMethod(mLauncherApps, 100 mGetActivityList, packageName, user.getUser()); 101 if (list.size() == 0) { 102 return Collections.EMPTY_LIST; 103 } 104 ArrayList<LauncherActivityInfoCompat> compatList = 105 new ArrayList<LauncherActivityInfoCompat>(list.size()); 106 for (Object info : list) { 107 compatList.add(new LauncherActivityInfoCompatVL(info)); 108 } 109 return compatList; 110 } 111 112 public LauncherActivityInfoCompat resolveActivity(Intent intent, UserHandleCompat user) { 113 Object activity = ReflectUtils.invokeMethod(mLauncherApps, mResolveActivity, 114 intent, user.getUser()); 115 if (activity != null) { 116 return new LauncherActivityInfoCompatVL(activity); 117 } else { 118 return null; 119 } 120 } 121 122 public void startActivityForProfile(ComponentName component, Rect sourceBounds, 123 Bundle opts, UserHandleCompat user) { 124 ReflectUtils.invokeMethod(mLauncherApps, mStartActivityForProfile, 125 component, sourceBounds, opts, user.getUser()); 126 } 127 128 public void addOnAppsChangedListener(LauncherAppsCompat.OnAppsChangedListenerCompat listener) { 129 Object wrappedListener = Proxy.newProxyInstance(mListenerClass.getClassLoader(), 130 new Class[]{mListenerClass}, new WrappedListener(listener)); 131 synchronized (mListeners) { 132 mListeners.put(listener, wrappedListener); 133 } 134 ReflectUtils.invokeMethod(mLauncherApps, mAddOnAppsChangedListener, wrappedListener); 135 } 136 137 public void removeOnAppsChangedListener( 138 LauncherAppsCompat.OnAppsChangedListenerCompat listener) { 139 Object wrappedListener = null; 140 synchronized (mListeners) { 141 wrappedListener = mListeners.remove(listener); 142 } 143 if (wrappedListener != null) { 144 ReflectUtils.invokeMethod(mLauncherApps, mRemoveOnAppsChangedListener, wrappedListener); 145 } 146 } 147 148 public boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user) { 149 return (Boolean) ReflectUtils.invokeMethod(mLauncherApps, mIsPackageEnabledForProfile, 150 packageName, user.getUser()); 151 } 152 153 public boolean isActivityEnabledForProfile(ComponentName component, UserHandleCompat user) { 154 return (Boolean) ReflectUtils.invokeMethod(mLauncherApps, mIsActivityEnabledForProfile, 155 component, user.getUser()); 156 } 157 158 private static class WrappedListener implements InvocationHandler { 159 private LauncherAppsCompat.OnAppsChangedListenerCompat mListener; 160 161 public WrappedListener(LauncherAppsCompat.OnAppsChangedListenerCompat listener) { 162 mListener = listener; 163 } 164 165 public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { 166 try { 167 String methodName = m.getName(); 168 if ("onPackageRemoved".equals(methodName)) { 169 onPackageRemoved((UserHandle) args[0], (String) args[1]); 170 } else if ("onPackageAdded".equals(methodName)) { 171 onPackageAdded((UserHandle) args[0], (String) args[1]); 172 } else if ("onPackageChanged".equals(methodName)) { 173 onPackageChanged((UserHandle) args[0], (String) args[1]); 174 } else if ("onPackagesAvailable".equals(methodName)) { 175 onPackagesAvailable((UserHandle) args[0], (String []) args[1], 176 (Boolean) args[2]); 177 } else if ("onPackagesUnavailable".equals(methodName)) { 178 onPackagesUnavailable((UserHandle) args[0], (String []) args[1], 179 (Boolean) args[2]); 180 } 181 } finally { 182 return null; 183 } 184 } 185 186 public void onPackageRemoved(UserHandle user, String packageName) { 187 mListener.onPackageRemoved(UserHandleCompat.fromUser(user), packageName); 188 } 189 190 public void onPackageAdded(UserHandle user, String packageName) { 191 mListener.onPackageAdded(UserHandleCompat.fromUser(user), packageName); 192 } 193 194 public void onPackageChanged(UserHandle user, String packageName) { 195 mListener.onPackageChanged(UserHandleCompat.fromUser(user), packageName); 196 } 197 198 public void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing) { 199 mListener.onPackagesAvailable(UserHandleCompat.fromUser(user), packageNames, replacing); 200 } 201 202 public void onPackagesUnavailable(UserHandle user, String[] packageNames, 203 boolean replacing) { 204 mListener.onPackagesUnavailable(UserHandleCompat.fromUser(user), packageNames, 205 replacing); 206 } 207 } 208} 209 210