Create DreamManager System Server TestApi

Bug: 141771803
Bug: 133216167

Test: atest DreamManagerServiceTests
Test: make checkbuild

Merged-In: I937061138bc8ccaf4475674f00331c3fe1c5a495
Change-Id: I937061138bc8ccaf4475674f00331c3fe1c5a495
(cherry picked from commit 4467c53c11)
This commit is contained in:
Galia Peycheva
2020-02-18 00:47:05 +01:00
parent e06e29bb09
commit 641e2e6361
7 changed files with 167 additions and 16 deletions

View File

@@ -412,6 +412,12 @@ package android.app {
field public static final String COLUMN_MEDIASTORE_URI = "mediastore_uri";
}
public class DreamManager {
method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void setActiveDream(@NonNull android.content.ComponentName);
method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void startDream(@NonNull android.content.ComponentName);
method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void stopDream();
}
public final class NotificationChannel implements android.os.Parcelable {
method public int getOriginalImportance();
method public boolean isBlockableSystem();
@@ -791,6 +797,7 @@ package android.content {
field public static final String BUGREPORT_SERVICE = "bugreport";
field public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "content_capture";
field public static final String DEVICE_IDLE_CONTROLLER = "deviceidle";
field public static final String DREAM_SERVICE = "dream";
field public static final String ETHERNET_SERVICE = "ethernet";
field public static final String NETWORK_STACK_SERVICE = "network_stack";
field public static final String PERMISSION_SERVICE = "permission";

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UserHandleAware;
import android.content.ComponentName;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
/**
* @hide
*/
@SystemService(Context.DREAM_SERVICE)
@TestApi
public class DreamManager {
private final IDreamManager mService;
private final Context mContext;
/**
* @hide
*/
public DreamManager(Context context) throws ServiceManager.ServiceNotFoundException {
mService = IDreamManager.Stub.asInterface(
ServiceManager.getServiceOrThrow(DreamService.DREAM_SERVICE));
mContext = context;
}
/**
* Starts dream service with name "name".
*
* <p>This is only used for testing the dream service APIs.
*
* @hide
*/
@TestApi
@UserHandleAware
@RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)
public void startDream(@NonNull ComponentName name) {
try {
mService.testDream(mContext.getUserId(), name);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/**
* Stops the dream service on the device if one is started.
*
* <p> This is only used for testing the dream service APIs.
*
* @hide
*/
@TestApi
@RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)
public void stopDream() {
try {
mService.awaken();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/**
* Sets the active dream on the device to be "dreamComponent".
*
* <p>This is only used for testing the dream service APIs.
*
* @hide
*/
@TestApi
@UserHandleAware
@RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)
public void setActiveDream(@NonNull ComponentName dreamComponent) {
ComponentName[] dreams = {dreamComponent};
try {
mService.setDreamComponentsForUser(mContext.getUserId(), dreams);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
}

View File

@@ -1334,6 +1334,13 @@ public final class SystemServiceRegistry {
IBinder b = ServiceManager.getServiceOrThrow(Context.APP_INTEGRITY_SERVICE);
return new AppIntegrityManager(IAppIntegrityManager.Stub.asInterface(b));
}});
registerService(Context.DREAM_SERVICE, DreamManager.class,
new CachedServiceFetcher<DreamManager>() {
@Override
public DreamManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
return new DreamManager(ctx);
}});
sInitializing = true;
try {

View File

@@ -5156,6 +5156,17 @@ public abstract class Context {
*/
public static final String LIGHTS_SERVICE = "lights";
/**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.app.DreamManager} for controlling Dream states.
*
* @see #getSystemService(String)
* @hide
*/
@TestApi
public static final String DREAM_SERVICE = "dream";
/**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.

View File

@@ -31,12 +31,14 @@ interface IDreamManager {
void setDreamComponents(in ComponentName[] componentNames);
@UnsupportedAppUsage
ComponentName[] getDreamComponents();
ComponentName getDefaultDreamComponent();
void testDream(in ComponentName componentName);
ComponentName getDefaultDreamComponentForUser(int userId);
void testDream(int userId, in ComponentName componentName);
@UnsupportedAppUsage
boolean isDreaming();
void finishSelf(in IBinder token, boolean immediate);
void startDozing(in IBinder token, int screenState, int screenBrightness);
void stopDozing(in IBinder token);
void forceAmbientDisplayEnabled(boolean enabled);
ComponentName[] getDreamComponentsForUser(int userId);
void setDreamComponentsForUser(int userId, in ComponentName[] componentNames);
}

View File

@@ -136,7 +136,7 @@ public class DreamBackend {
if (mDreamManager == null)
return null;
try {
return mDreamManager.getDefaultDreamComponent();
return mDreamManager.getDefaultDreamComponentForUser(mContext.getUserId());
} catch (RemoteException e) {
Log.w(TAG, "Failed to get default dream", e);
return null;
@@ -269,7 +269,7 @@ public class DreamBackend {
if (mDreamManager == null || dreamInfo == null || dreamInfo.componentName == null)
return;
try {
mDreamManager.testDream(dreamInfo.componentName);
mDreamManager.testDream(mContext.getUserId(), dreamInfo.componentName);
} catch (RemoteException e) {
Log.w(TAG, "Failed to preview " + dreamInfo, e);
}

View File

@@ -505,12 +505,18 @@ public final class DreamManagerService extends SystemService {
@Override // Binder call
public ComponentName[] getDreamComponents() {
checkPermission(android.Manifest.permission.READ_DREAM_STATE);
return getDreamComponentsForUser(UserHandle.getCallingUserId());
}
@Override // Binder call
public ComponentName[] getDreamComponentsForUser(int userId) {
checkPermission(android.Manifest.permission.READ_DREAM_STATE);
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, true, "getDreamComponents", null);
final int userId = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
return getDreamComponentsForUser(userId);
return DreamManagerService.this.getDreamComponentsForUser(userId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -530,13 +536,28 @@ public final class DreamManagerService extends SystemService {
}
@Override // Binder call
public ComponentName getDefaultDreamComponent() {
checkPermission(android.Manifest.permission.READ_DREAM_STATE);
public void setDreamComponentsForUser(int userId, ComponentName[] componentNames) {
checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, true, "setDreamComponents", null);
final int userId = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
return getDefaultDreamComponentForUser(userId);
DreamManagerService.this.setDreamComponentsForUser(userId, componentNames);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Override // Binder call
public ComponentName getDefaultDreamComponentForUser(int userId) {
checkPermission(android.Manifest.permission.READ_DREAM_STATE);
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, true, "getDefaultDreamComponent", null);
final long ident = Binder.clearCallingIdentity();
try {
return DreamManagerService.this.getDefaultDreamComponentForUser(userId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -567,24 +588,25 @@ public final class DreamManagerService extends SystemService {
}
@Override // Binder call
public void testDream(ComponentName dream) {
public void testDream(int userId, ComponentName dream) {
if (dream == null) {
throw new IllegalArgumentException("dream must not be null");
}
checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, true, "testDream", null);
final int callingUserId = UserHandle.getCallingUserId();
final int currentUserId = ActivityManager.getCurrentUser();
if (callingUserId != currentUserId) {
if (userId != currentUserId) {
// This check is inherently prone to races but at least it's something.
Slog.w(TAG, "Aborted attempt to start a test dream while a different "
+ " user is active: callingUserId=" + callingUserId
+ " user is active: userId=" + userId
+ ", currentUserId=" + currentUserId);
return;
}
final long ident = Binder.clearCallingIdentity();
try {
testDreamInternal(dream, callingUserId);
testDreamInternal(dream, userId);
} finally {
Binder.restoreCallingIdentity(ident);
}