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

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

Merge changes from topics "201676043", "201676597", "204605351"

* changes:
  Allow App Widget Overlays by Product Configuration.
  Add Support for App Widgets as Overlays.
  Centralized Dream Overlay State.
  SystemUI IDreamOverlay Implementation.
  Add Stub implementation for DreamOverlayService.
  Consolidate dream overlay binding logic.
  Pass Window to DreamOverlayService when attached.
  Correct launch task behind when dream is present.
parents dc6ad978 f0d376d4
Loading
Loading
Loading
Loading
+13 −1
Original line number Original line Diff line number Diff line
@@ -257,7 +257,8 @@ package android.app {


  public class DreamManager {
  public class DreamManager {
    method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isDreaming();
    method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isDreaming();
    method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void setActiveDream(@NonNull android.content.ComponentName);
    method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void setActiveDream(@Nullable android.content.ComponentName);
    method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void setDreamOverlay(@Nullable android.content.ComponentName);
    method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void startDream(@NonNull android.content.ComponentName);
    method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void startDream(@NonNull android.content.ComponentName);
    method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void stopDream();
    method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void stopDream();
  }
  }
@@ -2364,6 +2365,17 @@ package android.service.autofill.augmented {


}
}


package android.service.dreams {

  public abstract class DreamOverlayService extends android.app.Service {
    ctor public DreamOverlayService();
    method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
    method public abstract void onStartDream(@NonNull android.view.WindowManager.LayoutParams);
    method public final void requestExit();
  }

}

