Add a BIND_DREAM_SERVICE signature-level permission.
Starting in api 21, will be required to bind to a declared dream or doze service. Also added to aapt dump badging output. Bug:15862654 Change-Id: Ifa0a594eeecf21e6146176c7810a847e1d08fe3b
This commit is contained in:
@@ -21,6 +21,7 @@ package android {
|
||||
field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
|
||||
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
|
||||
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
|
||||
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
|
||||
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
|
||||
field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
|
||||
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
|
||||
|
||||
@@ -124,6 +124,19 @@ import com.android.internal.util.DumpUtils.Dump;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>When targeting api level 21 and above, you must declare the service in your manifest file
|
||||
* with the {@link android.Manifest.permission#BIND_DREAM_SERVICE} permission. For example:</p>
|
||||
* <pre>
|
||||
* <service
|
||||
* android:name=".MyDream"
|
||||
* android:exported="true"
|
||||
* android:icon="@drawable/my_icon"
|
||||
* android:label="@string/my_dream_label"
|
||||
* android:permission="android.permission.BIND_DREAM_SERVICE" >
|
||||
* ...
|
||||
* </service>
|
||||
* </pre>
|
||||
*/
|
||||
public class DreamService extends Service implements Window.Callback {
|
||||
private final String TAG = DreamService.class.getSimpleName() + "[" + getClass().getSimpleName() + "]";
|
||||
|
||||
@@ -2719,6 +2719,13 @@
|
||||
android:description="@string/permdesc_bindConditionProviderService"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- Must be required by an {@link android.service.dreams.DreamService},
|
||||
to ensure that only the system can bind to it. -->
|
||||
<permission android:name="android.permission.BIND_DREAM_SERVICE"
|
||||
android:label="@string/permlab_bindDreamService"
|
||||
android:description="@string/permdesc_bindDreamService"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- @SystemApi Allows an application to call into a carrier setup flow. It is up to the
|
||||
carrier setup application to enforce that this permission is required
|
||||
@hide This is not a third-party API (intended for OEMs and system apps). -->
|
||||
|
||||
@@ -2121,6 +2121,11 @@
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permdesc_bindConditionProviderService">Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps.</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_bindDreamService">bind to a dream service</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_bindDreamService">Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps.</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_invokeCarrierSetup">invoke the carrier-provided configuration app</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
|
||||
@@ -267,6 +267,7 @@
|
||||
android:name=".DessertCaseDream"
|
||||
android:exported="true"
|
||||
android:label="@string/dessert_case"
|
||||
android:permission="android.permission.BIND_DREAM_SERVICE"
|
||||
android:enabled="false"
|
||||
android:process=":sweetsweetdesserts"
|
||||
>
|
||||
@@ -305,6 +306,7 @@
|
||||
<!-- I dream of notifications -->
|
||||
<service
|
||||
android:name=".doze.DozeService"
|
||||
android:exported="true" />
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_DREAM_SERVICE" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.dreams;
|
||||
|
||||
import static android.Manifest.permission.BIND_DREAM_SERVICE;
|
||||
|
||||
import com.android.internal.util.DumpUtils;
|
||||
import com.android.server.FgThread;
|
||||
import com.android.server.SystemService;
|
||||
@@ -29,6 +31,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
@@ -193,7 +196,7 @@ public final class DreamManagerService extends SystemService {
|
||||
|
||||
private void startDreamInternal(boolean doze) {
|
||||
final int userId = ActivityManager.getCurrentUser();
|
||||
final ComponentName dream = doze ? getDozeComponent() : chooseDreamForUser(userId);
|
||||
final ComponentName dream = chooseDreamForUser(doze, userId);
|
||||
if (dream != null) {
|
||||
synchronized (mLock) {
|
||||
startDreamLocked(dream, false /*isTest*/, doze, userId);
|
||||
@@ -245,11 +248,31 @@ public final class DreamManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private ComponentName chooseDreamForUser(int userId) {
|
||||
private ComponentName chooseDreamForUser(boolean doze, int userId) {
|
||||
if (doze) {
|
||||
ComponentName dozeComponent = getDozeComponent();
|
||||
return validateDream(dozeComponent) ? dozeComponent : null;
|
||||
}
|
||||
ComponentName[] dreams = getDreamComponentsForUser(userId);
|
||||
return dreams != null && dreams.length != 0 ? dreams[0] : null;
|
||||
}
|
||||
|
||||
private boolean validateDream(ComponentName component) {
|
||||
if (component == null) return false;
|
||||
final ServiceInfo serviceInfo = getServiceInfo(component);
|
||||
if (serviceInfo == null) {
|
||||
Slog.w(TAG, "Dream " + component + " does not exist");
|
||||
return false;
|
||||
} else if (serviceInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.L
|
||||
&& !BIND_DREAM_SERVICE.equals(serviceInfo.permission)) {
|
||||
Slog.w(TAG, "Dream " + component
|
||||
+ " is not available because its manifest is missing the " + BIND_DREAM_SERVICE
|
||||
+ " permission on the dream service declaration.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ComponentName[] getDreamComponentsForUser(int userId) {
|
||||
String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.SCREENSAVER_COMPONENTS,
|
||||
@@ -260,10 +283,8 @@ public final class DreamManagerService extends SystemService {
|
||||
List<ComponentName> validComponents = new ArrayList<ComponentName>();
|
||||
if (components != null) {
|
||||
for (ComponentName component : components) {
|
||||
if (serviceExists(component)) {
|
||||
if (validateDream(component)) {
|
||||
validComponents.add(component);
|
||||
} else {
|
||||
Slog.w(TAG, "Dream " + component + " does not exist");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,11 +328,11 @@ public final class DreamManagerService extends SystemService {
|
||||
return TextUtils.isEmpty(name) ? null : ComponentName.unflattenFromString(name);
|
||||
}
|
||||
|
||||
private boolean serviceExists(ComponentName name) {
|
||||
private ServiceInfo getServiceInfo(ComponentName name) {
|
||||
try {
|
||||
return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null;
|
||||
return name != null ? mContext.getPackageManager().getServiceInfo(name, 0) : null;
|
||||
} catch (NameNotFoundException e) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -819,6 +819,7 @@ int doDump(Bundle* bundle)
|
||||
bool hasCameraSecureActivity = false;
|
||||
bool hasLauncher = false;
|
||||
bool hasNotificationListenerService = false;
|
||||
bool hasDreamService = false;
|
||||
|
||||
bool actMainActivity = false;
|
||||
bool actWidgetReceivers = false;
|
||||
@@ -831,6 +832,7 @@ int doDump(Bundle* bundle)
|
||||
bool actOffHostApduService = false;
|
||||
bool actDocumentsProvider = false;
|
||||
bool actNotificationListenerService = false;
|
||||
bool actDreamService = false;
|
||||
bool actCamera = false;
|
||||
bool actCameraSecure = false;
|
||||
bool catLauncher = false;
|
||||
@@ -846,6 +848,7 @@ int doDump(Bundle* bundle)
|
||||
bool hasBindNfcServicePermission = false;
|
||||
bool hasRequiredSafAttributes = false;
|
||||
bool hasBindNotificationListenerServicePermission = false;
|
||||
bool hasBindDreamServicePermission = false;
|
||||
|
||||
// These two implement the implicit permissions that are granted
|
||||
// to pre-1.6 applications.
|
||||
@@ -1007,6 +1010,7 @@ int doDump(Bundle* bundle)
|
||||
hasPrintService |= (actPrintService && hasBindPrintServicePermission);
|
||||
hasNotificationListenerService |= actNotificationListenerService &&
|
||||
hasBindNotificationListenerServicePermission;
|
||||
hasDreamService |= actDreamService && hasBindDreamServicePermission;
|
||||
hasOtherServices |= (!actImeService && !actWallpaperService &&
|
||||
!actAccessibilityService && !actPrintService &&
|
||||
!actHostApduService && !actOffHostApduService &&
|
||||
@@ -1389,6 +1393,7 @@ int doDump(Bundle* bundle)
|
||||
hasBindNfcServicePermission = false;
|
||||
hasRequiredSafAttributes = false;
|
||||
hasBindNotificationListenerServicePermission = false;
|
||||
hasBindDreamServicePermission = false;
|
||||
if (withinApplication) {
|
||||
if(tag == "activity") {
|
||||
withinActivity = true;
|
||||
@@ -1486,6 +1491,8 @@ int doDump(Bundle* bundle)
|
||||
hasBindNfcServicePermission = true;
|
||||
} else if (permission == "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE") {
|
||||
hasBindNotificationListenerServicePermission = true;
|
||||
} else if (permission == "android.permission.BIND_DREAM_SERVICE") {
|
||||
hasBindDreamServicePermission = true;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "ERROR getting 'android:permission' attribute for"
|
||||
@@ -1569,6 +1576,7 @@ int doDump(Bundle* bundle)
|
||||
actOffHostApduService = false;
|
||||
actDocumentsProvider = false;
|
||||
actNotificationListenerService = false;
|
||||
actDreamService = false;
|
||||
actCamera = false;
|
||||
actCameraSecure = false;
|
||||
catLauncher = false;
|
||||
@@ -1654,6 +1662,8 @@ int doDump(Bundle* bundle)
|
||||
actOffHostApduService = true;
|
||||
} else if (action == "android.service.notification.NotificationListenerService") {
|
||||
actNotificationListenerService = true;
|
||||
} else if (action == "android.service.dreams.DreamService") {
|
||||
actDreamService = true;
|
||||
}
|
||||
} else if (withinProvider) {
|
||||
if (action == "android.content.action.DOCUMENTS_PROVIDER") {
|
||||
@@ -1889,6 +1899,9 @@ int doDump(Bundle* bundle)
|
||||
if (hasNotificationListenerService) {
|
||||
printComponentPresence("notification-listener");
|
||||
}
|
||||
if (hasDreamService) {
|
||||
printComponentPresence("dream");
|
||||
}
|
||||
if (hasCameraActivity) {
|
||||
printComponentPresence("camera");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user