1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/background/preferences/PreferenceManagerCompat.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,231 @@ 1.4 +/* 1.5 + * Copyright (C) 2013 The Android Open Source Project 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * Unless required by applicable law or agreed to in writing, software 1.14 + * distributed under the License is distributed on an "AS IS" BASIS, 1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.16 + * See the License for the specific language governing permissions and 1.17 + * limitations under the License. 1.18 + */ 1.19 + 1.20 +package org.mozilla.gecko.background.preferences; 1.21 + 1.22 +import java.lang.reflect.Constructor; 1.23 +import java.lang.reflect.Field; 1.24 +import java.lang.reflect.InvocationHandler; 1.25 +import java.lang.reflect.Method; 1.26 +import java.lang.reflect.Proxy; 1.27 + 1.28 +import android.app.Activity; 1.29 +import android.content.Context; 1.30 +import android.content.Intent; 1.31 +import android.preference.Preference; 1.32 +import android.preference.PreferenceManager; 1.33 +import android.preference.PreferenceScreen; 1.34 +import android.util.Log; 1.35 + 1.36 +public class PreferenceManagerCompat { 1.37 + 1.38 + private static final String TAG = PreferenceManagerCompat.class.getSimpleName(); 1.39 + 1.40 + /** 1.41 + * Interface definition for a callback to be invoked when a 1.42 + * {@link Preference} in the hierarchy rooted at this {@link PreferenceScreen} is 1.43 + * clicked. 1.44 + */ 1.45 + interface OnPreferenceTreeClickListener { 1.46 + /** 1.47 + * Called when a preference in the tree rooted at this 1.48 + * {@link PreferenceScreen} has been clicked. 1.49 + * 1.50 + * @param preferenceScreen The {@link PreferenceScreen} that the 1.51 + * preference is located in. 1.52 + * @param preference The preference that was clicked. 1.53 + * @return Whether the click was handled. 1.54 + */ 1.55 + boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference); 1.56 + } 1.57 + 1.58 + static PreferenceManager newInstance(Activity activity, int firstRequestCode) { 1.59 + try { 1.60 + Constructor<PreferenceManager> c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class); 1.61 + c.setAccessible(true); 1.62 + return c.newInstance(activity, firstRequestCode); 1.63 + } catch (Exception e) { 1.64 + Log.w(TAG, "Couldn't call constructor PreferenceManager by reflection", e); 1.65 + } 1.66 + return null; 1.67 + } 1.68 + 1.69 + /** 1.70 + * Sets the owning preference fragment 1.71 + */ 1.72 + static void setFragment(PreferenceManager manager, PreferenceFragment fragment) { 1.73 + // stub 1.74 + } 1.75 + 1.76 + /** 1.77 + * Sets the callback to be invoked when a {@link Preference} in the 1.78 + * hierarchy rooted at this {@link PreferenceManager} is clicked. 1.79 + * 1.80 + * @param listener The callback to be invoked. 1.81 + */ 1.82 + static void setOnPreferenceTreeClickListener(PreferenceManager manager, final OnPreferenceTreeClickListener listener) { 1.83 + try { 1.84 + Field onPreferenceTreeClickListener = PreferenceManager.class.getDeclaredField("mOnPreferenceTreeClickListener"); 1.85 + onPreferenceTreeClickListener.setAccessible(true); 1.86 + if (listener != null) { 1.87 + Object proxy = Proxy.newProxyInstance( 1.88 + onPreferenceTreeClickListener.getType().getClassLoader(), 1.89 + new Class<?>[] { onPreferenceTreeClickListener.getType() }, 1.90 + new InvocationHandler() { 1.91 + @Override 1.92 + public Object invoke(Object proxy, Method method, Object[] args) { 1.93 + if (method.getName().equals("onPreferenceTreeClick")) { 1.94 + return Boolean.valueOf(listener.onPreferenceTreeClick((PreferenceScreen) args[0], (Preference) args[1])); 1.95 + } else { 1.96 + return null; 1.97 + } 1.98 + } 1.99 + }); 1.100 + onPreferenceTreeClickListener.set(manager, proxy); 1.101 + } else { 1.102 + onPreferenceTreeClickListener.set(manager, null); 1.103 + } 1.104 + } catch (Exception e) { 1.105 + Log.w(TAG, "Couldn't set PreferenceManager.mOnPreferenceTreeClickListener by reflection", e); 1.106 + } 1.107 + } 1.108 + 1.109 + /** 1.110 + * Inflates a preference hierarchy from the preference hierarchies of 1.111 + * {@link Activity Activities} that match the given {@link Intent}. An 1.112 + * {@link Activity} defines its preference hierarchy with meta-data using 1.113 + * the {@link #METADATA_KEY_PREFERENCES} key. 1.114 + * <p> 1.115 + * If a preference hierarchy is given, the new preference hierarchies will 1.116 + * be merged in. 1.117 + * 1.118 + * @param queryIntent The intent to match activities. 1.119 + * @param rootPreferences Optional existing hierarchy to merge the new 1.120 + * hierarchies into. 1.121 + * @return The root hierarchy (if one was not provided, the new hierarchy's 1.122 + * root). 1.123 + */ 1.124 + static PreferenceScreen inflateFromIntent(PreferenceManager manager, Intent intent, PreferenceScreen screen) { 1.125 + try { 1.126 + Method m = PreferenceManager.class.getDeclaredMethod("inflateFromIntent", Intent.class, PreferenceScreen.class); 1.127 + m.setAccessible(true); 1.128 + PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(manager, intent, screen); 1.129 + return prefScreen; 1.130 + } catch (Exception e) { 1.131 + Log.w(TAG, "Couldn't call PreferenceManager.inflateFromIntent by reflection", e); 1.132 + } 1.133 + return null; 1.134 + } 1.135 + 1.136 + /** 1.137 + * Inflates a preference hierarchy from XML. If a preference hierarchy is 1.138 + * given, the new preference hierarchies will be merged in. 1.139 + * 1.140 + * @param context The context of the resource. 1.141 + * @param resId The resource ID of the XML to inflate. 1.142 + * @param rootPreferences Optional existing hierarchy to merge the new 1.143 + * hierarchies into. 1.144 + * @return The root hierarchy (if one was not provided, the new hierarchy's 1.145 + * root). 1.146 + * @hide 1.147 + */ 1.148 + static PreferenceScreen inflateFromResource(PreferenceManager manager, Activity activity, int resId, PreferenceScreen screen) { 1.149 + try { 1.150 + Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class); 1.151 + m.setAccessible(true); 1.152 + PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(manager, activity, resId, screen); 1.153 + return prefScreen; 1.154 + } catch (Exception e) { 1.155 + Log.w(TAG, "Couldn't call PreferenceManager.inflateFromResource by reflection", e); 1.156 + } 1.157 + return null; 1.158 + } 1.159 + 1.160 + /** 1.161 + * Returns the root of the preference hierarchy managed by this class. 1.162 + * 1.163 + * @return The {@link PreferenceScreen} object that is at the root of the hierarchy. 1.164 + */ 1.165 + static PreferenceScreen getPreferenceScreen(PreferenceManager manager) { 1.166 + try { 1.167 + Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen"); 1.168 + m.setAccessible(true); 1.169 + return (PreferenceScreen) m.invoke(manager); 1.170 + } catch (Exception e) { 1.171 + Log.w(TAG, "Couldn't call PreferenceManager.getPreferenceScreen by reflection", e); 1.172 + } 1.173 + return null; 1.174 + } 1.175 + 1.176 + /** 1.177 + * Called by the {@link PreferenceManager} to dispatch a subactivity result. 1.178 + */ 1.179 + static void dispatchActivityResult(PreferenceManager manager, int requestCode, int resultCode, Intent data) { 1.180 + try { 1.181 + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class); 1.182 + m.setAccessible(true); 1.183 + m.invoke(manager, requestCode, resultCode, data); 1.184 + } catch (Exception e) { 1.185 + Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityResult by reflection", e); 1.186 + } 1.187 + } 1.188 + 1.189 + /** 1.190 + * Called by the {@link PreferenceManager} to dispatch the activity stop 1.191 + * event. 1.192 + */ 1.193 + static void dispatchActivityStop(PreferenceManager manager) { 1.194 + try { 1.195 + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop"); 1.196 + m.setAccessible(true); 1.197 + m.invoke(manager); 1.198 + } catch (Exception e) { 1.199 + Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityStop by reflection", e); 1.200 + } 1.201 + } 1.202 + 1.203 + /** 1.204 + * Called by the {@link PreferenceManager} to dispatch the activity destroy 1.205 + * event. 1.206 + */ 1.207 + static void dispatchActivityDestroy(PreferenceManager manager) { 1.208 + try { 1.209 + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy"); 1.210 + m.setAccessible(true); 1.211 + m.invoke(manager); 1.212 + } catch (Exception e) { 1.213 + Log.w(TAG, "Couldn't call PreferenceManager.dispatchActivityDestroy by reflection", e); 1.214 + } 1.215 + } 1.216 + 1.217 + /** 1.218 + * Sets the root of the preference hierarchy. 1.219 + * 1.220 + * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. 1.221 + * @return Whether the {@link PreferenceScreen} given is different than the previous. 1.222 + */ 1.223 + static boolean setPreferences(PreferenceManager manager, PreferenceScreen screen) { 1.224 + try { 1.225 + Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class); 1.226 + m.setAccessible(true); 1.227 + return ((Boolean) m.invoke(manager, screen)); 1.228 + } catch (Exception e) { 1.229 + Log.w(TAG, "Couldn't call PreferenceManager.setPreferences by reflection", e); 1.230 + } 1.231 + return false; 1.232 + } 1.233 + 1.234 +}