Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9280496 authored by Bryce Lee's avatar Bryce Lee Committed by Android (Google) Code Review
Browse files

Merge "Interact with DreamOverlay through distinct clients." into tm-qpr-dev

parents a7d9b7f9 c7b7735c
Loading
Loading
Loading
Loading
+93 −22
Original line number Diff line number Diff line
@@ -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() {
    }

@@ -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();
    }

    /**
@@ -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();
    }
}
+26 −12
Original line number Diff line number Diff line
@@ -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;
            }
        };

@@ -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));
        }

@@ -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) {
+3 −17
Original line number Diff line number Diff line
@@ -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
@@ -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);
}
+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();
}
+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