diff options
Diffstat (limited to 'location/lib/java')
-rw-r--r-- | location/lib/java/com/android/location/provider/LocationProviderBase.java | 264 | ||||
-rw-r--r-- | location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java | 10 |
2 files changed, 182 insertions, 92 deletions
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java index d45a4bac8f96..5bcec92c4fba 100644 --- a/location/lib/java/com/android/location/provider/LocationProviderBase.java +++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java @@ -16,6 +16,7 @@ package com.android.location.provider; +import android.annotation.Nullable; import android.content.Context; import android.location.ILocationManager; import android.location.Location; @@ -29,12 +30,11 @@ import android.os.WorkSource; import android.util.Log; import com.android.internal.location.ILocationProvider; +import com.android.internal.location.ILocationProviderManager; import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; -import com.android.internal.util.FastPrintWriter; import java.io.FileDescriptor; -import java.io.FileOutputStream; import java.io.PrintWriter; /** @@ -55,12 +55,6 @@ import java.io.PrintWriter; * of this package for more information. */ public abstract class LocationProviderBase { - private final String TAG; - - /** @hide */ - protected final ILocationManager mLocationManager; - private final ProviderProperties mProperties; - private final IBinder mBinder; /** * Bundle key for a version of the location containing no GPS data. @@ -77,49 +71,34 @@ public abstract class LocationProviderBase { */ public static final String FUSED_PROVIDER = LocationManager.FUSED_PROVIDER; - private final class Service extends ILocationProvider.Stub { - @Override - public void enable() { - onEnable(); - } - @Override - public void disable() { - onDisable(); - } - @Override - public void setRequest(ProviderRequest request, WorkSource ws) { - onSetRequest(new ProviderRequestUnbundled(request), ws); - } - @Override - public ProviderProperties getProperties() { - return mProperties; - } - @Override - public int getStatus(Bundle extras) { - return onGetStatus(extras); - } - @Override - public long getStatusUpdateTime() { - return onGetStatusUpdateTime(); - } - @Override - public boolean sendExtraCommand(String command, Bundle extras) { - return onSendExtraCommand(command, extras); - } - @Override - public void dump(FileDescriptor fd, String[] args) { - PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd)); - onDump(fd, pw, args); - pw.flush(); - } - } + private final String mTag; + private final IBinder mBinder; + + /** + * This field may be removed in the future, do not rely on it. + * + * @deprecated Do not use this field! Use LocationManager APIs instead. If you use this field + * you may be broken in the future. + * @hide + */ + @Deprecated + protected final ILocationManager mLocationManager; + + // write locked on mBinder, read lock is optional depending on atomicity requirements + @Nullable private volatile ILocationProviderManager mManager; + private volatile ProviderProperties mProperties; + private volatile boolean mEnabled; public LocationProviderBase(String tag, ProviderPropertiesUnbundled properties) { - TAG = tag; - IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE); - mLocationManager = ILocationManager.Stub.asInterface(b); - mProperties = properties.getProviderProperties(); + mTag = tag; mBinder = new Service(); + + mLocationManager = ILocationManager.Stub.asInterface( + ServiceManager.getService(Context.LOCATION_SERVICE)); + + mManager = null; + mProperties = properties.getProviderProperties(); + mEnabled = true; } public IBinder getBinder() { @@ -127,51 +106,116 @@ public abstract class LocationProviderBase { } /** - * Used by the location provider to report new locations. + * Sets whether this provider is currently enabled or not. Note that this is specific to the + * provider only, and is not related to global location settings. This is a hint to the Location + * Manager that this provider will generally be unable to fulfill incoming requests. This + * provider may still receive callbacks to onSetRequest while not enabled, and must decide + * whether to attempt to satisfy those requests or not. * - * @param location new Location to report - * - * Requires the android.permission.INSTALL_LOCATION_PROVIDER permission. + * Some guidelines: providers should set their own enabled/disabled status based only on state + * "owned" by that provider. For instance, providers should not take into account the state of + * the location master setting when setting themselves enabled or disabled, as this state is not + * owned by a particular provider. If a provider requires some additional user consent that is + * particular to the provider, this should be use to set the enabled/disabled state. If the + * provider proxies to another provider, the child provider's enabled/disabled state should be + * taken into account in the parent's enabled/disabled state. For most providers, it is expected + * that they will be always enabled. */ - public final void reportLocation(Location location) { - try { - mLocationManager.reportLocation(location, false); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException", e); - } catch (Exception e) { - // never crash provider, might be running in a system process - Log.e(TAG, "Exception", e); + public void setEnabled(boolean enabled) { + synchronized (mBinder) { + if (mEnabled == enabled) { + return; + } + + mEnabled = enabled; + } + + ILocationProviderManager manager = mManager; + if (manager != null) { + try { + manager.onSetEnabled(mEnabled); + } catch (RemoteException | RuntimeException e) { + Log.w(mTag, e); + } } } /** - * Enable the location provider. - * <p>The provider may initialize resources, but does - * not yet need to report locations. + * Sets the provider properties that may be queried by clients. Generally speaking, providers + * should try to avoid changing their properties after construction. */ - public abstract void onEnable(); + public void setProperties(ProviderPropertiesUnbundled properties) { + synchronized (mBinder) { + mProperties = properties.getProviderProperties(); + } + + ILocationProviderManager manager = mManager; + if (manager != null) { + try { + manager.onSetProperties(mProperties); + } catch (RemoteException | RuntimeException e) { + Log.w(mTag, e); + } + } + } /** - * Disable the location provider. - * <p>The provider must release resources, and stop - * performing work. It may no longer report locations. + * Returns true if this provider has been set as enabled. This will be true unless explicitly + * set otherwise. */ - public abstract void onDisable(); + public boolean isEnabled() { + return mEnabled; + } /** - * Set the {@link ProviderRequest} requirements for this provider. - * <p>Each call to this method overrides all previous requests. - * <p>This method might trigger the provider to start returning - * locations, or to stop returning locations, depending on the - * parameters in the request. + * Reports a new location from this provider. */ - public abstract void onSetRequest(ProviderRequestUnbundled request, WorkSource source); + public void reportLocation(Location location) { + ILocationProviderManager manager = mManager; + if (manager != null) { + try { + manager.onReportLocation(location); + } catch (RemoteException | RuntimeException e) { + Log.w(mTag, e); + } + } + } + + protected void onInit() { + // call once so that providers designed for APIs pre-Q are not broken + onEnable(); + } + + /** + * @deprecated This callback will be invoked once when the provider is created to maintain + * backwards compatibility with providers not designed for Android Q and above. This method + * should only be implemented in location providers that need to support SDKs below Android Q. + * Even in this case, it is usually unnecessary to implement this callback with the correct + * design. This method may be removed in the future. + */ + @Deprecated + protected void onEnable() {} + + /** + * @deprecated This callback will be never be invoked on Android Q and above. This method should + * only be implemented in location providers that need to support SDKs below Android Q. Even in + * this case, it is usually unnecessary to implement this callback with the correct design. This + * method may be removed in the future. + */ + @Deprecated + protected void onDisable() {} + + /** + * Set the {@link ProviderRequest} requirements for this provider. Each call to this method + * overrides all previous requests. This method might trigger the provider to start returning + * locations, or to stop returning locations, depending on the parameters in the request. + */ + protected abstract void onSetRequest(ProviderRequestUnbundled request, WorkSource source); /** * Dump debug information. */ - public void onDump(FileDescriptor fd, PrintWriter pw, String[] args) { - } + protected void onDump(FileDescriptor fd, PrintWriter pw, String[] args) {} /** * This method will no longer be invoked. @@ -187,10 +231,12 @@ public abstract class LocationProviderBase { * <p>If extras is non-null, additional status information may be * added to it in the form of provider-specific key/value pairs. * - * @deprecated This method will no longer be invoked. + * @deprecated This callback will be never be invoked on Android Q and above. This method should + * only be implemented in location providers that need to support SDKs below Android Q. This + * method may be removed in the future. */ @Deprecated - public int onGetStatus(Bundle extras) { + protected int onGetStatus(Bundle extras) { return LocationProvider.AVAILABLE; } @@ -206,24 +252,64 @@ public abstract class LocationProviderBase { * * @return time of last status update in millis since last reboot * - * @deprecated This method will no longer be invoked. + * @deprecated This callback will be never be invoked on Android Q and above. This method should + * only be implemented in location providers that need to support SDKs below Android Q. This + * method may be removed in the future. */ @Deprecated - public long onGetStatusUpdateTime() { + protected long onGetStatusUpdateTime() { return 0; } /** - * Implements addditional location provider specific additional commands. - * - * @param command name of the command to send to the provider. - * @param extras optional arguments for the command (or null). - * The provider may optionally fill the extras Bundle with results from the command. - * - * @return true if the command succeeds. + * Implements location provider specific custom commands. The return value will be ignored on + * Android Q and above. */ - public boolean onSendExtraCommand(String command, Bundle extras) { - // default implementation + protected boolean onSendExtraCommand(@Nullable String command, @Nullable Bundle extras) { return false; } + + private final class Service extends ILocationProvider.Stub { + + @Override + public void setLocationProviderManager(ILocationProviderManager manager) { + synchronized (mBinder) { + try { + manager.onSetProperties(mProperties); + manager.onSetEnabled(mEnabled); + } catch (RemoteException e) { + Log.w(mTag, e); + } + + mManager = manager; + } + + onInit(); + } + + @Override + public void setRequest(ProviderRequest request, WorkSource ws) { + onSetRequest(new ProviderRequestUnbundled(request), ws); + } + + @Override + public int getStatus(Bundle extras) { + return onGetStatus(extras); + } + + @Override + public long getStatusUpdateTime() { + return onGetStatusUpdateTime(); + } + + @Override + public void sendExtraCommand(String command, Bundle extras) { + onSendExtraCommand(command, extras); + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + onDump(fd, pw, args); + } + } } diff --git a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java index 6a8e61877e46..b825b58cd3e9 100644 --- a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java +++ b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java @@ -16,13 +16,13 @@ package com.android.location.provider; -import java.util.ArrayList; -import java.util.List; - import android.location.LocationRequest; import com.android.internal.location.ProviderRequest; +import java.util.ArrayList; +import java.util.List; + /** * This class is an interface to Provider Requests for unbundled applications. * @@ -46,6 +46,10 @@ public final class ProviderRequestUnbundled { return mRequest.interval; } + public boolean getForceLocation() { + return mRequest.forceLocation; + } + /** * Never null. */ |