Add special label to denote dream in preview mode

This allows accessibility services to denote when the dream is in
preview vs being started normally.

Fixes: 267831700
Test: enabled talkback, started dream using preview and normally
Test: atest DreamControllerTest
Change-Id: I53e27612ad177445f78868f60c07b85edbb9a642
This commit is contained in:
Lucas Silva
2023-02-09 15:07:22 -05:00
parent 18b730cbbb
commit b7a4838ff2
6 changed files with 47 additions and 12 deletions

View File

@@ -1300,9 +1300,10 @@ public class DreamService extends Service implements Window.Callback {
* Must run on mHandler.
*
* @param dreamToken Token for this dream service.
* @param started A callback that will be invoked once onDreamingStarted has completed.
* @param started A callback that will be invoked once onDreamingStarted has completed.
*/
private void attach(IBinder dreamToken, boolean canDoze, IRemoteCallback started) {
private void attach(IBinder dreamToken, boolean canDoze, boolean isPreviewMode,
IRemoteCallback started) {
if (mDreamToken != null) {
Slog.e(mTag, "attach() called when dream with token=" + mDreamToken
+ " already attached");
@@ -1350,7 +1351,8 @@ public class DreamService extends Service implements Window.Callback {
i.putExtra(DreamActivity.EXTRA_CALLBACK, new DreamActivityCallbacks(mDreamToken));
final ServiceInfo serviceInfo = fetchServiceInfo(this,
new ComponentName(this, getClass()));
i.putExtra(DreamActivity.EXTRA_DREAM_TITLE, fetchDreamLabel(this, serviceInfo));
i.putExtra(DreamActivity.EXTRA_DREAM_TITLE,
fetchDreamLabel(this, serviceInfo, isPreviewMode));
try {
if (!ActivityTaskManager.getService().startDreamActivity(i)) {
@@ -1466,10 +1468,18 @@ public class DreamService extends Service implements Window.Callback {
@Nullable
private static CharSequence fetchDreamLabel(Context context,
@Nullable ServiceInfo serviceInfo) {
if (serviceInfo == null) return null;
@Nullable ServiceInfo serviceInfo,
boolean isPreviewMode) {
if (serviceInfo == null) {
return null;
}
final PackageManager pm = context.getPackageManager();
return serviceInfo.loadLabel(pm);
final CharSequence dreamLabel = serviceInfo.loadLabel(pm);
if (!isPreviewMode || dreamLabel == null) {
return dreamLabel;
}
// When in preview mode, return a special label indicating the dream is in preview.
return context.getResources().getString(R.string.dream_preview_title, dreamLabel);
}
@Nullable
@@ -1525,8 +1535,9 @@ public class DreamService extends Service implements Window.Callback {
final class DreamServiceWrapper extends IDreamService.Stub {
@Override
public void attach(final IBinder dreamToken, final boolean canDoze,
IRemoteCallback started) {
mHandler.post(() -> DreamService.this.attach(dreamToken, canDoze, started));
final boolean isPreviewMode, IRemoteCallback started) {
mHandler.post(
() -> DreamService.this.attach(dreamToken, canDoze, isPreviewMode, started));
}
@Override

View File

@@ -22,7 +22,7 @@ import android.os.IRemoteCallback;
* @hide
*/
oneway interface IDreamService {
void attach(IBinder windowToken, boolean canDoze, IRemoteCallback started);
void attach(IBinder windowToken, boolean canDoze, boolean isPreviewMode, IRemoteCallback started);
void detach();
void wakeUp();
}

View File

@@ -975,6 +975,11 @@
<!-- Description for the capability of an accessibility service to take screenshot. [CHAR LIMIT=NONE] -->
<string name="capability_desc_canTakeScreenshot">Can take a screenshot of the display.</string>
<!-- Dream -->
<!-- The title to use when a dream is opened in preview mode. [CHAR LIMIT=NONE] -->
<string name="dream_preview_title">Preview, <xliff:g id="dream_name" example="Clock">%1$s</xliff:g></string>
<!-- Permissions -->
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->

View File

@@ -4281,6 +4281,8 @@
<java-symbol type="string" name="capability_desc_canTakeScreenshot" />
<java-symbol type="string" name="capability_title_canTakeScreenshot" />
<java-symbol type="string" name="dream_preview_title" />
<java-symbol type="string" name="config_servicesExtensionPackage" />
<!-- For app process exit info tracking -->

View File

@@ -270,7 +270,7 @@ final class DreamController {
try {
service.asBinder().linkToDeath(mCurrentDream, 0);
service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze,
mCurrentDream.mDreamingStartedCallback);
mCurrentDream.mIsPreviewMode, mCurrentDream.mDreamingStartedCallback);
} catch (RemoteException ex) {
Slog.e(TAG, "The dream service died unexpectedly.", ex);
stopDream(true /*immediate*/, "attach failed");

View File

@@ -99,7 +99,24 @@ public class DreamControllerTest {
mLooper.dispatchAll();
// Verify that dream service is called to attach.
verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/, any());
verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/,
eq(false) /*preview*/, any());
}
@Test
public void startDream_attachOnServiceConnectedInPreviewMode() throws RemoteException {
// Call dream controller to start dreaming.
mDreamController.startDream(mToken, mDreamName, true /*isPreview*/, false /*doze*/,
0 /*userId*/, null /*wakeLock*/, mOverlayName, "test" /*reason*/);
// Mock service connected.
final ServiceConnection serviceConnection = captureServiceConnection();
serviceConnection.onServiceConnected(mDreamName, mIBinder);
mLooper.dispatchAll();
// Verify that dream service is called to attach.
verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/,
eq(true) /*preview*/, any());
}
@Test
@@ -129,7 +146,7 @@ public class DreamControllerTest {
// Mock second dream started.
verify(newDreamService).attach(eq(newToken), eq(false) /*doze*/,
mRemoteCallbackCaptor.capture());
eq(false) /*preview*/, mRemoteCallbackCaptor.capture());
mRemoteCallbackCaptor.getValue().sendResult(null /*data*/);
mLooper.dispatchAll();