1fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill/* 2fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * Copyright (C) 2013 The Android Open Source Project 3fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 4fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * Licensed under the Apache License, Version 2.0 (the "License"); 5fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * you may not use this file except in compliance with the License. 6fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * You may obtain a copy of the License at 7fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 8fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * http://www.apache.org/licenses/LICENSE-2.0 9fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 10fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * Unless required by applicable law or agreed to in writing, software 11fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * distributed under the License is distributed on an "AS IS" BASIS, 12fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * See the License for the specific language governing permissions and 14fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * limitations under the License. 15fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill */ 16fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 17fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neillpackage android.location; 18fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 19cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neillimport android.app.Service; 20fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neillimport android.content.Intent; 21fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neillimport android.os.Bundle; 22cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neillimport android.os.IBinder; 23fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neillimport android.os.Message; 24fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neillimport android.os.Messenger; 25fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neillimport android.os.RemoteException; 26fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neillimport android.util.Log; 27fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 28fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill/** 29248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * Dynamically specifies the enabled status of a preference injected into 30cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * the list of app settings displayed by the system settings app 31cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * <p/> 32cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * For use only by apps that are included in the system image, for preferences that affect multiple 33cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * apps. Location settings that apply only to one app should be shown within that app, 34fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * rather than in the system settings. 35cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * <p/> 36fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * To add a preference to the list, a subclass of {@link SettingInjectorService} must be declared in 37fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * the manifest as so: 384a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * 39fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * <pre> 404a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * <service android:name="com.example.android.injector.MyInjectorService" > 414a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * <intent-filter> 42546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * <action android:name="android.location.SettingInjectorService" /> 434a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * </intent-filter> 44fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 454a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * <meta-data 46546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * android:name="android.location.SettingInjectorService" 474a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * android:resource="@xml/my_injected_location_setting" /> 484a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * </service> 49fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * </pre> 50fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * The resource file specifies the static data for the setting: 51fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * <pre> 524a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * <injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android" 53546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * android:title="@string/injected_setting_title" 54546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * android:icon="@drawable/ic_acme_corp" 55fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * android:settingsActivity="com.example.android.injector.MySettingActivity" 564a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * /> 57fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * </pre> 58fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * Here: 59fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * <ul> 60546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * <li>title: The {@link android.preference.Preference#getTitle()} value. The title should make 61546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * it clear which apps are affected by the setting, typically by including the name of the 62546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * developer. For example, "Acme Corp. ads preferences." </li> 63fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 64546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * <li>icon: The {@link android.preference.Preference#getIcon()} value. Typically this will be a 65546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * generic icon for the developer rather than the icon for an individual app.</li> 66fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 67fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * <li>settingsActivity: the activity which is launched to allow the user to modify the setting 68546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * value. The activity must be in the same package as the subclass of 69fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * {@link SettingInjectorService}. The activity should use your own branding to help emphasize 70fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * to the user that it is not part of the system settings.</li> 71fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * </ul> 72fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 73cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * To ensure a good user experience, your {@link android.app.Application#onCreate()}, 74248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * and {@link #onGetEnabled()} methods must all be fast. If either is slow, 75248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * it can delay the display of settings values for other apps as well. Note further that these 76248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * methods are called on your app's UI thread. 77cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * <p/> 78fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * For compactness, only one copy of a given setting should be injected. If each account has a 79248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * distinct value for the setting, then only {@code settingsActivity} should display the value for 80fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * each account. 81fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill */ 82cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neillpublic abstract class SettingInjectorService extends Service { 83fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 844a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill private static final String TAG = "SettingInjectorService"; 854a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill 86fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill /** 87546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * Intent action that must be declared in the manifest for the subclass. Used to start the 88546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * service to read the dynamic status for the setting. 89546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill */ 90546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill public static final String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService"; 91546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill 92546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill /** 93546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * Name of the meta-data tag used to specify the resource file that includes the settings 94546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * attributes. 95546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill */ 96546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill public static final String META_DATA_NAME = "android.location.SettingInjectorService"; 97546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill 98546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill /** 99546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * Name of the XML tag that includes the attributes for the setting. 100546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill */ 101546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill public static final String ATTRIBUTES_NAME = "injected-location-setting"; 102546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill 103546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill /** 104546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * Intent action a client should broadcast when the value of one of its injected settings has 105546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * changed, so that the setting can be updated in the UI. 106546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill */ 107546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill public static final String ACTION_INJECTED_SETTING_CHANGED = 108546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill "android.location.InjectedSettingChanged"; 109546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill 110546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill /** 111fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * Name of the bundle key for the string specifying whether the setting is currently enabled. 112fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 113fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * @hide 114fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill */ 115fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill public static final String ENABLED_KEY = "enabled"; 116fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 117fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill /** 118fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * Name of the intent key used to specify the messenger 119fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * 120fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill * @hide 121fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill */ 122fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill public static final String MESSENGER_KEY = "messenger"; 123fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 1244a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill private final String mName; 125fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 1264a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill /** 1274a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * Constructor. 1284a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill * 129cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * @param name used to identify your subclass in log messages 1304a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill */ 1314a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill public SettingInjectorService(String name) { 1324a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill mName = name; 133fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill } 134fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 135fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill @Override 136cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill public final IBinder onBind(Intent intent) { 137cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill return null; 138cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill } 139cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill 140cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill @Override 141cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill public final void onStart(Intent intent, int startId) { 142cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill super.onStart(intent, startId); 143cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill } 144cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill 145cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill @Override 146cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill public final int onStartCommand(Intent intent, int flags, int startId) { 147cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill onHandleIntent(intent); 148cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill stopSelf(startId); 149cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill return START_NOT_STICKY; 150cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill } 151cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill 152cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill private void onHandleIntent(Intent intent) { 153cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill 154cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill boolean enabled; 1554a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill try { 156cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill enabled = onGetEnabled(); 1574a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill } catch (RuntimeException e) { 158cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill // Exception. Send status anyway, so that settings injector can immediately start 159cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill // loading the status of the next setting. 160248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill sendStatus(intent, true); 161cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill throw e; 1624a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill } 163fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 164248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill sendStatus(intent, enabled); 165cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill } 166cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill 167cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill /** 168248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * Send the enabled values back to the caller via the messenger encoded in the 169cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * intent. 170cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill */ 171248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill private void sendStatus(Intent intent, boolean enabled) { 172fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill Message message = Message.obtain(); 173fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill Bundle bundle = new Bundle(); 174cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill bundle.putBoolean(ENABLED_KEY, enabled); 175fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill message.setData(bundle); 176fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 1774a7c49c81f021ebb01c1ac06737b4e705f212783Tom O'Neill if (Log.isLoggable(TAG, Log.DEBUG)) { 178248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill Log.d(TAG, mName + ": received " + intent 179cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill + ", enabled=" + enabled + ", sending message: " + message); 180fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill } 181cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill 182cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY); 183fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill try { 184fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill messenger.send(message); 185fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill } catch (RemoteException e) { 186cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill Log.e(TAG, mName + ": sending dynamic status failed", e); 187fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill } 188fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill } 189fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 190fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill /** 191248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * This method is no longer called, because status values are no longer shown for any injected 192248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * setting. 193546113d4c290f36bf21b1e9c7b93d1592df17fceTom O'Neill * 194248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * @return ignored 195248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * 196248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill * @deprecated not called any more 197fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill */ 198248ada68cce2d1ab8f59ef18b869d866f4af6045Tom O'Neill @Deprecated 19917c5e79496bc1e2d53bc3c4e33bad4b39b80c36dTom O'Neill protected abstract String onGetSummary(); 200fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill 201fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill /** 202cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * Returns the {@link android.preference.Preference#isEnabled()} value. Should not perform 203cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * unpredictably-long operations such as network access--see the running-time comments in the 204cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * class-level javadoc. 205cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * <p/> 206cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * Note that to prevent churn in the settings list, there is no support for dynamically choosing 207cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * to hide a setting. Instead you should have this method return false, which will disable the 208cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * setting and its link to your setting activity. One reason why you might choose to do this is 209cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * if {@link android.provider.Settings.Secure#LOCATION_MODE} is {@link 210cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * android.provider.Settings.Secure#LOCATION_MODE_OFF}. 211cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * <p/> 212cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * It is possible that the user may click on the setting before this method returns, so your 213cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * settings activity must handle the case where it is invoked even though the setting is 214cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * disabled. The simplest approach may be to simply call {@link android.app.Activity#finish()} 215cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * when disabled. 216cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * 217cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill * @return the {@link android.preference.Preference#isEnabled()} value 218fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill */ 219cef05c28eb452810e4b79895970457ff2bdef5b4Tom O'Neill protected abstract boolean onGetEnabled(); 220fa2992c412c08f76331a3f58ca57cf8cf04e7b84Tom O'Neill} 221