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

Commit 66de134b authored by William Leshner's avatar William Leshner Committed by Android (Google) Code Review
Browse files

Merge "Add a status bar to dream overlay."

parents 9e699657 cebb50f6
Loading
Loading
Loading
Loading
+24 −0
Original line number 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.
  -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M18.575,15.2L7.55,4.175q1.1,-0.325 2.212,-0.462 1.113,-0.138 2.238,-0.138 3.45,0 6.55,1.45Q21.65,6.475 24,9zM20.225,23.575l-4.75,-4.75 -3.475,4.1L0,9q0.675,-0.725 1.438,-1.4 0.762,-0.675 1.612,-1.225l-2.625,-2.6L2.1,2.1l19.8,19.8z"/>
</vector>
 No newline at end of file
+61 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ 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.
-->
<com.android.systemui.dreams.DreamOverlayContainerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/dream_overlay_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/dream_overlay_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <com.android.systemui.dreams.DreamOverlayStatusBarView
        android:id="@+id/dream_overlay_status_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dream_overlay_status_bar_height"
        android:layout_marginEnd="@dimen/dream_overlay_status_bar_margin"
        android:layout_marginStart="@dimen/dream_overlay_status_bar_margin"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/dream_overlay_system_status"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            app:layout_constraintEnd_toEndOf="parent">

            <com.android.systemui.statusbar.AlphaOptimizedImageView
                android:id="@+id/dream_overlay_wifi_status"
                android:layout_width="@dimen/status_bar_wifi_signal_size"
                android:layout_height="match_parent"
                android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
                android:visibility="gone"
                app:layout_constraintEnd_toStartOf="@id/dream_overlay_battery" />

            <com.android.systemui.battery.BatteryMeterView
                android:id="@+id/dream_overlay_battery"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                app:layout_constraintEnd_toEndOf="parent" />

        </androidx.constraintlayout.widget.ConstraintLayout>
    </com.android.systemui.dreams.DreamOverlayStatusBarView>
</com.android.systemui.dreams.DreamOverlayContainerView>
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -1303,4 +1303,9 @@
    <dimen name="keyguard_unfold_translation_x">16dp</dimen>

    <dimen name="fgs_manager_min_width_minor">100%</dimen>

    <!-- Dream overlay related dimensions -->
    <dimen name="dream_overlay_status_bar_height">80dp</dimen>
    <dimen name="dream_overlay_status_bar_margin">40dp</dimen>
    <dimen name="dream_overlay_status_icon_margin">8dp</dimen>
</resources>
+44 −0
Original line number 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 com.android.systemui.dreams;

import android.content.Context;
import android.util.AttributeSet;

import androidx.constraintlayout.widget.ConstraintLayout;

/**
 * {@link DreamOverlayContainerView} contains a dream overlay and its status bar.
 */
public class DreamOverlayContainerView extends ConstraintLayout {
    public DreamOverlayContainerView(Context context) {
        this(context, null);
    }

    public DreamOverlayContainerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DreamOverlayContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public DreamOverlayContainerView(
            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
}
+41 −35
Original line number Diff line number Diff line
@@ -29,11 +29,11 @@ import android.view.WindowInsets;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.PhoneWindow;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;

import java.util.concurrent.Executor;

@@ -54,10 +54,12 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
    private final Executor mExecutor;
    // The state controller informs the service of updates to the overlays present.
    private final DreamOverlayStateController mStateController;
    // The component used to resolve dream overlay dependencies.
    private final DreamOverlayComponent mDreamOverlayComponent;

    // The window is populated once the dream informs the service it has begun dreaming.
    private Window mWindow;
    private ConstraintLayout mLayout;
    // The dream overlay's content view, which is located below the status bar (in z-order) and is
    // the space into which widgets are placed.
    private ViewGroup mDreamOverlayContentView;

