1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.policy; 18 19 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BACK_GESTURE_EDGE_WIDTH; 20 21 import android.content.ContentResolver; 22 import android.content.Context; 23 import android.content.res.Resources; 24 import android.database.ContentObserver; 25 import android.os.Handler; 26 import android.os.UserHandle; 27 import android.provider.DeviceConfig; 28 import android.provider.Settings; 29 import android.util.DisplayMetrics; 30 import android.util.TypedValue; 31 32 /** 33 * @hide 34 */ 35 public class GestureNavigationSettingsObserver extends ContentObserver { 36 private Context mContext; 37 private Runnable mOnChangeRunnable; 38 private Handler mMainHandler; 39 GestureNavigationSettingsObserver(Handler handler, Context context, Runnable onChangeRunnable)40 public GestureNavigationSettingsObserver(Handler handler, Context context, 41 Runnable onChangeRunnable) { 42 super(handler); 43 mMainHandler = handler; 44 mContext = context; 45 mOnChangeRunnable = onChangeRunnable; 46 } 47 48 private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener = 49 new DeviceConfig.OnPropertiesChangedListener() { 50 @Override 51 public void onPropertiesChanged(DeviceConfig.Properties properties) { 52 if (DeviceConfig.NAMESPACE_SYSTEMUI.equals(properties.getNamespace()) 53 && mOnChangeRunnable != null) { 54 mOnChangeRunnable.run(); 55 } 56 } 57 }; 58 register()59 public void register() { 60 ContentResolver r = mContext.getContentResolver(); 61 r.registerContentObserver( 62 Settings.Secure.getUriFor(Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT), 63 false, this, UserHandle.USER_ALL); 64 r.registerContentObserver( 65 Settings.Secure.getUriFor(Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT), 66 false, this, UserHandle.USER_ALL); 67 r.registerContentObserver( 68 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), 69 false, this, UserHandle.USER_ALL); 70 DeviceConfig.addOnPropertiesChangedListener( 71 DeviceConfig.NAMESPACE_SYSTEMUI, 72 runnable -> mMainHandler.post(runnable), 73 mOnPropertiesChangedListener); 74 } 75 unregister()76 public void unregister() { 77 mContext.getContentResolver().unregisterContentObserver(this); 78 DeviceConfig.removeOnPropertiesChangedListener(mOnPropertiesChangedListener); 79 } 80 81 @Override onChange(boolean selfChange)82 public void onChange(boolean selfChange) { 83 super.onChange(selfChange); 84 if (mOnChangeRunnable != null) { 85 mOnChangeRunnable.run(); 86 } 87 } 88 getLeftSensitivity(Resources userRes)89 public int getLeftSensitivity(Resources userRes) { 90 return getSensitivity(userRes, Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT); 91 } 92 getRightSensitivity(Resources userRes)93 public int getRightSensitivity(Resources userRes) { 94 return getSensitivity(userRes, Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT); 95 } 96 areNavigationButtonForcedVisible()97 public boolean areNavigationButtonForcedVisible() { 98 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 99 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) == 0; 100 } 101 getSensitivity(Resources userRes, String side)102 private int getSensitivity(Resources userRes, String side) { 103 final DisplayMetrics dm = userRes.getDisplayMetrics(); 104 final float defaultInset = userRes.getDimension( 105 com.android.internal.R.dimen.config_backGestureInset) / dm.density; 106 // Only apply the back gesture config if there is an existing inset 107 final float backGestureInset = defaultInset > 0 108 ? DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI, 109 BACK_GESTURE_EDGE_WIDTH, defaultInset) 110 : defaultInset; 111 final float inset = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, backGestureInset, 112 dm); 113 final float scale = Settings.Secure.getFloatForUser( 114 mContext.getContentResolver(), side, 1.0f, UserHandle.USER_CURRENT); 115 return (int) (inset * scale); 116 } 117 } 118