1 /* 2 * Copyright (C) 2023 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.systemui.accessibility; 18 19 import static com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize; 20 21 import android.annotation.NonNull; 22 import android.annotation.UiContext; 23 import android.content.ComponentCallbacks; 24 import android.content.Context; 25 import android.content.res.Configuration; 26 import android.util.Range; 27 import android.view.WindowManager; 28 29 import com.android.internal.accessibility.common.MagnificationConstants; 30 import com.android.internal.annotations.VisibleForTesting; 31 import com.android.internal.graphics.SfVsyncFrameCallbackProvider; 32 import com.android.systemui.util.settings.SecureSettings; 33 import com.android.systemui.utils.windowmanager.WindowManagerProvider; 34 35 /** 36 * A class to control {@link WindowMagnificationSettings} and receive settings panel callbacks by 37 * {@link WindowMagnificationSettingsCallback}. 38 * The settings panel callbacks will be delegated through 39 * {@link MagnificationSettingsController.Callback} to {@link Magnification}. 40 */ 41 42 public class MagnificationSettingsController implements ComponentCallbacks { 43 44 // It should be consistent with the value defined in WindowMagnificationGestureHandler. 45 private static final Range<Float> A11Y_ACTION_SCALE_RANGE = 46 new Range<>(1.0f, MagnificationConstants.SCALE_MAX_VALUE); 47 48 private final Context mContext; 49 50 private final int mDisplayId; 51 52 @NonNull 53 private final Callback mSettingsControllerCallback; 54 55 // Window Magnification Setting view 56 private WindowMagnificationSettings mWindowMagnificationSettings; 57 58 private final Configuration mConfiguration; 59 MagnificationSettingsController( @iContext Context context, SfVsyncFrameCallbackProvider sfVsyncFrameProvider, @NonNull Callback settingsControllerCallback, SecureSettings secureSettings, WindowManagerProvider windowManagerProvider)60 MagnificationSettingsController( 61 @UiContext Context context, 62 SfVsyncFrameCallbackProvider sfVsyncFrameProvider, 63 @NonNull Callback settingsControllerCallback, 64 SecureSettings secureSettings, 65 WindowManagerProvider windowManagerProvider) { 66 this(context, sfVsyncFrameProvider, settingsControllerCallback, secureSettings, 67 windowManagerProvider, null); 68 } 69 70 @VisibleForTesting MagnificationSettingsController( @iContext Context context, SfVsyncFrameCallbackProvider sfVsyncFrameProvider, @NonNull Callback settingsControllerCallback, SecureSettings secureSettings, WindowManagerProvider windowManagerProvider, WindowMagnificationSettings windowMagnificationSettings)71 MagnificationSettingsController( 72 @UiContext Context context, 73 SfVsyncFrameCallbackProvider sfVsyncFrameProvider, 74 @NonNull Callback settingsControllerCallback, 75 SecureSettings secureSettings, 76 WindowManagerProvider windowManagerProvider, 77 WindowMagnificationSettings windowMagnificationSettings) { 78 mContext = context.createWindowContext( 79 context.getDisplay(), 80 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, 81 null); 82 mContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI); 83 mDisplayId = mContext.getDisplayId(); 84 mConfiguration = new Configuration(mContext.getResources().getConfiguration()); 85 mSettingsControllerCallback = settingsControllerCallback; 86 if (windowMagnificationSettings != null) { 87 mWindowMagnificationSettings = windowMagnificationSettings; 88 } else { 89 WindowManager windowManager = windowManagerProvider.getWindowManager(mContext); 90 mWindowMagnificationSettings = new WindowMagnificationSettings(mContext, 91 mWindowMagnificationSettingsCallback, 92 sfVsyncFrameProvider, secureSettings, windowManager); 93 } 94 } 95 96 /** 97 * Toggles the visibility of magnification settings panel {@link WindowMagnificationSettings}. 98 * We show the panel if it is not visible. Otherwise, hide the panel. 99 */ toggleSettingsPanelVisibility()100 void toggleSettingsPanelVisibility() { 101 if (!mWindowMagnificationSettings.isSettingPanelShowing()) { 102 onConfigurationChanged(mContext.getResources().getConfiguration()); 103 mContext.registerComponentCallbacks(this); 104 } 105 mWindowMagnificationSettings.toggleSettingsPanelVisibility(); 106 } 107 updateSettingsButtonStatusOnRestore(@agnificationSize int index)108 void updateSettingsButtonStatusOnRestore(@MagnificationSize int index) { 109 mWindowMagnificationSettings.updateSelectedButton(index); 110 } 111 closeMagnificationSettings()112 void closeMagnificationSettings() { 113 mContext.unregisterComponentCallbacks(this); 114 mWindowMagnificationSettings.hideSettingPanel(); 115 } 116 isMagnificationSettingsShowing()117 boolean isMagnificationSettingsShowing() { 118 return mWindowMagnificationSettings.isSettingPanelShowing(); 119 } 120 setMagnificationScale(float scale)121 void setMagnificationScale(float scale) { 122 mWindowMagnificationSettings.setMagnificationScale(scale); 123 } 124 125 @Override onConfigurationChanged(@onNull Configuration newConfig)126 public void onConfigurationChanged(@NonNull Configuration newConfig) { 127 final int configDiff = newConfig.diff(mConfiguration); 128 mConfiguration.setTo(newConfig); 129 onConfigurationChanged(configDiff); 130 } 131 132 @VisibleForTesting onConfigurationChanged(int configDiff)133 void onConfigurationChanged(int configDiff) { 134 mWindowMagnificationSettings.onConfigurationChanged(configDiff); 135 } 136 137 @Override onLowMemory()138 public void onLowMemory() { 139 140 } 141 142 interface Callback { 143 144 /** 145 * Called when change magnification size. 146 * 147 * @param displayId The logical display id. 148 * @param index Magnification size index. 149 * 0 : MagnificationSize.NONE, 150 * 1 : MagnificationSize.SMALL, 151 * 2 : MagnificationSize.MEDIUM, 152 * 3 : MagnificationSize.LARGE, 153 * 4 : MagnificationSize.FULLSCREEN 154 */ onSetMagnifierSize(int displayId, @MagnificationSize int index)155 void onSetMagnifierSize(int displayId, @MagnificationSize int index); 156 157 /** 158 * Called when set allow diagonal scrolling. 159 * 160 * @param displayId The logical display id. 161 * @param enable Allow diagonal scrolling enable value. 162 */ onSetDiagonalScrolling(int displayId, boolean enable)163 void onSetDiagonalScrolling(int displayId, boolean enable); 164 165 /** 166 * Called when change magnification size on free mode. 167 * 168 * @param displayId The logical display id. 169 * @param enable Free mode enable value. 170 */ onEditMagnifierSizeMode(int displayId, boolean enable)171 void onEditMagnifierSizeMode(int displayId, boolean enable); 172 173 /** 174 * Called when set magnification scale. 175 * 176 * @param displayId The logical display id. 177 * @param scale Magnification scale value. 178 * @param updatePersistence whether the new scale should be persisted. 179 */ onMagnifierScale(int displayId, float scale, boolean updatePersistence)180 void onMagnifierScale(int displayId, float scale, boolean updatePersistence); 181 182 /** 183 * Called when magnification mode changed. 184 * 185 * @param displayId The logical display id. 186 * @param newMode Magnification mode 187 * 1 : ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, 188 * 2 : ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW 189 */ onModeSwitch(int displayId, int newMode)190 void onModeSwitch(int displayId, int newMode); 191 192 /** 193 * Called when the visibility of the magnification settings panel changed. 194 * 195 * @param displayId The logical display id. 196 * @param shown The visibility of the magnification settings panel. 197 */ onSettingsPanelVisibilityChanged(int displayId, boolean shown)198 void onSettingsPanelVisibilityChanged(int displayId, boolean shown); 199 } 200 201 @VisibleForTesting 202 final WindowMagnificationSettingsCallback mWindowMagnificationSettingsCallback = 203 new WindowMagnificationSettingsCallback() { 204 @Override 205 public void onSetDiagonalScrolling(boolean enable) { 206 mSettingsControllerCallback.onSetDiagonalScrolling(mDisplayId, enable); 207 } 208 209 @Override 210 public void onModeSwitch(int newMode) { 211 mSettingsControllerCallback.onModeSwitch(mDisplayId, newMode); 212 } 213 214 @Override 215 public void onSettingsPanelVisibilityChanged(boolean shown) { 216 mSettingsControllerCallback.onSettingsPanelVisibilityChanged(mDisplayId, shown); 217 } 218 219 @Override 220 public void onSetMagnifierSize(@MagnificationSize int index) { 221 mSettingsControllerCallback.onSetMagnifierSize(mDisplayId, index); 222 } 223 224 @Override 225 public void onEditMagnifierSizeMode(boolean enable) { 226 mSettingsControllerCallback.onEditMagnifierSizeMode(mDisplayId, enable); 227 } 228 229 @Override 230 public void onMagnifierScale(float scale, boolean updatePersistence) { 231 mSettingsControllerCallback.onMagnifierScale(mDisplayId, 232 A11Y_ACTION_SCALE_RANGE.clamp(scale), updatePersistence); 233 } 234 }; 235 } 236