summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Svet Ganov <svetoslavganov@google.com> 2017-02-15 10:28:51 -0800
committer Svet Ganov <svetoslavganov@google.com> 2017-02-15 20:32:41 -0800
commitda0acdf938f1d6e7a978e143d5d80d8dd5af52ad (patch)
treea87f84a6afb69607c20513adb4730af5daf7ff92
parent3d52f79be4dba94f046709fabc1bfb911a670709 (diff)
Auto-grant background execution and data access
Companion apps can declare they want background access and background execution exceptions via dedicated permissions in their manifest. If such a permission is requested we auto-grant the corresponding exception after the user has chosen a device from the companion UI. These permissions are appop ones allowing us to use the app ops for gauging whether the user has made a change after we auto-granted the permission since we would like to revoke these special privileges when the app disassociates itself from the companion device if the user did not make an excplicit choice otherwise. While at this auto-grant fixed location permission to the companion device discovery service. Test: manual Change-Id: I46ee4291e5e5a8f7613f0dd75eb61d6b9341f306
-rw-r--r--Android.mk6
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--api/test-current.txt2
-rw-r--r--core/java/android/app/AppOpsManager.java29
-rw-r--r--core/java/android/companion/CompanionDeviceManager.java36
-rw-r--r--core/java/android/companion/ICompanionDeviceDiscoveryService.aidl (renamed from core/java/android/companion/ICompanionDeviceManagerService.aidl)11
-rw-r--r--core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl (renamed from core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl)6
-rw-r--r--core/java/android/companion/ICompanionDeviceManager.aidl6
-rw-r--r--core/java/android/companion/IFindDeviceCallback.aidl (renamed from core/java/android/companion/IOnAssociateCallback.aidl)2
-rw-r--r--core/res/AndroidManifest.xml18
-rw-r--r--core/res/res/values/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java6
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java37
-rw-r--r--services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java11
-rw-r--r--services/print/java/com/android/server/print/CompanionDeviceManagerService.java98
16 files changed, 185 insertions, 97 deletions
diff --git a/Android.mk b/Android.mk
index 28adbcaf88fc..7a8b1b763b4c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -295,9 +295,9 @@ LOCAL_SRC_FILES += \
core/java/android/printservice/IPrintService.aidl \
core/java/android/printservice/IPrintServiceClient.aidl \
core/java/android/companion/ICompanionDeviceManager.aidl \
- core/java/android/companion/ICompanionDeviceManagerService.aidl \
- core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl \
- core/java/android/companion/IOnAssociateCallback.aidl \
+ core/java/android/companion/ICompanionDeviceDiscoveryService.aidl \
+ core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl \
+ core/java/android/companion/IFindDeviceCallback.aidl \
core/java/android/service/dreams/IDreamManager.aidl \
core/java/android/service/dreams/IDreamService.aidl \
core/java/android/service/persistentdata/IPersistentDataBlockService.aidl \
diff --git a/api/current.txt b/api/current.txt
index a03ef38035fb..c5005080ab2b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -121,6 +121,7 @@ package android {
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
+ field public static final java.lang.String RUN_IN_BACKGROUND = "android.permission.RUN_IN_BACKGROUND";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
@@ -139,6 +140,7 @@ package android {
field public static final java.lang.String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
field public static final java.lang.String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
+ field public static final java.lang.String USE_DATA_IN_BACKGROUND = "android.permission.USE_DATA_IN_BACKGROUND";
field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
diff --git a/api/system-current.txt b/api/system-current.txt
index 406d51c4f428..54de0c6fe473 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -211,6 +211,7 @@ package android {
field public static final java.lang.String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
field public static final java.lang.String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
+ field public static final java.lang.String RUN_IN_BACKGROUND = "android.permission.RUN_IN_BACKGROUND";
field public static final java.lang.String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
@@ -248,6 +249,7 @@ package android {
field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
+ field public static final java.lang.String USE_DATA_IN_BACKGROUND = "android.permission.USE_DATA_IN_BACKGROUND";
field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
diff --git a/api/test-current.txt b/api/test-current.txt
index 1be19ed32858..b9cf94d0d7e7 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -121,6 +121,7 @@ package android {
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
+ field public static final java.lang.String RUN_IN_BACKGROUND = "android.permission.RUN_IN_BACKGROUND";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
@@ -139,6 +140,7 @@ package android {
field public static final java.lang.String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
field public static final java.lang.String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
+ field public static final java.lang.String USE_DATA_IN_BACKGROUND = "android.permission.USE_DATA_IN_BACKGROUND";
field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index fb927e96d1f5..6dd31a852172 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -357,7 +357,8 @@ public class AppOpsManager {
public static final String OPSTR_INSTANT_APP_START_FOREGROUND
= "android:instant_app_start_foreground";
- private static final int[] RUNTIME_PERMISSIONS_OPS = {
+ private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
+ // RUNTIME PERMISSIONS
// Contacts
OP_READ_CONTACTS,
OP_WRITE_CONTACTS,
@@ -392,7 +393,13 @@ public class AppOpsManager {
// Camera
OP_CAMERA,
// Body sensors
- OP_BODY_SENSORS
+ OP_BODY_SENSORS,
+
+ // APPOP PERMISSIONS
+ OP_ACCESS_NOTIFICATIONS,
+ OP_SYSTEM_ALERT_WINDOW,
+ OP_WRITE_SETTINGS,
+ OP_REQUEST_INSTALL_PACKAGES,
};
/**
@@ -926,9 +933,9 @@ public class AppOpsManager {
AppOpsManager.MODE_ALLOWED, // OP_RUN_IN_BACKGROUND
AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ACCESSIBILITY_VOLUME
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_DEFAULT, // OP_REQUEST_INSTALL_PACKAGES
+ AppOpsManager.MODE_DEFAULT, // OP_REQUEST_INSTALL_PACKAGES
AppOpsManager.MODE_ALLOWED, // OP_ENTER_PICTURE_IN_PICTURE_ON_HIDE
- AppOpsManager.MODE_DEFAULT, // OP_INSTANT_APP_START_FOREGROUND
+ AppOpsManager.MODE_DEFAULT, // OP_INSTANT_APP_START_FOREGROUND
};
/**
@@ -1018,7 +1025,7 @@ public class AppOpsManager {
/**
* Mapping from a permission to the corresponding app op.
*/
- private static HashMap<String, Integer> sRuntimePermToOp = new HashMap<>();
+ private static HashMap<String, Integer> sPermToOp = new HashMap<>();
static {
if (sOpToSwitch.length != _NUM_OP) {
@@ -1058,9 +1065,9 @@ public class AppOpsManager {
sOpStrToOp.put(sOpToString[i], i);
}
}
- for (int op : RUNTIME_PERMISSIONS_OPS) {
+ for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
if (sOpPerms[op] != null) {
- sRuntimePermToOp.put(sOpPerms[op], op);
+ sPermToOp.put(sOpPerms[op], op);
}
}
}
@@ -1112,12 +1119,12 @@ public class AppOpsManager {
/**
* Retrieve the app op code for a permission, or null if there is not one.
- * This API is intended to be used for mapping runtime permissions to the
- * corresponding app op.
+ * This API is intended to be used for mapping runtime or appop permissions
+ * to the corresponding app op.
* @hide
*/
public static int permissionToOpCode(String permission) {
- Integer boxedOpCode = sRuntimePermToOp.get(permission);
+ Integer boxedOpCode = sPermToOp.get(permission);
return boxedOpCode != null ? boxedOpCode : OP_NONE;
}
@@ -1462,7 +1469,7 @@ public class AppOpsManager {
* @return The app op associated with the permission or null.
*/
public static String permissionToOp(String permission) {
- final Integer opCode = sRuntimePermToOp.get(permission);
+ final Integer opCode = sPermToOp.get(permission);
if (opCode == null) {
return null;
}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index b379c7c57554..c0c1a4dd198b 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -29,12 +29,10 @@ import android.os.RemoteException;
/**
* System level service for managing companion devices
*
- * Usage:
- * To obtain an instance call
- * {@link Context#getSystemService}({@link Context#COMPANION_DEVICE_SERVICE})
- *
- * Then, call {@link #associate} to initiate the flow of associating current package
- * with a device selected by user
+ * <p>To obtain an instance call {@link Context#getSystemService}({@link
+ * Context#COMPANION_DEVICE_SERVICE}) Then, call {@link #associate(AssociationRequest,
+ * Callback, Handler)} to initiate the flow of associating current package with a
+ * device selected by user.</p>
*
* @see AssociationRequest
*/
@@ -47,6 +45,14 @@ public final class CompanionDeviceManager {
public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
/**
+ * The package name of the companion device discovery component.
+ *
+ * @hide
+ */
+ public static final String COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME =
+ "com.android.companiondevicemanager";
+
+ /**
* A callback to receive once at least one suitable device is found, or the search failed
* (e.g. timed out)
*/
@@ -81,13 +87,20 @@ public final class CompanionDeviceManager {
/**
* Associate this app with a companion device, selected by user
*
- * Once at least one appropriate device is found, {@code callback} will be called with a
+ * <p>Once at least one appropriate device is found, {@code callback} will be called with a
* {@link PendingIntent} that can be used to show the list of available devices for the user
* to select.
* It should be started for result (i.e. using
* {@link android.app.Activity#startIntentSenderForResult}), as the resulting
* {@link android.content.Intent} will contain extra {@link #EXTRA_DEVICE}, with the selected
- * device. (e.g. {@link android.bluetooth.BluetoothDevice})
+ * device. (e.g. {@link android.bluetooth.BluetoothDevice})</p>
+ *
+ * <p>If your app needs to be excluded from battery optimizations (run in the background)
+ * or to have unrestricted data access (use data in the background) you can declare that
+ * you use the {@link android.Manifest.permission#RUN_IN_BACKGROUND} and {@link
+ * android.Manifest.permission#USE_DATA_IN_BACKGROUND} respectively. Note that these
+ * special capabilities have a negative effect on the device's battery and user's data
+ * usage, therefore you should requested them when absolutely necessary.</p>
*
* @param request specific details about this request
* @param callback will be called once there's at least one device found for user to choose from
@@ -106,17 +119,16 @@ public final class CompanionDeviceManager {
try {
mService.associate(
request,
- new IOnAssociateCallback.Stub() {
-
+ new IFindDeviceCallback.Stub() {
@Override
- public void onSuccess(PendingIntent launcher) throws RemoteException {
+ public void onSuccess(PendingIntent launcher) {
finalHandler.post(() -> {
callback.onDeviceFound(launcher.getIntentSender());
});
}
@Override
- public void onFailure(CharSequence reason) throws RemoteException {
+ public void onFailure(CharSequence reason) {
finalHandler.post(() -> callback.onFailure(reason));
}
},
diff --git a/core/java/android/companion/ICompanionDeviceManagerService.aidl b/core/java/android/companion/ICompanionDeviceDiscoveryService.aidl
index ff2a7eb957f0..4d779639888e 100644
--- a/core/java/android/companion/ICompanionDeviceManagerService.aidl
+++ b/core/java/android/companion/ICompanionDeviceDiscoveryService.aidl
@@ -17,13 +17,14 @@
package android.companion;
import android.companion.AssociationRequest;
-import android.companion.IOnAssociateCallback;
-
+import android.companion.ICompanionDeviceDiscoveryServiceCallback;
+import android.companion.IFindDeviceCallback;
/** @hide */
-interface ICompanionDeviceManagerService {
+interface ICompanionDeviceDiscoveryService {
void startDiscovery(
in AssociationRequest request,
- in IOnAssociateCallback callback,
- in String callingPackage);
+ in String callingPackage,
+ in IFindDeviceCallback findCallback,
+ in ICompanionDeviceDiscoveryServiceCallback serviceCallback);
}
diff --git a/core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl b/core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl
index c9dd345341b2..7af708e94d97 100644
--- a/core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
+++ b/core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl
@@ -16,9 +16,7 @@
package android.companion;
-import android.bluetooth.BluetoothDevice;
-
/** @hide */
-interface ICompanionDeviceManagerServiceCallback {
- void onDeviceSelected(in BluetoothDevice device);
+interface ICompanionDeviceDiscoveryServiceCallback {
+ void onDeviceSelected(String packageName, int userId);
}
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 065e31be9adf..1d30ada25c62 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -16,7 +16,7 @@
package android.companion;
-import android.companion.IOnAssociateCallback;
+import android.companion.IFindDeviceCallback;
import android.companion.AssociationRequest;
/**
@@ -26,8 +26,8 @@ import android.companion.AssociationRequest;
*/
interface ICompanionDeviceManager {
void associate(in AssociationRequest request,
- in IOnAssociateCallback callback,
- in String callingPackage); //TODO int userId?
+ in IFindDeviceCallback callback,
+ in String callingPackage);
//TODO add these
// boolean haveNotificationAccess(String packageName);
diff --git a/core/java/android/companion/IOnAssociateCallback.aidl b/core/java/android/companion/IFindDeviceCallback.aidl
index 4867eadd2577..919e15198efa 100644
--- a/core/java/android/companion/IOnAssociateCallback.aidl
+++ b/core/java/android/companion/IFindDeviceCallback.aidl
@@ -19,7 +19,7 @@ package android.companion;
import android.app.PendingIntent;
/** @hide */
-interface IOnAssociateCallback {
+interface IFindDeviceCallback {
void onSuccess(in PendingIntent launcher);
void onFailure(in CharSequence reason);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cd02fbbedb7e..97fbfa5a55b6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1813,6 +1813,22 @@
android:description="@string/permdesc_systemAlertWindow"
android:protectionLevel="signature|preinstalled|appop|pre23|development" />
+ <!-- Allows an app to run in the background.
+ <p>Protection level: signature
+ -->
+ <permission android:name="android.permission.RUN_IN_BACKGROUND"
+ android:label="@string/permlab_runInBackground"
+ android:description="@string/permdesc_runInBackground"
+ android:protectionLevel="signature" />
+
+ <!-- Allows an app to use data in the background.
+ <p>Protection level: signature
+ -->
+ <permission android:name="android.permission.USE_DATA_IN_BACKGROUND"
+ android:label="@string/permlab_useDataInBackground"
+ android:description="@string/permdesc_useDataInBackground"
+ android:protectionLevel="signature" />
+
<!-- ================================== -->
<!-- Permissions affecting the system wallpaper -->
<!-- ================================== -->
@@ -2996,7 +3012,7 @@
any metadata and intents attached.
@hide -->
<permission android:name="android.permission.ACCESS_NOTIFICATIONS"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature|privileged|appop" />
<!-- Marker permission for applications that wish to access notification policy.
<p>Protection level: normal
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 23098668c082..8faa76cda808 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -816,6 +816,16 @@
<string name="permdesc_systemAlertWindow">This app can appear on top of other apps or other parts of the screen. This may interfere with normal app usage and change the way that other apps appear.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_runInBackground">run in the background</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_runInBackground">This app can run in the background. This may drain battery faster.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_useDataInBackground">use data in the background</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_useDataInBackground">This app can use data in the background. This may increase data usage.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_persistentActivity">make app always run</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_persistentActivity" product="tablet">Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the tablet.</string>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index 8a970da474e6..25127efad502 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -33,7 +33,6 @@ import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import android.widget.Toast;
public class DeviceChooserActivity extends Activity {
@@ -129,12 +128,9 @@ public class DeviceChooserActivity extends Activity {
}
protected void onPairTapped(BluetoothDevice selectedDevice) {
+ getService().onDeviceSelected();
setResult(RESULT_OK,
new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice));
finish();
}
-
- private void toast(String msg) {
- Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
- }
} \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index ccbee2ae196e..11c722d7676c 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -32,16 +32,15 @@ import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.companion.AssociationRequest;
-import android.companion.BluetoothDeviceFilterUtils;
import android.companion.BluetoothLEDeviceFilter;
-import android.companion.ICompanionDeviceManagerService;
-import android.companion.IOnAssociateCallback;
+import android.companion.ICompanionDeviceDiscoveryService;
+import android.companion.ICompanionDeviceDiscoveryServiceCallback;
+import android.companion.IFindDeviceCallback;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
-import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.os.RemoteException;
@@ -70,21 +69,25 @@ public class DeviceDiscoveryService extends Service {
List<BluetoothDevice> mDevicesFound;
BluetoothDevice mSelectedDevice;
DevicesAdapter mDevicesAdapter;
- IOnAssociateCallback mCallback;
+ IFindDeviceCallback mFindCallback;
+ ICompanionDeviceDiscoveryServiceCallback mServiceCallback;
String mCallingPackage;
- private final ICompanionDeviceManagerService mBinder =
- new ICompanionDeviceManagerService.Stub() {
+ private final ICompanionDeviceDiscoveryService mBinder =
+ new ICompanionDeviceDiscoveryService.Stub() {
@Override
public void startDiscovery(AssociationRequest request,
- IOnAssociateCallback callback,
- String callingPackage) throws RemoteException {
+ String callingPackage,
+ IFindDeviceCallback findCallback,
+ ICompanionDeviceDiscoveryServiceCallback serviceCallback) {
if (DEBUG) {
Log.i(LOG_TAG,
- "startDiscovery() called with: filter = [" + request + "], callback = ["
- + callback + "]");
+ "startDiscovery() called with: filter = [" + request
+ + "], findCallback = [" + findCallback + "]"
+ + "], serviceCallback = [" + serviceCallback + "]");
}
- mCallback = callback;
+ mFindCallback = findCallback;
+ mServiceCallback = serviceCallback;
mCallingPackage = callingPackage;
DeviceDiscoveryService.this.startDiscovery(request);
}
@@ -171,6 +174,14 @@ public class DeviceDiscoveryService extends Service {
return super.onUnbind(intent);
}
+ public void onDeviceSelected() {
+ try {
+ mServiceCallback.onDeviceSelected(mCallingPackage, getUserId());
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Error reporting selected device");
+ }
+ }
+
private void stopScan() {
if (DEBUG) Log.i(LOG_TAG, "stopScan() called");
mBluetoothAdapter.cancelDiscovery();
@@ -205,7 +216,7 @@ public class DeviceDiscoveryService extends Service {
//TODO also, on timeout -> call onFailure
private void onReadyToShowUI() {
try {
- mCallback.onSuccess(PendingIntent.getActivity(
+ mFindCallback.onSuccess(PendingIntent.getActivity(
this, 0,
new Intent(this, DeviceChooserActivity.class),
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 9da94b3007ee..06b6f66203aa 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -20,6 +20,7 @@ import android.Manifest;
import android.annotation.NonNull;
import android.app.DownloadManager;
import android.app.admin.DevicePolicyManager;
+import android.companion.CompanionDeviceManager;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -673,6 +674,16 @@ final class DefaultPermissionGrantPolicy {
&& doesPackageSupportRuntimePermissions(storageManagerPckg)) {
grantRuntimePermissionsLPw(storageManagerPckg, STORAGE_PERMISSIONS, true, userId);
}
+
+ // Companion devices
+ PackageParser.Package companionDeviceDiscoveryPackage = getSystemPackageLPr(
+ CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME);
+ if (companionDeviceDiscoveryPackage != null
+ && doesPackageSupportRuntimePermissions(companionDeviceDiscoveryPackage)) {
+ grantRuntimePermissionsLPw(companionDeviceDiscoveryPackage,
+ LOCATION_PERMISSIONS, true, userId);
+ }
+
mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
}
}
diff --git a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
index 9824c1d12613..9ac8295e816d 100644
--- a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
+++ b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
@@ -19,20 +19,28 @@ package com.android.server.print;
import static com.android.internal.util.Preconditions.checkNotNull;
-import android.app.PendingIntent;
+import android.Manifest;
import android.companion.AssociationRequest;
+import android.companion.CompanionDeviceManager;
+import android.companion.ICompanionDeviceDiscoveryService;
+import android.companion.ICompanionDeviceDiscoveryServiceCallback;
import android.companion.ICompanionDeviceManager;
-import android.companion.ICompanionDeviceManagerService;
-import android.companion.IOnAssociateCallback;
+import android.companion.IFindDeviceCallback;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.NetworkPolicyManager;
import android.os.Binder;
import android.os.IBinder;
+import android.os.IDeviceIdleController;
import android.os.RemoteException;
-import android.util.Log;
+import android.os.ServiceManager;
+import android.util.Slog;
+import com.android.internal.util.ArrayUtils;
import com.android.server.SystemService;
//TODO move to own package!
@@ -40,7 +48,8 @@ import com.android.server.SystemService;
public class CompanionDeviceManagerService extends SystemService {
private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
- "com.android.companiondevicemanager", ".DeviceDiscoveryService");
+ CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
+ ".DeviceDiscoveryService");
private static final boolean DEBUG = false;
private static final String LOG_TAG = "CompanionDeviceManagerService";
@@ -58,14 +67,13 @@ public class CompanionDeviceManagerService extends SystemService {
}
class CompanionDeviceManagerImpl extends ICompanionDeviceManager.Stub {
-
@Override
public void associate(
AssociationRequest request,
- IOnAssociateCallback callback,
- String callingPackage) throws RemoteException {
+ IFindDeviceCallback callback,
+ String callingPackage) {
if (DEBUG) {
- Log.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback
+ Slog.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback
+ ", callingPackage = " + callingPackage + ")");
}
checkNotNull(request);
@@ -85,23 +93,24 @@ public class CompanionDeviceManagerService extends SystemService {
private ServiceConnection getServiceConnection(
final AssociationRequest<?> request,
- final IOnAssociateCallback callback,
+ final IFindDeviceCallback findDeviceCallback,
final String callingPackage) {
return new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) {
- Log.i(LOG_TAG,
+ Slog.i(LOG_TAG,
"onServiceConnected(name = " + name + ", service = "
+ service + ")");
}
try {
- ICompanionDeviceManagerService.Stub
+ ICompanionDeviceDiscoveryService.Stub
.asInterface(service)
.startDiscovery(
request,
- getCallback(callingPackage, callback),
- callingPackage);
+ callingPackage,
+ findDeviceCallback,
+ getServiceCallback());
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -109,39 +118,50 @@ public class CompanionDeviceManagerService extends SystemService {
@Override
public void onServiceDisconnected(ComponentName name) {
- if (DEBUG) Log.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")");
+ if (DEBUG) Slog.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")");
}
};
}
- private IOnAssociateCallback.Stub getCallback(
- String callingPackage,
- IOnAssociateCallback propagateTo) {
- return new IOnAssociateCallback.Stub() {
-
- @Override
- public void onSuccess(PendingIntent launcher)
- throws RemoteException {
- if (DEBUG) Log.i(LOG_TAG, "onSuccess(launcher = " + launcher + ")");
- recordSpecialPriviledgesForPackage(callingPackage);
- propagateTo.onSuccess(launcher);
- }
-
+ private ICompanionDeviceDiscoveryServiceCallback.Stub getServiceCallback() {
+ return new ICompanionDeviceDiscoveryServiceCallback.Stub() {
@Override
- public void onFailure(CharSequence reason) throws RemoteException {
- if (DEBUG) Log.i(LOG_TAG, "onFailure()");
- propagateTo.onFailure(reason);
+ public void onDeviceSelected(String packageName, int userId) {
+ grantSpecialAccessPermissionsIfNeeded(packageName, userId);
}
};
}
- void recordSpecialPriviledgesForPackage(String priviledgedPackage) {
- //TODO Show dialog before recording notification access
-// final SettingStringHelper setting =
-// new SettingStringHelper(
-// getContext().getContentResolver(),
-// Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
-// Binder.getCallingUid());
-// setting.write(ColonDelimitedSet.OfStrings.add(setting.read(), priviledgedPackage));
+ private void grantSpecialAccessPermissionsIfNeeded(String packageName, int userId) {
+ final long identity = Binder.clearCallingIdentity();
+ final PackageInfo packageInfo;
+ try {
+ packageInfo = getContext().getPackageManager().getPackageInfoAsUser(
+ packageName, PackageManager.GET_PERMISSIONS, userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(LOG_TAG, "Error granting special access permissions to package:"
+ + packageName, e);
+ return;
+ }
+ try {
+ if (ArrayUtils.contains(packageInfo.requestedPermissions,
+ Manifest.permission.RUN_IN_BACKGROUND)) {
+ IDeviceIdleController idleController = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ try {
+ idleController.addPowerSaveWhitelistApp(packageName);
+ } catch (RemoteException e) {
+ /* ignore - local call */
+ }
+ }
+ if (ArrayUtils.contains(packageInfo.requestedPermissions,
+ Manifest.permission.USE_DATA_IN_BACKGROUND)) {
+ NetworkPolicyManager.from(getContext()).addUidPolicy(
+ packageInfo.applicationInfo.uid,
+ NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
}