package android.service.notification {
package android.service.notification {


  @Deprecated public abstract class ConditionProviderService extends android.app.Service {
  @Deprecated public abstract class ConditionProviderService extends android.app.Service {
+23 −2
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app;
package android.app;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.TestApi;
@@ -91,10 +92,30 @@ public class DreamManager {
    @TestApi
    @TestApi
    @UserHandleAware
    @UserHandleAware
    @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)
    @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)
    public void setActiveDream(@NonNull ComponentName dreamComponent) {
    public void setActiveDream(@Nullable ComponentName dreamComponent) {
        ComponentName[] dreams = {dreamComponent};
        ComponentName[] dreams = {dreamComponent};

        try {
            mService.setDreamComponentsForUser(mContext.getUserId(),
                    dreamComponent != null ? dreams : null);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    /**
     * Sets the active dream on the device to be "dreamComponent".
     *
     * <p>This is only used for testing the dream service APIs.
     *
     * @hide
     */
    @TestApi
    @UserHandleAware
    @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)
    public void setDreamOverlay(@Nullable ComponentName dreamOverlayComponent) {
        try {
        try {
            mService.setDreamComponentsForUser(mContext.getUserId(), dreams);
            mService.registerDreamOverlayService(dreamOverlayComponent);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
            e.rethrowFromSystemServer();
        }
        }
+77 −0
Original line number Original line Diff line number Diff line
/*
 * 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.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.WindowManager;


/**
 * Basic implementation of for {@link IDreamOverlay} for testing.
 * @hide
 */
@TestApi
public abstract class DreamOverlayService extends Service {
    private static final String TAG = "DreamOverlayService";
    private static final boolean DEBUG = false;

    private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() {
        @Override
        public void startDream(WindowManager.LayoutParams layoutParams,
                IDreamOverlayCallback callback) {
            mDreamOverlayCallback = callback;
            onStartDream(layoutParams);
        }
    };

    IDreamOverlayCallback mDreamOverlayCallback;

    public DreamOverlayService() {
    }

    @Nullable
    @Override
    public final IBinder onBind(@NonNull Intent intent) {
        return mDreamOverlay.asBinder();
    }

    /**
     * This method is overridden by implementations to handle when the dream has started and the
     * window is ready to be interacted with.
     * @param layoutParams The {@link android.view.WindowManager.LayoutParams} associated with the
     *                     dream window.
     */
    public abstract void onStartDream(@NonNull WindowManager.LayoutParams layoutParams);

    /**
     * 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);
        }
    }
}
+37 −23
Original line number Original line Diff line number Diff line
@@ -203,7 +203,6 @@ public class DreamService extends Service implements Window.Callback {
    private boolean mCanDoze;
    private boolean mCanDoze;
    private boolean mDozing;
    private boolean mDozing;
    private boolean mWindowless;
    private boolean mWindowless;
    private boolean mOverlayServiceBound;
    private int mDozeScreenState = Display.STATE_UNKNOWN;
    private int mDozeScreenState = Display.STATE_UNKNOWN;
    private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
    private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;


@@ -220,10 +219,34 @@ public class DreamService extends Service implements Window.Callback {
        // A Queue of pending requests to execute on the overlay.
        // A Queue of pending requests to execute on the overlay.
        private ArrayDeque<Consumer<IDreamOverlay>> mRequests;
        private ArrayDeque<Consumer<IDreamOverlay>> mRequests;


        private boolean mBound;

        OverlayConnection() {
        OverlayConnection() {
            mRequests = new ArrayDeque<>();
            mRequests = new ArrayDeque<>();
        }
        }


        public void bind(Context context, @Nullable ComponentName overlayService) {
            if (overlayService == null) {
                return;
            }

            final Intent overlayIntent = new Intent();
            overlayIntent.setComponent(overlayService);

            context.bindService(overlayIntent,
                    this, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE);
            mBound = true;
        }

        public void unbind(Context context) {
            if (!mBound) {
                return;
            }

            context.unbindService(this);
            mBound = false;
        }

        public void request(Consumer<IDreamOverlay> request) {
        public void request(Consumer<IDreamOverlay> request) {
            mRequests.push(request);
            mRequests.push(request);
            evaluate();
            evaluate();
@@ -930,14 +953,8 @@ public class DreamService extends Service implements Window.Callback {
        mDreamServiceWrapper = new DreamServiceWrapper();
        mDreamServiceWrapper = new DreamServiceWrapper();


        // Connect to the overlay service if present.
        // Connect to the overlay service if present.
        final ComponentName overlayComponent =
        if (!mWindowless) {
                intent.getParcelableExtra(EXTRA_DREAM_OVERLAY_COMPONENT);
            mOverlayConnection.bind(this, 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;
        return mDreamServiceWrapper;
@@ -973,10 +990,7 @@ public class DreamService extends Service implements Window.Callback {
            return;
            return;
        }
        }


        if (!mWindowless && mOverlayServiceBound) {
        mOverlayConnection.unbind(this);
            unbindService(mOverlayConnection);
            mOverlayServiceBound = false;
        }


        try {
        try {
            // finishSelf will unbind the dream controller from the dream service. This will
            // finishSelf will unbind the dream controller from the dream service. This will
@@ -1173,6 +1187,16 @@ public class DreamService extends Service implements Window.Callback {
                    @Override
                    @Override
                    public void onViewAttachedToWindow(View v) {
                    public void onViewAttachedToWindow(View v) {
                        mDispatchAfterOnAttachedToWindow.run();
                        mDispatchAfterOnAttachedToWindow.run();

                        // Request the DreamOverlay be told to dream with dream's window parameters
                        // once the window has been attached.
                        mOverlayConnection.request(overlay -> {
                            try {
                                overlay.startDream(mWindow.getAttributes(), mOverlayCallback);
                            } catch (RemoteException e) {
                                Log.e(TAG, "could not send window attributes:" + e);
                            }
                        });
                    }
                    }


                    @Override
                    @Override
@@ -1185,16 +1209,6 @@ 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) {
    private boolean getWindowFlagValue(int flag, boolean defaultValue) {
+10 −0
Original line number Original line Diff line number Diff line
@@ -294,6 +294,11 @@


    <uses-permission android:name="android.permission.READ_PEOPLE_DATA" />
    <uses-permission android:name="android.permission.READ_PEOPLE_DATA" />


    <!-- Permission for dream overlay. -->
    <uses-permission android:name="android.permission.BIND_DREAM_SERVICE" />

    <uses-permission android:name="android.permission.BIND_APPWIDGET" />

    <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
    <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
    <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
    <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
    <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
    <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
@@ -673,6 +678,11 @@
            android:name=".keyguard.KeyguardService"
            android:name=".keyguard.KeyguardService"
            android:exported="true" />
            android:exported="true" />


        <service
            android:name=".dreams.DreamOverlayService"
            android:enabled="@bool/config_dreamOverlayServiceEnabled"
            android:exported="true" />

        <activity android:name=".keyguard.WorkLockActivity"
        <activity android:name=".keyguard.WorkLockActivity"
                  android:label="@string/accessibility_desc_work_lock"
                  android:label="@string/accessibility_desc_work_lock"
                  android:permission="android.permission.MANAGE_USERS"
                  android:permission="android.permission.MANAGE_USERS"
Loading