am cef05c28: Incorporate new API council comments
* commit 'cef05c28eb452810e4b79895970457ff2bdef5b4': Incorporate new API council comments
This commit is contained in:
@@ -11895,20 +11895,19 @@ package android.location {
|
|||||||
field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
|
field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class SettingInjectorService extends android.app.IntentService {
|
public abstract class SettingInjectorService extends android.app.Service {
|
||||||
ctor public SettingInjectorService(java.lang.String);
|
ctor public SettingInjectorService(java.lang.String);
|
||||||
method protected abstract android.location.SettingInjectorService.Status getStatus();
|
method public final android.os.IBinder onBind(android.content.Intent);
|
||||||
method protected final void onHandleIntent(android.content.Intent);
|
method protected abstract boolean onGetEnabled();
|
||||||
|
method protected abstract java.lang.String onGetSummary();
|
||||||
|
method public final void onStart(android.content.Intent, int);
|
||||||
|
method public final int onStartCommand(android.content.Intent, int, int);
|
||||||
field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
|
field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
|
||||||
field public static final java.lang.String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
|
field public static final java.lang.String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
|
||||||
field public static final java.lang.String ATTRIBUTES_NAME = "injected-location-setting";
|
field public static final java.lang.String ATTRIBUTES_NAME = "injected-location-setting";
|
||||||
field public static final java.lang.String META_DATA_NAME = "android.location.SettingInjectorService";
|
field public static final java.lang.String META_DATA_NAME = "android.location.SettingInjectorService";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SettingInjectorService.Status {
|
|
||||||
ctor public SettingInjectorService.Status(java.lang.String, boolean);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
package android.media {
|
package android.media {
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
package android.location;
|
package android.location;
|
||||||
|
|
||||||
import android.app.IntentService;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Messenger;
|
import android.os.Messenger;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@@ -26,12 +27,12 @@ import android.util.Log;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Dynamically specifies the summary (subtitle) and enabled status of a preference injected into
|
* Dynamically specifies the summary (subtitle) and enabled status of a preference injected into
|
||||||
* the list of location services displayed by the system settings app.
|
* the list of app settings displayed by the system settings app
|
||||||
*
|
* <p/>
|
||||||
* The location services list is intended for use only by preferences that affect multiple apps from
|
* For use only by apps that are included in the system image, for preferences that affect multiple
|
||||||
* the same developer. Location settings that apply only to one app should be shown within that app,
|
* apps. Location settings that apply only to one app should be shown within that app,
|
||||||
* rather than in the system settings.
|
* rather than in the system settings.
|
||||||
*
|
* <p/>
|
||||||
* To add a preference to the list, a subclass of {@link SettingInjectorService} must be declared in
|
* To add a preference to the list, a subclass of {@link SettingInjectorService} must be declared in
|
||||||
* the manifest as so:
|
* the manifest as so:
|
||||||
*
|
*
|
||||||
@@ -69,21 +70,17 @@ import android.util.Log;
|
|||||||
* to the user that it is not part of the system settings.</li>
|
* to the user that it is not part of the system settings.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* To ensure a good user experience, the average time from the start of
|
* To ensure a good user experience, your {@link android.app.Application#onCreate()},
|
||||||
* {@link #startService(Intent)} to the end of {@link #onHandleIntent(Intent)} should be less
|
* {@link #onGetSummary()}, and {@link #onGetEnabled()} methods must all be fast. If any are slow,
|
||||||
* than 300 msec even if your app is not already in memory. This means that both your
|
* it can delay the display of settings values for other apps as well. Note further that all are
|
||||||
* {@link android.app.Application#onCreate()} and your {@link #getStatus()} must be fast. If
|
* called on your app's UI thread.
|
||||||
* either is slow, it can delay the display of settings values for other apps as well.
|
* <p/>
|
||||||
*
|
|
||||||
* For compactness, only one copy of a given setting should be injected. If each account has a
|
* 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
|
* distinct value for the setting, then the {@link #onGetSummary()} value should represent a summary
|
||||||
* the state across all of the accounts and {@code settingsActivity} should display the value for
|
* of the state across all of the accounts and {@code settingsActivity} should display the value for
|
||||||
* each account.
|
* each account.
|
||||||
*/
|
*/
|
||||||
// TODO: is there a public list of supported locales?
|
public abstract class SettingInjectorService extends Service {
|
||||||
// TODO: is there a public list of guidelines for settings text?
|
|
||||||
// TODO: would a bound service be better? E.g., we could just disconnect if a service took too long
|
|
||||||
public abstract class SettingInjectorService extends IntentService {
|
|
||||||
|
|
||||||
private static final String TAG = "SettingInjectorService";
|
private static final String TAG = "SettingInjectorService";
|
||||||
|
|
||||||
@@ -138,100 +135,104 @@ public abstract class SettingInjectorService extends IntentService {
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param name used to name the worker thread and in log messages
|
* @param name used to identify your subclass in log messages
|
||||||
*/
|
*/
|
||||||
public SettingInjectorService(String name) {
|
public SettingInjectorService(String name) {
|
||||||
super(name);
|
|
||||||
mName = name;
|
mName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
final protected void onHandleIntent(Intent intent) {
|
public final IBinder onBind(Intent intent) {
|
||||||
// Get messenger first to ensure intent doesn't get messed with (in case we later decide
|
return null;
|
||||||
// to pass intent into getStatus())
|
}
|
||||||
Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY);
|
|
||||||
|
|
||||||
Status status;
|
@Override
|
||||||
|
public final void onStart(Intent intent, int startId) {
|
||||||
|
super.onStart(intent, startId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
onHandleIntent(intent);
|
||||||
|
stopSelf(startId);
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onHandleIntent(Intent intent) {
|
||||||
|
|
||||||
|
String summary;
|
||||||
try {
|
try {
|
||||||
status = getStatus();
|
summary = onGetSummary();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
Log.e(TAG, mName + ": error getting status", e);
|
// Exception. Send status anyway, so that settings injector can immediately start
|
||||||
status = null;
|
// loading the status of the next setting.
|
||||||
|
sendStatus(intent, null, true);
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the status back to the caller via the messenger
|
boolean enabled;
|
||||||
|
try {
|
||||||
|
enabled = onGetEnabled();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// Exception. Send status anyway, so that settings injector can immediately start
|
||||||
|
// loading the status of the next setting.
|
||||||
|
sendStatus(intent, summary, true);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendStatus(intent, summary, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the summary and enabled values back to the caller via the messenger encoded in the
|
||||||
|
* intent.
|
||||||
|
*/
|
||||||
|
private void sendStatus(Intent intent, String summary, boolean enabled) {
|
||||||
Message message = Message.obtain();
|
Message message = Message.obtain();
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
if (status != null) {
|
bundle.putString(SUMMARY_KEY, summary);
|
||||||
bundle.putString(SUMMARY_KEY, status.summary);
|
bundle.putBoolean(ENABLED_KEY, enabled);
|
||||||
bundle.putBoolean(ENABLED_KEY, status.enabled);
|
|
||||||
}
|
|
||||||
message.setData(bundle);
|
message.setData(bundle);
|
||||||
|
|
||||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||||
Log.d(TAG, mName + ": received " + intent + " and " + status
|
Log.d(TAG, mName + ": received " + intent + ", summary=" + summary
|
||||||
+ ", sending message: " + message);
|
+ ", enabled=" + enabled + ", sending message: " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY);
|
||||||
try {
|
try {
|
||||||
messenger.send(message);
|
messenger.send(message);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, mName + ": sending status failed", e);
|
Log.e(TAG, mName + ": sending dynamic status failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the status of the setting. Should not perform unpredictably-long operations such as
|
* Returns the {@link android.preference.Preference#getSummary()} value (allowed to be null or
|
||||||
* network access--see the running-time comments in the class-level javadoc.
|
* empty). Should not perform unpredictably-long operations such as network access--see the
|
||||||
|
* running-time comments in the class-level javadoc.
|
||||||
*
|
*
|
||||||
* @return the status of the setting value
|
* @return the {@link android.preference.Preference#getSummary()} value
|
||||||
*/
|
*/
|
||||||
protected abstract Status getStatus();
|
protected abstract String onGetSummary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dynamic characteristics of an injected location setting.
|
* Returns the {@link android.preference.Preference#isEnabled()} value. Should not perform
|
||||||
|
* unpredictably-long operations such as network access--see the running-time comments in the
|
||||||
|
* class-level javadoc.
|
||||||
|
* <p/>
|
||||||
|
* Note that to prevent churn in the settings list, there is no support for dynamically choosing
|
||||||
|
* to hide a setting. Instead you should have this method return false, which will disable the
|
||||||
|
* setting and its link to your setting activity. One reason why you might choose to do this is
|
||||||
|
* if {@link android.provider.Settings.Secure#LOCATION_MODE} is {@link
|
||||||
|
* android.provider.Settings.Secure#LOCATION_MODE_OFF}.
|
||||||
|
* <p/>
|
||||||
|
* It is possible that the user may click on the setting before this method returns, so your
|
||||||
|
* settings activity must handle the case where it is invoked even though the setting is
|
||||||
|
* disabled. The simplest approach may be to simply call {@link android.app.Activity#finish()}
|
||||||
|
* when disabled.
|
||||||
|
*
|
||||||
|
* @return the {@link android.preference.Preference#isEnabled()} value
|
||||||
*/
|
*/
|
||||||
public static final class Status {
|
protected abstract boolean onGetEnabled();
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link android.preference.Preference#getSummary()} value.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public final String summary;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link android.preference.Preference#isEnabled()} value.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public final boolean enabled;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
* <p/>
|
|
||||||
* Note that to prevent churn in the settings list, there is no support for dynamically
|
|
||||||
* choosing to hide a setting. Instead you should provide a {@code enabled} value of false,
|
|
||||||
* which will disable the setting and its link to your setting activity. One reason why you
|
|
||||||
* might choose to do this is if {@link android.provider.Settings.Secure#LOCATION_MODE}
|
|
||||||
* is {@link android.provider.Settings.Secure#LOCATION_MODE_OFF}.
|
|
||||||
*
|
|
||||||
* It is possible that the user may click on the setting before you return a false value for
|
|
||||||
* {@code enabled}, so your settings activity must handle the case where it is invoked even
|
|
||||||
* though the setting is disabled. The simplest approach may be to simply call
|
|
||||||
* {@link android.app.Activity#finish()} when disabled.
|
|
||||||
*
|
|
||||||
* @param summary the {@link android.preference.Preference#getSummary()} value (allowed to
|
|
||||||
* be null or empty)
|
|
||||||
* @param enabled the {@link android.preference.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 + '}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user