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

Commit 56ff8c44 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge ""Global Actions Panel" plugin"

parents 4d8cabe4 9b87a44b
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ public class FeatureFlagUtils {
    public static final String SAFETY_HUB = "settings_safety_hub";
    public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
    public static final String GLOBAL_ACTIONS_GRID_ENABLED = "settings_global_actions_grid_enabled";
    public static final String GLOBAL_ACTIONS_PANEL_ENABLED =
            "settings_global_actions_panel_enabled";

    private static final Map<String, String> DEFAULT_FLAGS;

@@ -56,7 +58,8 @@ public class FeatureFlagUtils {
        DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
        DEFAULT_FLAGS.put(SAFETY_HUB, "false");
        DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
        DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "false");
        DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true");
        DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true");
    }

    /**
+86 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.plugins;

import android.view.View;

import com.android.systemui.plugins.annotations.DependsOn;
import com.android.systemui.plugins.annotations.ProvidesInterface;

/**
 * Plugin which provides a "Panel" {@link View} to be rendered inside of the GlobalActions menu.
 *
 * Implementations should construct a new {@link PanelViewController} with the given
 * {@link Callbacks} instance inside of {@link #onPanelShown(Callbacks)}, and should not hold onto
 * a reference, instead allowing Global Actions to manage the lifetime of the object.
 *
 * Under this assumption, {@link PanelViewController} represents the lifetime of a single invocation
 * of the Global Actions menu. The {@link View} for the Panel is generated when the
 * {@link PanelViewController} is constructed, and {@link PanelViewController#getPanelContent()}
 * serves as a simple getter. When Global Actions is dismissed,
 * {@link PanelViewController#onDismissed()} can be used to cleanup any resources allocated when
 * constructed. Global Actions will then release the reference, and the {@link PanelViewController}
 * will be garbage-collected.
 */
@ProvidesInterface(
        action = GlobalActionsPanelPlugin.ACTION, version = GlobalActionsPanelPlugin.VERSION)
@DependsOn(target = GlobalActionsPanelPlugin.Callbacks.class)
@DependsOn(target = GlobalActionsPanelPlugin.PanelViewController.class)
public interface GlobalActionsPanelPlugin extends Plugin {
    String ACTION = "com.android.systemui.action.PLUGIN_GLOBAL_ACTIONS_PANEL";
    int VERSION = 0;

    /**
     * Invoked when the GlobalActions menu is shown.
     *
     * @param callbacks {@link Callbacks} instance that can be used by the Panel to interact with
     *                  the Global Actions menu.
     * @return A {@link PanelViewController} instance used to receive Global Actions events.
     */
    PanelViewController onPanelShown(Callbacks callbacks);

    /**
     * Provides methods to interact with the Global Actions menu.
     */
    @ProvidesInterface(version = Callbacks.VERSION)
    interface Callbacks {
        int VERSION = 0;

        /** Dismisses the Global Actions menu. */
        void dismissGlobalActionsMenu();
    }

    /**
     * Receives Global Actions events, and provides the Panel {@link View}.
     */
    @ProvidesInterface(version = PanelViewController.VERSION)
    interface PanelViewController {
        int VERSION = 0;

        /**
         * Returns the {@link View} for the Panel to be rendered in Global Actions. This View can be
         * any size, and will be rendered above the Global Actions menu when z-ordered.
         */
        View getPanelContent();

        /**
         * Invoked when the Global Actions menu (containing the View returned from
         * {@link #getPanelContent()}) is dismissed.
         */
        void onDismissed();
    }
}
+26 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2019 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
  -->

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <gradient
        android:centerY="0.45"
        android:startColor="#be3c4043"
        android:centerColor="#be3c4043"
        android:endColor="#4d3c4043"
        android:angle="270" />
</shape>
 No newline at end of file
