Merge "Auto-grant background execution and data access"
This commit is contained in:
committed by
Android (Google) Code Review
commit
55ab689fac
@@ -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 \
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -46,6 +44,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));
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -815,6 +815,16 @@
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<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. -->
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
private ICompanionDeviceDiscoveryServiceCallback.Stub getServiceCallback() {
|
||||
return new ICompanionDeviceDiscoveryServiceCallback.Stub() {
|
||||
@Override
|
||||
public void onSuccess(PendingIntent launcher)
|
||||
throws RemoteException {
|
||||
if (DEBUG) Log.i(LOG_TAG, "onSuccess(launcher = " + launcher + ")");
|
||||
recordSpecialPriviledgesForPackage(callingPackage);
|
||||
propagateTo.onSuccess(launcher);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user