blob: 9988c85361bbbaf7a25c870c07f9113c76c8704f [file] [log] [blame]
/*
* 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 static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import android.annotation.IntDef;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Point;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import com.android.systemui.shared.system.QuickStepContract;
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 implements ComponentCallbacks {
private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback";
private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome";
private static final String PROTOTYPE_ENABLED = "prototype_enabled";
public static final String EDGE_SENSITIVITY_WIDTH_SETTING =
"quickstepcontroller_edge_width_sensitivity";
private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map";
public static final String NAV_COLOR_ADAPT_ENABLE_SETTING = "navbar_color_adapt_enable";
public static final String SHOW_HOME_HANDLE_SETTING = "quickstepcontroller_showhandle";
public static final String ENABLE_ASSISTANT_GESTURE = "ENABLE_ASSISTANT_GESTURE";
@Retention(RetentionPolicy.SOURCE)
@IntDef({ACTION_DEFAULT, ACTION_QUICKSTEP, ACTION_QUICKSCRUB, ACTION_BACK,
ACTION_QUICKSWITCH, ACTION_NOTHING, ACTION_ASSISTANT})
@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;
static final int ACTION_QUICKSWITCH = 4;
static final int ACTION_NOTHING = 5;
static final int ACTION_ASSISTANT = 6;
private OnPrototypeChangedListener mListener;
/**
* Each index corresponds to a different action set in QuickStepController
* {@see updateSwipeLTRBackSetting}
*/
private int[] mActionMap = new int[6];
private final Context mContext;
public NavigationPrototypeController(Context context) {
super(new 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(HIDE_HOME_BUTTON_SETTING);
registerObserver(GESTURE_MATCH_SETTING);
registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING);
registerObserver(SHOW_HOME_HANDLE_SETTING);
registerObserver(ENABLE_ASSISTANT_GESTURE);
mContext.registerComponentCallbacks(this);
}
/**
* Disable observing settings to react to from prototype settings
*/
public void unregister() {
mContext.getContentResolver().unregisterContentObserver(this);
mContext.unregisterComponentCallbacks(this);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (!selfChange && mListener != null) {
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, false));
} else if (path.endsWith(HIDE_HOME_BUTTON_SETTING)) {
mListener.onHomeButtonVisibilityChanged(!hideHomeButton());
} else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) {
mListener.onColorAdaptChanged(
NavBarTintController.isEnabled(mContext, NAV_BAR_MODE_GESTURAL));
} else if (path.endsWith(SHOW_HOME_HANDLE_SETTING)) {
mListener.onHomeHandleVisiblilityChanged(showHomeHandle());
} else if (path.endsWith(ENABLE_ASSISTANT_GESTURE)) {
mListener.onAssistantGestureEnabled(isAssistantGestureEnabled());
}
}
}
/**
* @return the width for edge swipe
*/
public int getEdgeSensitivityWidth() {
return mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.config_backGestureInset);
}
/**
* @return full screen height
*/
public int getEdgeSensitivityHeight() {
final Point size = new Point();
mContext.getDisplay().getRealSize(size);
return size.y;
}
public boolean isEnabled() {
return getGlobalBool(PROTOTYPE_ENABLED, false);
}
/**
* Retrieve the action map to apply to the quick step controller
* @return an action map
*/
int[] getGestureActionMap() {
return mActionMap;
}
/**
* @return if home button should be invisible
*/
boolean hideHomeButton() {
return getGlobalBool(HIDE_HOME_BUTTON_SETTING, false /* default */);
}
boolean showHomeHandle() {
return getGlobalBool(SHOW_HOME_HANDLE_SETTING, false /* default */);
}
boolean isAssistantGestureEnabled() {
return getGlobalBool(ENABLE_ASSISTANT_GESTURE, false /* default */);
}
/**
* 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, boolean defaultVal) {
return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal ? 1 : 0) == 1;
}
private int getGlobalInt(String name, int defaultVal) {
return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal);
}
private void registerObserver(String name) {
mContext.getContentResolver()
.registerContentObserver(Settings.Global.getUriFor(name), false, this);
}
private static int convertDpToPixel(float dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (mListener != null) {
mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(),
getEdgeSensitivityHeight());
}
}
@Override
public void onLowMemory() {
}
public interface OnPrototypeChangedListener {
void onGestureRemap(@GestureAction int[] actions);
void onBackButtonVisibilityChanged(boolean visible);
void onHomeButtonVisibilityChanged(boolean visible);
void onHomeHandleVisiblilityChanged(boolean visible);
void onColorAdaptChanged(boolean enabled);
void onEdgeSensitivityChanged(int width, int height);
void onAssistantGestureEnabled(boolean enabled);
}
}