+3 −0
Original line number Diff line number Diff line
@@ -856,6 +856,9 @@
    <!-- Global actions grid layout -->
    <dimen name="global_actions_grid_side_margin">4dp</dimen>

    <!-- Global actions panel -->
    <dimen name="global_actions_panel_top_margin">85dp</dimen>

    <!-- The maximum offset in either direction that elements are moved horizontally to prevent
         burn-in on AOD. -->
    <dimen name="burn_in_prevention_offset_x">8dp</dimen>
+91 −21
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
@@ -88,8 +89,10 @@ import com.android.systemui.Interpolators;
import com.android.systemui.MultiListLayout;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.ExtensionController.Extension;
import com.android.systemui.util.EmergencyDialerConstants;
import com.android.systemui.util.leak.RotationUtils;
import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator;
@@ -161,6 +164,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
    private final ScreenshotHelper mScreenshotHelper;
    private final ScreenRecordHelper mScreenRecordHelper;

    private final Extension<GlobalActionsPanelPlugin> mPanelExtension;

    /**
     * @param context everything needs a context :(
     */
@@ -204,6 +209,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
        mScreenRecordHelper = new ScreenRecordHelper(context);

        Dependency.get(ConfigurationController.class).addCallback(this);

        mPanelExtension = Dependency.get(ExtensionController.class)
            .newExtension(GlobalActionsPanelPlugin.class)
            .withPlugin(GlobalActionsPanelPlugin.class)
            .build();
    }

    /**
@@ -399,8 +409,16 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
            }
            return false;
        };
        GlobalActionsPanelPlugin.PanelViewController panelViewController =
                mPanelExtension.get() != null
                        ? mPanelExtension.get().onPanelShown(() -> {
                            if (mDialog != null) {
                                mDialog.dismiss();
                            }
                        })
                        : null;
        ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener,
                mSeparatedEmergencyButtonEnabled);
                mSeparatedEmergencyButtonEnabled, panelViewController);
        dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
        dialog.setKeyguardShowing(mKeyguardShowing);

@@ -1470,20 +1488,22 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
        private MultiListLayout mGlobalActionsLayout;
        private final OnClickListener mClickListener;
        private final OnItemLongClickListener mLongClickListener;
        private final GradientDrawable mGradientDrawable;
        private final Drawable mBackgroundDrawable;
        private final ColorExtractor mColorExtractor;
        private final GlobalActionsPanelPlugin.PanelViewController mPanelController;
        private boolean mKeyguardShowing;
        private boolean mShouldDisplaySeparatedButton;
        private boolean mShowing;
        private final float mScrimAlpha;

        public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
                OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton) {
                OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton,
                GlobalActionsPanelPlugin.PanelViewController plugin) {
            super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
            mContext = context;
            mAdapter = adapter;
            mClickListener = clickListener;
            mLongClickListener = longClickListener;
            mGradientDrawable = new GradientDrawable(mContext);
            mColorExtractor = Dependency.get(SysuiColorExtractor.class);
            mShouldDisplaySeparatedButton = shouldDisplaySeparatedButton;

@@ -1504,12 +1524,46 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
            window.setBackgroundDrawable(mGradientDrawable);
            window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);

            initializeLayout();

            setTitle(R.string.global_actions);

            mPanelController = plugin;
            View panelView = initializePanel();
            if (panelView == null) {
                mBackgroundDrawable = new GradientDrawable(context);
                mScrimAlpha = 0.7f;
            } else {
                mBackgroundDrawable = context.getDrawable(
                        com.android.systemui.R.drawable.global_action_panel_scrim);
                mScrimAlpha = 1f;
                addContentView(
                        panelView,
                        new ViewGroup.LayoutParams(
                                ViewGroup.LayoutParams.MATCH_PARENT,
                                ViewGroup.LayoutParams.MATCH_PARENT));
            }
            window.setBackgroundDrawable(mBackgroundDrawable);
        }

        private View initializePanel() {
            if (isPanelEnabled(mContext) && mPanelController != null) {
                View panelView = mPanelController.getPanelContent();
                if (panelView != null) {
                    FrameLayout panelContainer = new FrameLayout(mContext);
                    FrameLayout.LayoutParams panelParams =
                            new FrameLayout.LayoutParams(
                                    FrameLayout.LayoutParams.MATCH_PARENT,
                                    FrameLayout.LayoutParams.WRAP_CONTENT);
                    panelParams.topMargin = mContext.getResources().getDimensionPixelSize(
                            com.android.systemui.R.dimen.global_actions_panel_top_margin);
                    panelContainer.addView(panelView, panelParams);
                    return panelContainer;
                }
            }
            return null;
        }

        private void initializeLayout() {
@@ -1530,6 +1584,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
            mGlobalActionsLayout.setRotationListener(this::onRotate);
        }

        private boolean isPanelEnabled(Context context) {
            return FeatureFlagUtils.isEnabled(
                    context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED);
        }

        private int getGlobalActionsLayoutId(Context context) {
            if (isGridEnabled(context)) {
                if (RotationUtils.getRotation(context) == RotationUtils.ROTATION_SEASCAPE) {
@@ -1590,14 +1649,19 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
            super.onStart();
            updateList();

            if (mBackgroundDrawable instanceof GradientDrawable) {
                Point displaySize = new Point();
                mContext.getDisplay().getRealSize(displaySize);
                mColorExtractor.addOnColorsChangedListener(this);
            mGradientDrawable.setScreenSize(displaySize.x, displaySize.y);
            GradientColors colors = mColorExtractor.getColors(mKeyguardShowing ?
                    WallpaperManager.FLAG_LOCK : WallpaperManager.FLAG_SYSTEM);
                ((GradientDrawable) mBackgroundDrawable)
                        .setScreenSize(displaySize.x, displaySize.y);
                GradientColors colors = mColorExtractor.getColors(
                        mKeyguardShowing
                                ? WallpaperManager.FLAG_LOCK
                                : WallpaperManager.FLAG_SYSTEM);
                updateColors(colors, false /* animate */);
            }
        }

        /**
         * Updates background and system bars according to current GradientColors.
@@ -1605,7 +1669,10 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
         * @param animate Interpolates gradient if true, just sets otherwise.
         */
        private void updateColors(GradientColors colors, boolean animate) {
            mGradientDrawable.setColors(colors, animate);
            if (!(mBackgroundDrawable instanceof GradientDrawable)) {
                return;
            }
            ((GradientDrawable) mBackgroundDrawable).setColors(colors, animate);
            View decorView = getWindow().getDecorView();
            if (colors.supportsDarkText()) {
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
@@ -1625,7 +1692,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
        public void show() {
            super.show();
            mShowing = true;
            mGradientDrawable.setAlpha(0);
            mBackgroundDrawable.setAlpha(0);
            mGlobalActionsLayout.setTranslationX(getAnimTranslation());
            mGlobalActionsLayout.setAlpha(0);
            mGlobalActionsLayout.animate()
@@ -1635,8 +1702,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                    .setUpdateListener(animation -> {
                        int alpha = (int) ((Float) animation.getAnimatedValue()
                                * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
                        mGradientDrawable.setAlpha(alpha);
                                * mScrimAlpha * 255);
                        mBackgroundDrawable.setAlpha(alpha);
                    })
                    .start();
        }
@@ -1653,14 +1720,17 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
                    .alpha(0)
                    .translationX(getAnimTranslation())
                    .setDuration(300)
                    .withEndAction(() -> super.dismiss())
                    .withEndAction(super::dismiss)
                    .setInterpolator(new LogAccelerateInterpolator())
                    .setUpdateListener(animation -> {
                        int alpha = (int) ((1f - (Float) animation.getAnimatedValue())
                                * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
                        mGradientDrawable.setAlpha(alpha);
                                * mScrimAlpha * 255);
                        mBackgroundDrawable.setAlpha(alpha);
                    })
                    .start();
            if (mPanelController != null) {
                mPanelController.onDismissed();
            }
        }

        void dismissImmediately() {