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

Commit cf8cfa3c authored by Bryce Lee's avatar Bryce Lee Committed by Automerger Merge Worker
Browse files

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

parents e98a2bfb b9280496
Loading
Loading
Loading
Loading
+93 −22
Original line number Original line Diff line number Diff line
@@ -36,39 +36,101 @@ import android.view.WindowManager;
public abstract class DreamOverlayService extends Service {
public abstract class DreamOverlayService extends Service {
    private static final String TAG = "DreamOverlayService";
    private static final String TAG = "DreamOverlayService";
    private static final boolean DEBUG = false;
    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 boolean mShowComplications;
        private ComponentName mDreamComponent;
        private ComponentName mDreamComponent;
        IDreamOverlayCallback mDreamOverlayCallback;

        OverlayClient(DreamOverlayService service) {
            mService = service;
        }


    private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() {
        @Override
        @Override
        public void startDream(WindowManager.LayoutParams layoutParams,
        public void startDream(WindowManager.LayoutParams params, IDreamOverlayCallback callback,
                IDreamOverlayCallback callback, String dreamComponent,
                String dreamComponent, boolean shouldShowComplications) throws RemoteException {
                boolean shouldShowComplications) {
            mDreamOverlayCallback = callback;
            mDreamComponent = ComponentName.unflattenFromString(dreamComponent);
            mDreamComponent = ComponentName.unflattenFromString(dreamComponent);
            mShowComplications = shouldShowComplications;
            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
        @Override
        public void endDream() {
        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();
        onEndDream();
        mCurrentClient = null;
    }

    private void wakeUp(OverlayClient client, Runnable callback) {
        if (mCurrentClient != client) {
            return;
        }
        }


        onWakeUp(callback);
    }

    private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() {
        @Override
        @Override
        public void wakeUp() {
        public void getClient(IDreamOverlayClientCallback callback) {
            onWakeUp(() -> {
            try {
            try {
                    mDreamOverlayCallback.onWakeUpComplete();
                callback.onDreamOverlayClient(
                        new OverlayClient(DreamOverlayService.this));
            } catch (RemoteException e) {
            } 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() {
    public DreamOverlayService() {
    }
    }


@@ -110,18 +172,23 @@ public abstract class DreamOverlayService extends Service {
     * This method is invoked to request the dream exit.
     * This method is invoked to request the dream exit.
     */
     */
    public final void requestExit() {
    public final void requestExit() {
        try {
        if (mCurrentClient == null) {
            mDreamOverlayCallback.onExitRequested();
            throw new IllegalStateException("requested exit with no dream present");
        } catch (RemoteException e) {
            Log.e(TAG, "Could not request exit:" + e);
        }
        }

        mCurrentClient.onExitRequested();
    }
    }


    /**
    /**
     * Returns whether to show complications on the dream overlay.
     * Returns whether to show complications on the dream overlay.
     */
     */
    public final boolean shouldShowComplications() {
    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
     * @hide
     */
     */
    public final ComponentName getDreamComponent() {
    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 Original line Diff line number Diff line
@@ -248,25 +248,39 @@ public class DreamService extends Service implements Window.Callback {
    private OverlayConnection mOverlayConnection;
    private OverlayConnection mOverlayConnection;


    private static class OverlayConnection extends PersistentServiceConnection<IDreamOverlay> {
    private static class OverlayConnection extends PersistentServiceConnection<IDreamOverlay> {
        // Overlay set during onBind.
        // Retrieved Client
        private IDreamOverlay mOverlay;
        private IDreamOverlayClient mClient;

        // A list of pending requests to execute on the overlay.
        // 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>() {
        private final Callback<IDreamOverlay> mCallback = new Callback<IDreamOverlay>() {
            @Override
            @Override
            public void onConnected(ObservableServiceConnection<IDreamOverlay> connection,
            public void onConnected(ObservableServiceConnection<IDreamOverlay> connection,
                    IDreamOverlay service) {
                    IDreamOverlay service) {
                mOverlay = service;
                try {
                for (Consumer<IDreamOverlay> consumer : mConsumers) {
                    service.getClient(mClientCallback);
                    consumer.accept(mOverlay);
                } catch (RemoteException e) {
                    Log.e(TAG, "could not get DreamOverlayClient", e);
                }
                }
            }
            }


            @Override
            @Override
            public void onDisconnected(ObservableServiceConnection<IDreamOverlay> connection,
            public void onDisconnected(ObservableServiceConnection<IDreamOverlay> connection,
                    int reason) {
                    int reason) {
                mOverlay = null;
                mClient = null;
            }
            }
        };
        };


@@ -296,16 +310,16 @@ public class DreamService extends Service implements Window.Callback {
            super.unbind();
            super.unbind();
        }
        }


        public void addConsumer(Consumer<IDreamOverlay> consumer) {
        public void addConsumer(Consumer<IDreamOverlayClient> consumer) {
            execute(() -> {
            execute(() -> {
                mConsumers.add(consumer);
                mConsumers.add(consumer);
                if (mOverlay != null) {
                if (mClient != null) {
                    consumer.accept(mOverlay);
                    consumer.accept(mClient);
                }
                }
            });
            });
        }
        }


        public void removeConsumer(Consumer<IDreamOverlay> consumer) {
        public void removeConsumer(Consumer<IDreamOverlayClient> consumer) {
            execute(() -> mConsumers.remove(consumer));
            execute(() -> mConsumers.remove(consumer));
        }
        }


@@ -1365,7 +1379,7 @@ public class DreamService extends Service implements Window.Callback {


        mWindow.getDecorView().addOnAttachStateChangeListener(
        mWindow.getDecorView().addOnAttachStateChangeListener(
                new View.OnAttachStateChangeListener() {
                new View.OnAttachStateChangeListener() {
                    private Consumer<IDreamOverlay> mDreamStartOverlayConsumer;
                    private Consumer<IDreamOverlayClient> mDreamStartOverlayConsumer;


                    @Override
                    @Override
                    public void onViewAttachedToWindow(View v) {
                    public void onViewAttachedToWindow(View v) {
+3 −17
Original line number Original line Diff line number Diff line
@@ -16,8 +16,7 @@


package android.service.dreams;
package android.service.dreams;


import android.service.dreams.IDreamOverlayCallback;
import android.service.dreams.IDreamOverlayClientCallback;
import android.view.WindowManager.LayoutParams;


/**
/**
* {@link IDreamOverlay} provides a way for a component to annotate a dream with additional view
* {@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 {
interface IDreamOverlay {
    /**
    /**
    * @param params The {@link LayoutParams} for the associated DreamWindow, including the window
    * Retrieves a client the caller can use to interact with the dream overlay.
                    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,
    void getClient(in IDreamOverlayClientCallback 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();
}
}
+45 −0
Original line number Original line 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 Original line 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