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

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

Merge "Prototype settings can remap the gestures and actions"

parents 1dbe2b20 1cf6eac2
Loading
Loading
Loading
Loading
+2 −21
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.systemui.statusbar.phone;

import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;

import android.annotation.NonNull;
import android.hardware.input.InputManager;
import android.os.Handler;
@@ -35,10 +33,8 @@ import com.android.systemui.recents.OverviewProxyService;
 */
public class NavigationBackAction extends NavigationGestureAction {

    private static final String PULL_HOME_GO_BACK_PROP = "quickstepcontroller_homegoesback";
    private static final String BACK_AFTER_END_PROP =
            "quickstepcontroller_homegoesbackwhenend";
    private static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled";
    private static final long BACK_BUTTON_FADE_OUT_ALPHA = 60;
    private static final long BACK_GESTURE_POLL_TIMEOUT = 1000;

@@ -59,16 +55,6 @@ public class NavigationBackAction extends NavigationGestureAction {
        super(navigationBarView, service);
    }

    @Override
    public int requiresTouchDownHitTarget() {
        return HIT_TARGET_HOME;
    }

    @Override
    public boolean requiresDragWithHitTarget() {
        return true;
    }

    @Override
    public boolean canPerformAction() {
        return mProxySender.getBackButtonAlpha() > 0;
@@ -76,7 +62,7 @@ public class NavigationBackAction extends NavigationGestureAction {

    @Override
    public boolean isEnabled() {
        return swipeHomeGoBackGestureEnabled();
        return !getGlobalBoolean(NavigationPrototypeController.NAVBAR_EXPERIMENTS_DISABLED);
    }

    @Override
@@ -110,13 +96,8 @@ public class NavigationBackAction extends NavigationGestureAction {
        mNavigationBarView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
    }

    private boolean swipeHomeGoBackGestureEnabled() {
        return !getGlobalBoolean(NAVBAR_EXPERIMENTS_DISABLED)
                && getGlobalBoolean(PULL_HOME_GO_BACK_PROP);
    }

    private boolean shouldExecuteBackOnUp() {
        return !getGlobalBoolean(NAVBAR_EXPERIMENTS_DISABLED)
        return !getGlobalBoolean(NavigationPrototypeController.NAVBAR_EXPERIMENTS_DISABLED)
                && getGlobalBoolean(BACK_AFTER_END_PROP);
    }

+51 −2
Original line number Diff line number Diff line
@@ -77,6 +77,8 @@ import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.NavigationBarCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.statusbar.phone.NavigationPrototypeController.GestureAction;
import com.android.systemui.statusbar.phone.NavigationPrototypeController.OnPrototypeChangedListener;
import com.android.systemui.statusbar.policy.DeadZone;
import com.android.systemui.statusbar.policy.KeyButtonDrawable;

@@ -146,6 +148,8 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
    private RecentsOnboarding mRecentsOnboarding;
    private NotificationPanelView mPanelView;

    private NavigationPrototypeController mPrototypeController;
    private NavigationGestureAction[] mDefaultGestureMap;
    private QuickScrubAction mQuickScrubAction;
    private QuickStepAction mQuickStepAction;
    private NavigationBackAction mBackAction;
@@ -261,6 +265,18 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
        }
    };

    private OnPrototypeChangedListener mPrototypeListener = new OnPrototypeChangedListener() {
        @Override
        public void onGestureRemap(int[] actions) {
            updateNavigationGestures();
        }

        @Override
        public void onBackButtonVisibilityChanged(boolean visible) {
            getBackButton().setVisibility(visible ? VISIBLE : GONE);
        }
    };

    public NavigationBarView(Context context, AttributeSet attrs) {
        super(context, attrs);

@@ -309,6 +325,14 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
        mQuickScrubAction = new QuickScrubAction(this, mOverviewProxyService);
        mQuickStepAction = new QuickStepAction(this, mOverviewProxyService);
        mBackAction = new NavigationBackAction(this, mOverviewProxyService);
        mDefaultGestureMap = new NavigationGestureAction[] {
                mQuickStepAction, null /* swipeDownAction*/, null /* swipeLeftAction */,
                mQuickScrubAction
        };

        mPrototypeController = new NavigationPrototypeController(mHandler, mContext);
        mPrototypeController.register();
        mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener);
    }

    public BarTransitions getBarTransitions() {
@@ -323,8 +347,32 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
        mPanelView = panel;
        if (mGestureHelper instanceof QuickStepController) {
            ((QuickStepController) mGestureHelper).setComponents(this);
            ((QuickStepController) mGestureHelper).setGestureActions(mQuickStepAction,
                    null /* swipeDownAction*/, mBackAction, mQuickScrubAction);
            updateNavigationGestures();
        }
    }

    private void updateNavigationGestures() {
        if (mGestureHelper instanceof QuickStepController) {
            final int[] assignedMap = mPrototypeController.getGestureActionMap();
            ((QuickStepController) mGestureHelper).setGestureActions(
                    getNavigationActionFromType(assignedMap[0], mDefaultGestureMap[0]),
                    getNavigationActionFromType(assignedMap[1], mDefaultGestureMap[1]),
                    getNavigationActionFromType(assignedMap[2], mDefaultGestureMap[2]),
                    getNavigationActionFromType(assignedMap[3], mDefaultGestureMap[3]));
        }
    }

    private NavigationGestureAction getNavigationActionFromType(@GestureAction int actionType,
            NavigationGestureAction defaultAction) {
        switch(actionType) {
            case NavigationPrototypeController.ACTION_QUICKSTEP:
                return mQuickStepAction;
            case NavigationPrototypeController.ACTION_QUICKSCRUB:
                return mQuickScrubAction;
            case NavigationPrototypeController.ACTION_BACK:
                return mBackAction;
            default:
                return defaultAction;
        }
    }

