diff options
| author | 2018-11-09 17:29:35 +0000 | |
|---|---|---|
| committer | 2018-11-09 17:29:35 +0000 | |
| commit | cb35c807eae0def51cc512fa699c4d7ee972e66e (patch) | |
| tree | 80048ebd6e6c39a9a57c2cd03239baf738caec14 | |
| parent | 9403a36202d849e6a206ff985fc58c973a405092 (diff) | |
| parent | ed9882833578e84de9aafcc78107897bded924ba (diff) | |
Merge "Allow location provider to deep link into permissions UI"
| -rw-r--r-- | api/system-current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/content/Intent.java | 28 | ||||
| -rw-r--r-- | location/java/android/location/ILocationManager.aidl | 14 | ||||
| -rw-r--r-- | location/java/android/location/LocationManager.java | 28 | ||||
| -rw-r--r-- | services/core/java/com/android/server/LocationManagerService.java | 45 |
5 files changed, 116 insertions, 3 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index da1adac5bddf..237d4c427e90 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1052,6 +1052,7 @@ package android.content { field public static final java.lang.String ACTION_INSTALL_INSTANT_APP_PACKAGE = "android.intent.action.INSTALL_INSTANT_APP_PACKAGE"; field public static final java.lang.String ACTION_INSTANT_APP_RESOLVER_SETTINGS = "android.intent.action.INSTANT_APP_RESOLVER_SETTINGS"; field public static final java.lang.String ACTION_INTENT_FILTER_NEEDS_VERIFICATION = "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION"; + field public static final java.lang.String ACTION_MANAGE_APP_PERMISSION = "android.intent.action.MANAGE_APP_PERMISSION"; field public static final java.lang.String ACTION_MANAGE_APP_PERMISSIONS = "android.intent.action.MANAGE_APP_PERMISSIONS"; field public static final java.lang.String ACTION_MANAGE_PERMISSIONS = "android.intent.action.MANAGE_PERMISSIONS"; field public static final java.lang.String ACTION_MANAGE_PERMISSION_APPS = "android.intent.action.MANAGE_PERMISSION_APPS"; @@ -2719,6 +2720,7 @@ package android.location { public class LocationManager { method public deprecated boolean addGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener); method public deprecated boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener); + method public android.app.PendingIntent createManageLocationPermissionIntent(java.lang.String, java.lang.String); method public void flushGnssBatch(); method public int getGnssBatchSize(); method public java.lang.String getNetworkProviderPackage(); @@ -3645,9 +3647,9 @@ package android.net.wifi { method public boolean isPortableHotspotSupported(); method public boolean isWifiApEnabled(); method public boolean isWifiScannerSupported(); - method public void registerNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback, android.os.Handler); method public boolean isWpa3SaeSupported(); method public boolean isWpa3SuiteBSupported(); + method public void registerNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback, android.os.Handler); method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration); method public boolean startScan(android.os.WorkSource); method public void unregisterNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 6c0fa4c4d35c..aa34da8e0159 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1753,6 +1753,30 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.MANAGE_APP_PERMISSIONS"; /** + * Activity action: Launch UI to manage a specific permissions of an app. + * <p> + * Input: {@link #EXTRA_PACKAGE_NAME} specifies the package whose permission + * will be managed by the launched UI. + * </p> + * <p> + * Input: {@link #EXTRA_PERMISSION_NAME} specifies the (individual) permission + * that should be managed by the launched UI. + * </p> + * <p> + * Output: Nothing. + * </p> + * + * @see #EXTRA_PACKAGE_NAME + * @see #EXTRA_PERMISSION_NAME + * + * @hide + */ + @SystemApi + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_MANAGE_APP_PERMISSION = + "android.intent.action.MANAGE_APP_PERMISSION"; + + /** * Activity action: Launch UI to manage permissions. * <p> * Input: Nothing. @@ -1882,8 +1906,8 @@ public class Intent implements Parcelable, Cloneable { /** * Activity action: Launch UI to manage which apps have a given permission. * <p> - * Input: {@link #EXTRA_PERMISSION_NAME} specifies the permission access - * to which will be managed by the launched UI. + * Input: {@link #EXTRA_PERMISSION_NAME} specifies the permission group + * which will be managed by the launched UI. * </p> * <p> * Output: Nothing. diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index 1276881704cf..b5d835a90c7b 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -120,4 +120,18 @@ interface ILocationManager // used by gts tests to verify throttling whitelist String[] getBackgroundThrottlingWhitelist(); + + /** + * Allow the {@link android.location.LocationManager#getNetworkProviderPackage location + * provider} to start the UI to modify the location permission for a package. + * + * <p>Can only be called by the location provider. + * + * @param packageName The package the permission belongs to + * @param permission The (individual) permission to switch + * + * @return A pending intent that starts the permission management UI or {@code null} if the + * intent cannot be created + */ + PendingIntent createManageLocationPermissionIntent(in String packageName, in String permission); } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index b1968babe99f..02680ab86062 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.LOCATION_HARDWARE; import static android.Manifest.permission.WRITE_SECURE_SETTINGS; import android.Manifest; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; @@ -43,7 +44,9 @@ import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; + import com.android.internal.location.ProviderProperties; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -2393,4 +2396,29 @@ public class LocationManager { return null; } } + + /** + * Allow the {@link android.location.LocationManager#getNetworkProviderPackage location + * provider} to start the UI to modify the location permission for a package. + * + * <p>Can only be called by the location provider. + * + * @param packageName The package the permission belongs to + * @param permission The (individual) location permission to switch + * + * @return A one-shot pending intent that starts the permission management UI or {@code null} if + * the intent cannot be created + * + * @hide + */ + @SystemApi + public @Nullable PendingIntent createManageLocationPermissionIntent(@NonNull String packageName, + @NonNull String permission) { + try { + return mService.createManageLocationPermissionIntent(packageName, permission); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return null; + } + } } diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index 90ad09eed5d7..046442a0b3ad 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -18,6 +18,7 @@ package com.android.server; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -83,6 +84,7 @@ import com.android.internal.location.ProviderRequest; import com.android.internal.os.BackgroundThread; import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; +import com.android.internal.util.Preconditions; import com.android.server.location.ActivityRecognitionProxy; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; @@ -111,6 +113,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Set; /** @@ -3420,6 +3423,48 @@ public class LocationManagerService extends ILocationManager.Stub { } } + @Override + public PendingIntent createManageLocationPermissionIntent(String packageName, + String permission) { + Preconditions.checkNotNull(packageName); + Preconditions.checkArgument(permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) + || permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION) + || permission.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)); + + int callingUid = Binder.getCallingUid(); + long token = Binder.clearCallingIdentity(); + try { + String locProvider = getNetworkProviderPackage(); + if (locProvider == null) { + return null; + } + + PackageInfo locProviderInfo; + try { + locProviderInfo = mContext.getPackageManager().getPackageInfo( + locProvider, PackageManager.MATCH_DIRECT_BOOT_AUTO); + } catch (NameNotFoundException e) { + Log.e(TAG, "Could not resolve " + locProvider, e); + return null; + } + + if (locProviderInfo.applicationInfo.uid != callingUid) { + throw new SecurityException("Only " + locProvider + " can call this API"); + } + + Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(Intent.EXTRA_PERMISSION_NAME, permission); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + return PendingIntent.getActivity(mContext, + Objects.hash(packageName, permission), intent, + PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); + } finally { + Binder.restoreCallingIdentity(token); + } + } + private void log(String log) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Slog.d(TAG, log); |