    private final DreamOverlayStateController.Callback mOverlayStateCallback =
            new DreamOverlayStateController.Callback() {
@@ -90,12 +92,12 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
            new ViewTreeObserver.OnComputeInternalInsetsListener() {
        @Override
        public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
            if (mLayout != null) {
            if (mDreamOverlayContentView != null) {
                inoutInfo.setTouchableInsets(
                        ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
                final Region region = new Region();
                for (int i = 0; i < mLayout.getChildCount(); i++) {
                    View child = mLayout.getChildAt(i);
                for (int i = 0; i < mDreamOverlayContentView.getChildCount(); i++) {
                    View child = mDreamOverlayContentView.getChildAt(i);
                    final Rect rect = new Rect();
                    child.getGlobalVisibleRect(rect);
                    region.op(rect, Region.Op.UNION);
@@ -106,16 +108,30 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
        }
    };

    @Inject
    public DreamOverlayService(
            Context context,
            @Main Executor executor,
            DreamOverlayStateController overlayStateController,
            DreamOverlayComponent.Factory dreamOverlayComponentFactory) {
        mContext = context;
        mExecutor = executor;
        mStateController = overlayStateController;
        mDreamOverlayComponent = dreamOverlayComponentFactory.create();

        mStateController.addCallback(mOverlayStateCallback);
    }

    @Override
    public void onStartDream(@NonNull WindowManager.LayoutParams layoutParams) {
        mExecutor.execute(() -> addOverlayWindowLocked(layoutParams));
    }

    private void reloadOverlaysLocked() {
        if (mLayout == null) {
        if (mDreamOverlayContentView == null) {
            return;
        }
        mLayout.removeAllViews();
        mDreamOverlayContentView.removeAllViews();
        for (OverlayProvider overlayProvider : mStateController.getOverlays()) {
            addOverlay(overlayProvider);
        }
@@ -129,31 +145,30 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
     *                     into the dream window.
     */
    private void addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) {
        mWindow = new PhoneWindow(mContext);
        mWindow.setAttributes(layoutParams);
        mWindow.setWindowManager(null, layoutParams.token, "DreamOverlay", true);
        final PhoneWindow window = new PhoneWindow(mContext);
        window.setAttributes(layoutParams);
        window.setWindowManager(null, layoutParams.token, "DreamOverlay", true);

        mWindow.setBackgroundDrawable(new ColorDrawable(0));
        window.setBackgroundDrawable(new ColorDrawable(0));

        mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
        mWindow.requestFeature(Window.FEATURE_NO_TITLE);
        window.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
        window.requestFeature(Window.FEATURE_NO_TITLE);
        // Hide all insets when the dream is showing
        mWindow.getDecorView().getWindowInsetsController().hide(WindowInsets.Type.systemBars());
        mWindow.setDecorFitsSystemWindows(false);
        window.getDecorView().getWindowInsetsController().hide(WindowInsets.Type.systemBars());
        window.setDecorFitsSystemWindows(false);

        if (DEBUG) {
            Log.d(TAG, "adding overlay window to dream");
        }

        mLayout = new ConstraintLayout(mContext);
        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        mLayout.addOnAttachStateChangeListener(mRootViewAttachListener);
        mWindow.setContentView(mLayout);
        window.setContentView(mDreamOverlayComponent.getDreamOverlayContainerView());
        mDreamOverlayContentView = mDreamOverlayComponent.getDreamOverlayContentView();

        mDreamOverlayComponent.getDreamOverlayStatusBarViewController().init();

        final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
        windowManager.addView(mWindow.getDecorView(), mWindow.getAttributes());
        windowManager.addView(window.getDecorView(), window.getAttributes());
        mExecutor.execute(this::reloadOverlaysLocked);
    }

@@ -163,11 +178,11 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
                (view, layoutParams) -> {
                    // Always move UI related work to the main thread.
                    mExecutor.execute(() -> {
                        if (mLayout == null) {
                        if (mDreamOverlayContentView == null) {
                            return;
                        }

                        mLayout.addView(view, layoutParams);
                        mDreamOverlayContentView.addView(view, layoutParams);
                    });
                },
                () -> {
@@ -178,15 +193,6 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
                });
    }

    @Inject
    public DreamOverlayService(Context context, @Main Executor executor,
            DreamOverlayStateController overlayStateController) {
        mContext = context;
        mExecutor = executor;
        mStateController = overlayStateController;
        mStateController.addCallback(mOverlayStateCallback);
    }

    @Override
    public void onDestroy() {
        mStateController.removeCallback(mOverlayStateCallback);
Loading