diff options
author | Tom O'Neill <tomo@google.com> | 2013-08-13 14:41:22 -0700 |
---|---|---|
committer | Tom O'Neill <tomo@google.com> | 2013-08-13 14:41:22 -0700 |
commit | fa2992c412c08f76331a3f58ca57cf8cf04e7b84 (patch) | |
tree | 8ff95fba0faff30428923dfcee0c5dda4596f9a8 /location/java/android | |
parent | 5893a97cbf398ca3e1bff5444454343d94e25a4c (diff) | |
download | frameworks_base-fa2992c412c08f76331a3f58ca57cf8cf04e7b84.zip frameworks_base-fa2992c412c08f76331a3f58ca57cf8cf04e7b84.tar.gz frameworks_base-fa2992c412c08f76331a3f58ca57cf8cf04e7b84.tar.bz2 |
API for location settings injection
- Partial fix for b/10287745
Change-Id: Ie998ce0a7b350e4183fce5753bfac3eb51238ff4
Diffstat (limited to 'location/java/android')
-rw-r--r-- | location/java/android/location/SettingInjectorService.java | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/location/java/android/location/SettingInjectorService.java b/location/java/android/location/SettingInjectorService.java new file mode 100644 index 0000000..d410408 --- /dev/null +++ b/location/java/android/location/SettingInjectorService.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2013 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 android.location; + +import android.app.IntentService; +import android.content.Intent; +import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.preference.Preference; +import android.util.Log; + +/** + * Dynamically specifies the summary (subtile) and enabled status of a preference injected into + * the "Settings > Location > Location services" list. + * + * The location services list is intended for use only by preferences that affect multiple apps from + * the same developer. Location settings that apply only to one app should be shown within that app, + * rather than in the system settings. + * + * To add a preference to the list, a subclass of {@link SettingInjectorService} must be declared in + * the manifest as so: + * <pre> + * <service android:name="com.example.android.injector.MyInjectorService" > + * <intent-filter> + * <action android:name="com.android.settings.InjectedLocationSetting" /> + * </intent-filter> + * + * <meta-data + * android:name="com.android.settings.InjectedLocationSetting" + * android:resource="@xml/my_injected_location_setting" /> + * </service> + * </pre> + * The resource file specifies the static data for the setting: + * <pre> + * <injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android" + * android:label="@string/injected_setting_label" + * android:icon="@drawable/ic_launcher" + * android:settingsActivity="com.example.android.injector.MySettingActivity" + * /> + * </pre> + * Here: + * <ul> + * <li>label: The {@link Preference#getTitle()} value. The title should make it clear which apps + * are affected by the setting, typically by including the name of the developer. For example, + * "Acme Corp. ads preferences." </li> + * + * <li>icon: The {@link Preference#getIcon()} value. Typically this will be a generic icon for + * the developer rather than the icon for an individual app.</li> + * + * <li>settingsActivity: the activity which is launched to allow the user to modify the setting + * value The activity must be in the same package as the subclass of + * {@link SettingInjectorService}. The activity should use your own branding to help emphasize + * to the user that it is not part of the system settings.</li> + * </ul> + * + * For consistency, the label and {@link #getStatus()} values should be provided in all of the + * locales supported by the system settings app. The text should not contain offensive language. + * + * For compactness, only one copy of a given setting should be injected. If each account has a + * distinct value for the setting, then the {@link #getStatus()} value should represent a summary of + * the state across all of the accounts and {@code settingsActivity} should display the value for + * each account. + * + * Apps that violate these guidelines will be taken down from the Google Play Store and/or flagged + * as malware. + */ +// TODO: is there a public list of supported locales? +// TODO: is there a public list of guidelines for settings text? +public abstract class SettingInjectorService extends IntentService { + + /** + * Name of the bundle key for the string specifying the status of the setting (e.g., "ON" or + * "OFF"). + * + * @hide + */ + public static final String STATUS_KEY = "status"; + + /** + * Name of the bundle key for the string specifying whether the setting is currently enabled. + * + * @hide + */ + public static final String ENABLED_KEY = "enabled"; + + /** + * Name of the intent key used to specify the messenger + * + * @hide + */ + public static final String MESSENGER_KEY = "messenger"; + + private final String mLogTag; + + /** + * Constructor. + * + * @param logTag used for logging, must be less than 23 characters + */ + public SettingInjectorService(String logTag) { + super(logTag); + + // Fast fail if log tag is too long + Log.isLoggable(logTag, Log.WARN); + + mLogTag = logTag; + } + + @Override + final protected void onHandleIntent(Intent intent) { + // Get messenger first to ensure intent doesn't get messed with (in case we later decide + // to pass intent into getStatus()) + Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY); + + Status status = getStatus(); + + // Send the status back to the caller via the messenger + Message message = Message.obtain(); + Bundle bundle = new Bundle(); + bundle.putString(STATUS_KEY, status.summary); + bundle.putBoolean(ENABLED_KEY, status.enabled); + message.setData(bundle); + + if (Log.isLoggable(mLogTag, Log.DEBUG)) { + Log.d(mLogTag, + "received " + intent + " and " + status + ", sending message: " + message); + } + try { + messenger.send(message); + } catch (RemoteException e) { + Log.e(mLogTag, "", e); + } + } + + /** + * Reads the status of the setting. + */ + protected abstract Status getStatus(); + + /** + * Dynamic characteristics of an injected location setting. + */ + public static final class Status { + + public final String summary; + + public final boolean enabled; + + /** + * Constructor. + * + * @param summary the {@link Preference#getSummary()} value + * @param enabled the {@link Preference#isEnabled()} value + */ + public Status(String summary, boolean enabled) { + this.summary = summary; + this.enabled = enabled; + } + + @Override + public String toString() { + return "Status{summary='" + summary + '\'' + ", enabled=" + enabled + '}'; + } + } +} |