@@ -1043,6 +1091,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
        if (mGestureHelper != null) {
            mGestureHelper.destroy();
        }
        mPrototypeController.unregister();
        setUpSwipeUpOnboarding(false);
        for (int i = 0; i < mButtonDispatchers.size(); ++i) {
            mButtonDispatchers.valueAt(i).onDestroy();
+142 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 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.statusbar.phone;

import android.annotation.IntDef;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;

import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Coordinates with the prototype settings plugin app that uses Settings.Global to allow different
 * prototypes to run in the system. The class will handle communication changes from the settings
 * app and call back to listeners.
 */
public class NavigationPrototypeController extends ContentObserver {
    private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback";

    static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled";
    private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map";

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({ACTION_DEFAULT, ACTION_QUICKSTEP, ACTION_QUICKSCRUB, ACTION_BACK})
    @interface GestureAction {}
    static final int ACTION_DEFAULT = 0;
    static final int ACTION_QUICKSTEP = 1;
    static final int ACTION_QUICKSCRUB = 2;
    static final int ACTION_BACK = 3;

    private OnPrototypeChangedListener mListener;

    /**
     * Each index corresponds to a different action set in QuickStepController
     * {@see updateSwipeLTRBackSetting}
     */
    private int[] mActionMap = new int[4];

    private final Context mContext;

    public NavigationPrototypeController(Handler handler, Context context) {
        super(handler);
        mContext = context;
        updateSwipeLTRBackSetting();
    }

    public void setOnPrototypeChangedListener(OnPrototypeChangedListener listener) {
        mListener = listener;
    }

    /**
     * Observe all the settings to react to from prototype settings
     */
    public void register() {
        registerObserver(HIDE_BACK_BUTTON_SETTING);
        registerObserver(GESTURE_MATCH_SETTING);
    }

    /**
     * Disable observing settings to react to from prototype settings
     */
    public void unregister() {
        mContext.getContentResolver().unregisterContentObserver(this);
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        super.onChange(selfChange, uri);
        if (!selfChange && mListener != null) {
            try {
                final String path = uri.getPath();
                if (path.endsWith(GESTURE_MATCH_SETTING)) {
                    // Get the settings gesture map corresponding to each action
                    // {@see updateSwipeLTRBackSetting}
                    updateSwipeLTRBackSetting();
                    mListener.onGestureRemap(mActionMap);
                } else if (path.endsWith(HIDE_BACK_BUTTON_SETTING)) {
                    mListener.onBackButtonVisibilityChanged(
                            !getGlobalBool(HIDE_BACK_BUTTON_SETTING));
                }
            } catch (SettingNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Retrieve the action map to apply to the quick step controller
     * @return an action map
     */
    int[] getGestureActionMap() {
        return mActionMap;
    }

    /**
     * Since Settings.Global cannot pass arrays, use a string to represent each character as a
     * gesture map to actions corresponding to {@see GestureAction}. The number is represented as:
     * Number: [up] [down] [left] [right]
     */
    private void updateSwipeLTRBackSetting() {
        String value = Settings.Global.getString(mContext.getContentResolver(),
                GESTURE_MATCH_SETTING);
        if (value != null) {
            for (int i = 0; i < mActionMap.length; ++i) {
                mActionMap[i] = Character.getNumericValue(value.charAt(i));
            }
        }
    }

    private boolean getGlobalBool(String name) throws SettingNotFoundException {
        return Settings.Global.getInt(mContext.getContentResolver(), name) == 1;
    }

    private void registerObserver(String name) {
        mContext.getContentResolver()
                .registerContentObserver(Settings.Global.getUriFor(name), false, this);
    }

    public interface OnPrototypeChangedListener {
        void onGestureRemap(@GestureAction int[] actions);
        void onBackButtonVisibilityChanged(boolean visible);
    }
}
+5 −2
Original line number Diff line number Diff line
@@ -30,9 +30,9 @@ import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_

import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.Log;
@@ -100,6 +100,7 @@ public class QuickStepController implements GestureHelper {
    private NavigationGestureAction mCurrentAction;
    private NavigationGestureAction[] mGestureActions = new NavigationGestureAction[MAX_GESTURES];

    private final Rect mLastLayoutRect = new Rect();
    private final OverviewProxyService mOverviewEventSender;
    private final Context mContext;
    private final StatusBar mStatusBar;
@@ -107,7 +108,6 @@ public class QuickStepController implements GestureHelper {
    private final Matrix mTransformLocalMatrix = new Matrix();

    public QuickStepController(Context context) {
        final Resources res = context.getResources();
        mContext = context;
        mStatusBar = SysUiServiceProvider.getComponent(context, StatusBar.class);
        mOverviewEventSender = Dependency.get(OverviewProxyService.class);
@@ -142,6 +142,8 @@ public class QuickStepController implements GestureHelper {
            if (action != null) {
                action.setBarState(true, mNavBarPosition, mDragHPositive, mDragVPositive);
                action.onDarkIntensityChange(mDarkIntensity);
                action.onLayout(true /* changed */, mLastLayoutRect.left, mLastLayoutRect.top,
                        mLastLayoutRect.right, mLastLayoutRect.bottom);
            }
        }
    }
@@ -382,6 +384,7 @@ public class QuickStepController implements GestureHelper {
                action.onLayout(changed, left, top, right, bottom);
            }
        }
        mLastLayoutRect.set(left, top, right, bottom);
    }

    @Override