summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorBryce Lee <brycelee@google.com>2021-10-27 23:02:53 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-10-27 23:02:53 +0000
commit9043bddf1b8aafdcba2703bf7b3d0d872504bbeb (patch)
treef89cf9cb4f048a656176bb85653049b7d0fd5233 /core/java/android
parent8c0a9894756a6f2d73c2b4f42a41becd7538722c (diff)
parent87a5024ef5ed68f36b2c6618b13fa4512e06c47c (diff)
Merge "IDreamOverlay Introduction."
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/service/dreams/DreamService.java94
-rw-r--r--core/java/android/service/dreams/IDreamManager.aidl1
-rw-r--r--core/java/android/service/dreams/IDreamOverlay.aidl37
-rw-r--r--core/java/android/service/dreams/IDreamOverlayCallback.aidl31
4 files changed, 163 insertions, 0 deletions
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 98196489a2ed..096595f30b05 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -26,7 +26,10 @@ import android.app.ActivityTaskManager;
import android.app.AlarmManager;
import android.app.Service;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@@ -58,6 +61,8 @@ import com.android.internal.util.DumpUtils.Dump;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayDeque;
+import java.util.function.Consumer;
/**
* Extend this class to implement a custom dream (available to the user as a "Daydream").
@@ -170,6 +175,13 @@ public class DreamService extends Service implements Window.Callback {
"android.service.dreams.DreamService";
/**
+ * The name of the extra where the dream overlay component is stored.
+ * @hide
+ */
+ public static final String EXTRA_DREAM_OVERLAY_COMPONENT =
+ "android.service.dream.DreamService.dream_overlay_component";
+
+ /**
* Name under which a Dream publishes information about itself.
* This meta-data must reference an XML resource containing
* a <code>&lt;{@link android.R.styleable#Dream dream}&gt;</code>
@@ -191,6 +203,7 @@ public class DreamService extends Service implements Window.Callback {
private boolean mCanDoze;
private boolean mDozing;
private boolean mWindowless;
+ private boolean mOverlayServiceBound;
private int mDozeScreenState = Display.STATE_UNKNOWN;
private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
@@ -199,8 +212,62 @@ public class DreamService extends Service implements Window.Callback {
private DreamServiceWrapper mDreamServiceWrapper;
private Runnable mDispatchAfterOnAttachedToWindow;
+ private OverlayConnection mOverlayConnection;
+
+ private static class OverlayConnection implements ServiceConnection {
+ // Overlay set during onBind.
+ private IDreamOverlay mOverlay;
+ // A Queue of pending requests to execute on the overlay.
+ private ArrayDeque<Consumer<IDreamOverlay>> mRequests;
+
+ OverlayConnection() {
+ mRequests = new ArrayDeque<>();
+ }
+
+ public void request(Consumer<IDreamOverlay> request) {
+ mRequests.push(request);
+ evaluate();
+ }
+
+ private void evaluate() {
+ if (mOverlay == null) {
+ return;
+ }
+
+ // Any new requests that arrive during this loop will be processed synchronously after
+ // the loop exits.
+ while (!mRequests.isEmpty()) {
+ final Consumer<IDreamOverlay> request = mRequests.pop();
+ request.accept(mOverlay);
+ }
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ // Store Overlay and execute pending requests.
+ mOverlay = IDreamOverlay.Stub.asInterface(service);
+ evaluate();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ // Clear Overlay binder to prevent further request processing.
+ mOverlay = null;
+ }
+ }
+
+ private IDreamOverlayCallback mOverlayCallback = new IDreamOverlayCallback.Stub() {
+ @Override
+ public void onExitRequested() {
+ // Simply finish dream when exit is requested.
+ finish();
+ }
+ };
+
+
public DreamService() {
mDreamManager = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
+ mOverlayConnection = new OverlayConnection();
}
/**
@@ -861,6 +928,18 @@ public class DreamService extends Service implements Window.Callback {
public final IBinder onBind(Intent intent) {
if (mDebug) Slog.v(TAG, "onBind() intent = " + intent);
mDreamServiceWrapper = new DreamServiceWrapper();
+
+ // Connect to the overlay service if present.
+ final ComponentName overlayComponent =
+ intent.getParcelableExtra(EXTRA_DREAM_OVERLAY_COMPONENT);
+ if (overlayComponent != null && !mWindowless) {
+ final Intent overlayIntent = new Intent();
+ overlayIntent.setComponent(overlayComponent);
+
+ mOverlayServiceBound = getApplicationContext().bindService(overlayIntent,
+ mOverlayConnection, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE);
+ }
+
return mDreamServiceWrapper;
}
@@ -894,6 +973,11 @@ public class DreamService extends Service implements Window.Callback {
return;
}
+ if (!mWindowless && mOverlayServiceBound) {
+ unbindService(mOverlayConnection);
+ mOverlayServiceBound = false;
+ }
+
try {
// finishSelf will unbind the dream controller from the dream service. This will
// trigger DreamService.this.onDestroy and DreamService.this will die.
@@ -1101,6 +1185,16 @@ public class DreamService extends Service implements Window.Callback {
}
}
});
+
+ // Request the DreamOverlay be told to dream with dream's window parameters once the service
+ // has connected.
+ mOverlayConnection.request(overlay -> {
+ try {
+ overlay.startDream(mWindow.getAttributes(), mOverlayCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "could not send window attributes:" + e);
+ }
+ });
}
private boolean getWindowFlagValue(int flag, boolean defaultValue) {
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index 0ce9cfa7a0bf..3e0deeb556e9 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -41,4 +41,5 @@ interface IDreamManager {
void forceAmbientDisplayEnabled(boolean enabled);
ComponentName[] getDreamComponentsForUser(int userId);
void setDreamComponentsForUser(int userId, in ComponentName[] componentNames);
+ void registerDreamOverlayService(in ComponentName componentName);
}
diff --git a/core/java/android/service/dreams/IDreamOverlay.aidl b/core/java/android/service/dreams/IDreamOverlay.aidl
new file mode 100644
index 000000000000..2b6633d93dc5
--- /dev/null
+++ b/core/java/android/service/dreams/IDreamOverlay.aidl
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2021, 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.service.dreams;
+
+import android.service.dreams.IDreamOverlayCallback;
+import android.view.WindowManager.LayoutParams;
+
+/**
+* {@link IDreamOverlay} provides a way for a component to annotate a dream with additional view
+* elements. Registered through the DreamManager, a IDreamOverlay is bound to by the dream and
+* passed the necessary window details to participate in the user interface.
+
+* @hide
+*/
+interface IDreamOverlay {
+ /**
+ * @param params The {@link LayoutParams} for the associated DreamWindow, including the window
+ token of the Dream Activity.
+ * @param callback The {@link IDreamOverlayCallback} for requesting actions such as exiting the
+ * dream.
+ */
+ void startDream(in LayoutParams params, in IDreamOverlayCallback callback);
+}
diff --git a/core/java/android/service/dreams/IDreamOverlayCallback.aidl b/core/java/android/service/dreams/IDreamOverlayCallback.aidl
new file mode 100644
index 000000000000..ec76a334d5b2
--- /dev/null
+++ b/core/java/android/service/dreams/IDreamOverlayCallback.aidl
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2021, 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.service.dreams;
+
+/**
+* {@link IDreamOverlayCallback} defines the interactions a dream overlay can have with its
+* associated dream. It is the discretion of the {@link DreamService}) to honor any inbound requests
+* from this callback.
+*
+* @hide
+*/
+interface IDreamOverlayCallback {
+ /**
+ * Invoked to request the dream exit.
+ */
+ void onExitRequested();
+} \ No newline at end of file