diff options
| author | Bryce Lee <brycelee@google.com> | 2021-10-27 23:02:53 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-10-27 23:02:53 +0000 |
| commit | 9043bddf1b8aafdcba2703bf7b3d0d872504bbeb (patch) | |
| tree | f89cf9cb4f048a656176bb85653049b7d0fd5233 /core/java/android | |
| parent | 8c0a9894756a6f2d73c2b4f42a41becd7538722c (diff) | |
| parent | 87a5024ef5ed68f36b2c6618b13fa4512e06c47c (diff) | |
Merge "IDreamOverlay Introduction."
Diffstat (limited to 'core/java/android')
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><{@link android.R.styleable#Dream dream}></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 |
