Loading core/java/android/service/dreams/DreamOverlayService.java +93 −22 Original line number Diff line number Diff line Loading @@ -36,39 +36,101 @@ import android.view.WindowManager; public abstract class DreamOverlayService extends Service { private static final String TAG = "DreamOverlayService"; private static final boolean DEBUG = false; // The last client that started dreaming and hasn't ended private OverlayClient mCurrentClient; // An {@link IDreamOverlayClient} implementation that identifies itself when forwarding // requests to the {@link DreamOverlayService} private static class OverlayClient extends IDreamOverlayClient.Stub { private final DreamOverlayService mService; private boolean mShowComplications; private ComponentName mDreamComponent; IDreamOverlayCallback mDreamOverlayCallback; OverlayClient(DreamOverlayService service) { mService = service; } private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() { @Override public void startDream(WindowManager.LayoutParams layoutParams, IDreamOverlayCallback callback, String dreamComponent, boolean shouldShowComplications) { mDreamOverlayCallback = callback; public void startDream(WindowManager.LayoutParams params, IDreamOverlayCallback callback, String dreamComponent, boolean shouldShowComplications) throws RemoteException { mDreamComponent = ComponentName.unflattenFromString(dreamComponent); mShowComplications = shouldShowComplications; onStartDream(layoutParams); mDreamOverlayCallback = callback; mService.startDream(this, params); } @Override public void wakeUp() { mService.wakeUp(this, () -> { try { mDreamOverlayCallback.onWakeUpComplete(); } catch (RemoteException e) { Log.e(TAG, "Could not notify dream of wakeUp", e); } }); } @Override public void endDream() { mService.endDream(this); } private void onExitRequested() { try { mDreamOverlayCallback.onExitRequested(); } catch (RemoteException e) { Log.e(TAG, "Could not request exit:" + e); } } private boolean shouldShowComplications() { return mShowComplications; } private ComponentName getComponent() { return mDreamComponent; } } private void startDream(OverlayClient client, WindowManager.LayoutParams params) { endDream(mCurrentClient); mCurrentClient = client; onStartDream(params); } private void endDream(OverlayClient client) { if (client == null || client != mCurrentClient) { return; } onEndDream(); mCurrentClient = null; } private void wakeUp(OverlayClient client, Runnable callback) { if (mCurrentClient != client) { return; } onWakeUp(callback); } private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() { @Override public void wakeUp() { onWakeUp(() -> { public void getClient(IDreamOverlayClientCallback callback) { try { mDreamOverlayCallback.onWakeUpComplete(); callback.onDreamOverlayClient( new OverlayClient(DreamOverlayService.this)); } catch (RemoteException e) { Log.e(TAG, "Could not notify dream of wakeUp:" + e); Log.e(TAG, "could not send client to callback", e); } }); } }; IDreamOverlayCallback mDreamOverlayCallback; public DreamOverlayService() { } Loading Loading @@ -110,18 +172,23 @@ public abstract class DreamOverlayService extends Service { * This method is invoked to request the dream exit. */ public final void requestExit() { try { mDreamOverlayCallback.onExitRequested(); } catch (RemoteException e) { Log.e(TAG, "Could not request exit:" + e); if (mCurrentClient == null) { throw new IllegalStateException("requested exit with no dream present"); } mCurrentClient.onExitRequested(); } /** * Returns whether to show complications on the dream overlay. */ public final boolean shouldShowComplications() { return mShowComplications; if (mCurrentClient == null) { throw new IllegalStateException( "requested if should show complication when no dream active"); } return mCurrentClient.shouldShowComplications(); } /** Loading @@ -129,6 +196,10 @@ public abstract class DreamOverlayService extends Service { * @hide */ public final ComponentName getDreamComponent() { return mDreamComponent; if (mCurrentClient == null) { throw new IllegalStateException("requested dream component when no dream active"); } return mCurrentClient.getComponent(); } } core/java/android/service/dreams/DreamService.java +26 −12 Original line number Diff line number Diff line Loading @@ -248,25 +248,39 @@ public class DreamService extends Service implements Window.Callback { private OverlayConnection mOverlayConnection; private static class OverlayConnection extends PersistentServiceConnection<IDreamOverlay> { // Overlay set during onBind. private IDreamOverlay mOverlay; // Retrieved Client private IDreamOverlayClient mClient; // A list of pending requests to execute on the overlay. private final ArrayList<Consumer<IDreamOverlay>> mConsumers = new ArrayList<>(); private final ArrayList<Consumer<IDreamOverlayClient>> mConsumers = new ArrayList<>(); private final IDreamOverlayClientCallback mClientCallback = new IDreamOverlayClientCallback.Stub() { @Override public void onDreamOverlayClient(IDreamOverlayClient client) { mClient = client; for (Consumer<IDreamOverlayClient> consumer : mConsumers) { consumer.accept(mClient); } } }; private final Callback<IDreamOverlay> mCallback = new Callback<IDreamOverlay>() { @Override public void onConnected(ObservableServiceConnection<IDreamOverlay> connection, IDreamOverlay service) { mOverlay = service; for (Consumer<IDreamOverlay> consumer : mConsumers) { consumer.accept(mOverlay); try { service.getClient(mClientCallback); } catch (RemoteException e) { Log.e(TAG, "could not get DreamOverlayClient", e); } } @Override public void onDisconnected(ObservableServiceConnection<IDreamOverlay> connection, int reason) { mOverlay = null; mClient = null; } }; Loading Loading @@ -296,16 +310,16 @@ public class DreamService extends Service implements Window.Callback { super.unbind(); } public void addConsumer(Consumer<IDreamOverlay> consumer) { public void addConsumer(Consumer<IDreamOverlayClient> consumer) { execute(() -> { mConsumers.add(consumer); if (mOverlay != null) { consumer.accept(mOverlay); if (mClient != null) { consumer.accept(mClient); } }); } public void removeConsumer(Consumer<IDreamOverlay> consumer) { public void removeConsumer(Consumer<IDreamOverlayClient> consumer) { execute(() -> mConsumers.remove(consumer)); } Loading Loading @@ -1365,7 +1379,7 @@ public class DreamService extends Service implements Window.Callback { mWindow.getDecorView().addOnAttachStateChangeListener( new View.OnAttachStateChangeListener() { private Consumer<IDreamOverlay> mDreamStartOverlayConsumer; private Consumer<IDreamOverlayClient> mDreamStartOverlayConsumer; @Override public void onViewAttachedToWindow(View v) { Loading core/java/android/service/dreams/IDreamOverlay.aidl +3 −17 Original line number Diff line number Diff line Loading @@ -16,8 +16,7 @@ package android.service.dreams; import android.service.dreams.IDreamOverlayCallback; import android.view.WindowManager.LayoutParams; import android.service.dreams.IDreamOverlayClientCallback; /** * {@link IDreamOverlay} provides a way for a component to annotate a dream with additional view Loading @@ -28,20 +27,7 @@ import android.view.WindowManager.LayoutParams; */ 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. * @param dreamComponent The component name of the dream service requesting overlay. * @param shouldShowComplications Whether the dream overlay should show complications, e.g. clock * and weather. * Retrieves a client the caller can use to interact with the dream overlay. */ void startDream(in LayoutParams params, in IDreamOverlayCallback callback, in String dreamComponent, in boolean shouldShowComplications); /** Called when the dream is waking, to do any exit animations */ void wakeUp(); /** Called when the dream has ended. */ void endDream(); void getClient(in IDreamOverlayClientCallback callback); } core/java/android/service/dreams/IDreamOverlayClient.aidl 0 → 100644 +45 −0 Original line number Diff line number Diff line /** * Copyright (c) 2023, 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 IDreamOverlayClient} allows {@link DreamService} instances to act upon the dream overlay. * * @hide */ interface IDreamOverlayClient { /** * @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. * @param dreamComponent The component name of the dream service requesting overlay. * @param shouldShowComplications Whether the dream overlay should show complications, e.g. clock * and weather. */ void startDream(in LayoutParams params, in IDreamOverlayCallback callback, in String dreamComponent, in boolean shouldShowComplications); /** Called when the dream is waking, to do any exit animations */ void wakeUp(); /** Called when the dream has ended. */ void endDream(); } core/java/android/service/dreams/IDreamOverlayClientCallback.aidl 0 → 100644 +30 −0 Original line number Diff line number Diff line /** * Copyright (c) 2023, 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.IDreamOverlayClient; /** * {@link IDreamOverlayClientCallback} allows receiving a requested {@link IDreamOverlayClient}. * @hide */ interface IDreamOverlayClientCallback { /** * Called with a unique {@link IDreamOverlayClient}. */ void onDreamOverlayClient(in IDreamOverlayClient client); } Loading
core/java/android/service/dreams/DreamOverlayService.java +93 −22 Original line number Diff line number Diff line Loading @@ -36,39 +36,101 @@ import android.view.WindowManager; public abstract class DreamOverlayService extends Service { private static final String TAG = "DreamOverlayService"; private static final boolean DEBUG = false; // The last client that started dreaming and hasn't ended private OverlayClient mCurrentClient; // An {@link IDreamOverlayClient} implementation that identifies itself when forwarding // requests to the {@link DreamOverlayService} private static class OverlayClient extends IDreamOverlayClient.Stub { private final DreamOverlayService mService; private boolean mShowComplications; private ComponentName mDreamComponent; IDreamOverlayCallback mDreamOverlayCallback; OverlayClient(DreamOverlayService service) { mService = service; } private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() { @Override public void startDream(WindowManager.LayoutParams layoutParams, IDreamOverlayCallback callback, String dreamComponent, boolean shouldShowComplications) { mDreamOverlayCallback = callback; public void startDream(WindowManager.LayoutParams params, IDreamOverlayCallback callback, String dreamComponent, boolean shouldShowComplications) throws RemoteException { mDreamComponent = ComponentName.unflattenFromString(dreamComponent); mShowComplications = shouldShowComplications; onStartDream(layoutParams); mDreamOverlayCallback = callback; mService.startDream(this, params); } @Override public void wakeUp() { mService.wakeUp(this, () -> { try { mDreamOverlayCallback.onWakeUpComplete(); } catch (RemoteException e) { Log.e(TAG, "Could not notify dream of wakeUp", e); } }); } @Override public void endDream() { mService.endDream(this); } private void onExitRequested() { try { mDreamOverlayCallback.onExitRequested(); } catch (RemoteException e) { Log.e(TAG, "Could not request exit:" + e); } } private boolean shouldShowComplications() { return mShowComplications; } private ComponentName getComponent() { return mDreamComponent; } } private void startDream(OverlayClient client, WindowManager.LayoutParams params) { endDream(mCurrentClient); mCurrentClient = client; onStartDream(params); } private void endDream(OverlayClient client) { if (client == null || client != mCurrentClient) { return; } onEndDream(); mCurrentClient = null; } private void wakeUp(OverlayClient client, Runnable callback) { if (mCurrentClient != client) { return; } onWakeUp(callback); } private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() { @Override public void wakeUp() { onWakeUp(() -> { public void getClient(IDreamOverlayClientCallback callback) { try { mDreamOverlayCallback.onWakeUpComplete(); callback.onDreamOverlayClient( new OverlayClient(DreamOverlayService.this)); } catch (RemoteException e) { Log.e(TAG, "Could not notify dream of wakeUp:" + e); Log.e(TAG, "could not send client to callback", e); } }); } }; IDreamOverlayCallback mDreamOverlayCallback; public DreamOverlayService() { } Loading Loading @@ -110,18 +172,23 @@ public abstract class DreamOverlayService extends Service { * This method is invoked to request the dream exit. */ public final void requestExit() { try { mDreamOverlayCallback.onExitRequested(); } catch (RemoteException e) { Log.e(TAG, "Could not request exit:" + e); if (mCurrentClient == null) { throw new IllegalStateException("requested exit with no dream present"); } mCurrentClient.onExitRequested(); } /** * Returns whether to show complications on the dream overlay. */ public final boolean shouldShowComplications() { return mShowComplications; if (mCurrentClient == null) { throw new IllegalStateException( "requested if should show complication when no dream active"); } return mCurrentClient.shouldShowComplications(); } /** Loading @@ -129,6 +196,10 @@ public abstract class DreamOverlayService extends Service { * @hide */ public final ComponentName getDreamComponent() { return mDreamComponent; if (mCurrentClient == null) { throw new IllegalStateException("requested dream component when no dream active"); } return mCurrentClient.getComponent(); } }
core/java/android/service/dreams/DreamService.java +26 −12 Original line number Diff line number Diff line Loading @@ -248,25 +248,39 @@ public class DreamService extends Service implements Window.Callback { private OverlayConnection mOverlayConnection; private static class OverlayConnection extends PersistentServiceConnection<IDreamOverlay> { // Overlay set during onBind. private IDreamOverlay mOverlay; // Retrieved Client private IDreamOverlayClient mClient; // A list of pending requests to execute on the overlay. private final ArrayList<Consumer<IDreamOverlay>> mConsumers = new ArrayList<>(); private final ArrayList<Consumer<IDreamOverlayClient>> mConsumers = new ArrayList<>(); private final IDreamOverlayClientCallback mClientCallback = new IDreamOverlayClientCallback.Stub() { @Override public void onDreamOverlayClient(IDreamOverlayClient client) { mClient = client; for (Consumer<IDreamOverlayClient> consumer : mConsumers) { consumer.accept(mClient); } } }; private final Callback<IDreamOverlay> mCallback = new Callback<IDreamOverlay>() { @Override public void onConnected(ObservableServiceConnection<IDreamOverlay> connection, IDreamOverlay service) { mOverlay = service; for (Consumer<IDreamOverlay> consumer : mConsumers) { consumer.accept(mOverlay); try { service.getClient(mClientCallback); } catch (RemoteException e) { Log.e(TAG, "could not get DreamOverlayClient", e); } } @Override public void onDisconnected(ObservableServiceConnection<IDreamOverlay> connection, int reason) { mOverlay = null; mClient = null; } }; Loading Loading @@ -296,16 +310,16 @@ public class DreamService extends Service implements Window.Callback { super.unbind(); } public void addConsumer(Consumer<IDreamOverlay> consumer) { public void addConsumer(Consumer<IDreamOverlayClient> consumer) { execute(() -> { mConsumers.add(consumer); if (mOverlay != null) { consumer.accept(mOverlay); if (mClient != null) { consumer.accept(mClient); } }); } public void removeConsumer(Consumer<IDreamOverlay> consumer) { public void removeConsumer(Consumer<IDreamOverlayClient> consumer) { execute(() -> mConsumers.remove(consumer)); } Loading Loading @@ -1365,7 +1379,7 @@ public class DreamService extends Service implements Window.Callback { mWindow.getDecorView().addOnAttachStateChangeListener( new View.OnAttachStateChangeListener() { private Consumer<IDreamOverlay> mDreamStartOverlayConsumer; private Consumer<IDreamOverlayClient> mDreamStartOverlayConsumer; @Override public void onViewAttachedToWindow(View v) { Loading
core/java/android/service/dreams/IDreamOverlay.aidl +3 −17 Original line number Diff line number Diff line Loading @@ -16,8 +16,7 @@ package android.service.dreams; import android.service.dreams.IDreamOverlayCallback; import android.view.WindowManager.LayoutParams; import android.service.dreams.IDreamOverlayClientCallback; /** * {@link IDreamOverlay} provides a way for a component to annotate a dream with additional view Loading @@ -28,20 +27,7 @@ import android.view.WindowManager.LayoutParams; */ 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. * @param dreamComponent The component name of the dream service requesting overlay. * @param shouldShowComplications Whether the dream overlay should show complications, e.g. clock * and weather. * Retrieves a client the caller can use to interact with the dream overlay. */ void startDream(in LayoutParams params, in IDreamOverlayCallback callback, in String dreamComponent, in boolean shouldShowComplications); /** Called when the dream is waking, to do any exit animations */ void wakeUp(); /** Called when the dream has ended. */ void endDream(); void getClient(in IDreamOverlayClientCallback callback); }
core/java/android/service/dreams/IDreamOverlayClient.aidl 0 → 100644 +45 −0 Original line number Diff line number Diff line /** * Copyright (c) 2023, 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 IDreamOverlayClient} allows {@link DreamService} instances to act upon the dream overlay. * * @hide */ interface IDreamOverlayClient { /** * @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. * @param dreamComponent The component name of the dream service requesting overlay. * @param shouldShowComplications Whether the dream overlay should show complications, e.g. clock * and weather. */ void startDream(in LayoutParams params, in IDreamOverlayCallback callback, in String dreamComponent, in boolean shouldShowComplications); /** Called when the dream is waking, to do any exit animations */ void wakeUp(); /** Called when the dream has ended. */ void endDream(); }
core/java/android/service/dreams/IDreamOverlayClientCallback.aidl 0 → 100644 +30 −0 Original line number Diff line number Diff line /** * Copyright (c) 2023, 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.IDreamOverlayClient; /** * {@link IDreamOverlayClientCallback} allows receiving a requested {@link IDreamOverlayClient}. * @hide */ interface IDreamOverlayClientCallback { /** * Called with a unique {@link IDreamOverlayClient}. */ void onDreamOverlayClient(in IDreamOverlayClient client); }