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