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.systemui.accessibility; 18 19 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; 20 21 import static com.android.systemui.accessibility.MagnificationModeSwitch.ClickListener; 22 23 import android.annotation.MainThread; 24 import android.content.Context; 25 import android.hardware.display.DisplayManager; 26 import android.view.Display; 27 28 import com.android.internal.annotations.VisibleForTesting; 29 import com.android.systemui.dagger.SysUISingleton; 30 31 import javax.inject.Inject; 32 33 /** 34 * A class to control {@link MagnificationModeSwitch}. It shows the button UI with following 35 * conditions: 36 * <ol> 37 * <li> Both full-screen and window magnification mode are capable.</li> 38 * <li> The magnification scale is changed by a user.</li> 39 * <ol> 40 * The click action will be handled by {@link #mClickListenerDelegate} which opens the 41 * {@link WindowMagnificationSettings} panel. 42 */ 43 @SysUISingleton 44 public class ModeSwitchesController implements ClickListener { 45 46 private final DisplayIdIndexSupplier<MagnificationModeSwitch> mSwitchSupplier; 47 private ClickListener mClickListenerDelegate; 48 49 @Inject ModeSwitchesController(Context context, DisplayManager displayManager)50 public ModeSwitchesController(Context context, DisplayManager displayManager) { 51 mSwitchSupplier = new SwitchSupplier(context, displayManager, this::onClick); 52 } 53 54 @VisibleForTesting ModeSwitchesController(DisplayIdIndexSupplier<MagnificationModeSwitch> switchSupplier)55 ModeSwitchesController(DisplayIdIndexSupplier<MagnificationModeSwitch> switchSupplier) { 56 mSwitchSupplier = switchSupplier; 57 } 58 59 /** 60 * Shows a button that a user can click to switch magnification mode. And the button 61 * would be dismissed automatically after the button is displayed for a period of time. 62 * 63 * @param displayId The logical display id 64 * @param mode The magnification mode 65 * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW 66 * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN 67 */ 68 @MainThread showButton(int displayId, int mode)69 void showButton(int displayId, int mode) { 70 final MagnificationModeSwitch magnificationModeSwitch = 71 mSwitchSupplier.get(displayId); 72 if (magnificationModeSwitch == null) { 73 return; 74 } 75 magnificationModeSwitch.showButton(mode); 76 } 77 78 /** 79 * Removes magnification mode switch button immediately. 80 * 81 * @param displayId The logical display id 82 */ removeButton(int displayId)83 void removeButton(int displayId) { 84 final MagnificationModeSwitch magnificationModeSwitch = 85 mSwitchSupplier.get(displayId); 86 if (magnificationModeSwitch == null) { 87 return; 88 } 89 magnificationModeSwitch.removeButton(); 90 } 91 92 /** 93 * Called when the configuration has changed, and it updates magnification button UI. 94 * 95 * @param configDiff a bit mask of the differences between the configurations 96 */ 97 @MainThread onConfigurationChanged(int configDiff)98 void onConfigurationChanged(int configDiff) { 99 mSwitchSupplier.forEach( 100 switchController -> switchController.onConfigurationChanged(configDiff)); 101 } 102 103 @Override onClick(int displayId)104 public void onClick(int displayId) { 105 if (mClickListenerDelegate != null) { 106 mClickListenerDelegate.onClick(displayId); 107 } 108 } 109 setClickListenerDelegate(ClickListener clickListenerDelegate)110 public void setClickListenerDelegate(ClickListener clickListenerDelegate) { 111 mClickListenerDelegate = clickListenerDelegate; 112 } 113 114 private static class SwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> { 115 116 private final Context mContext; 117 private final ClickListener mClickListener; 118 119 /** 120 * Supplies the switch for the given display. 121 * 122 * @param context Context 123 * @param displayManager DisplayManager 124 * @param clickListener The callback that will run when the switch is clicked 125 */ SwitchSupplier(Context context, DisplayManager displayManager, ClickListener clickListener)126 SwitchSupplier(Context context, DisplayManager displayManager, 127 ClickListener clickListener) { 128 super(displayManager); 129 mContext = context; 130 mClickListener = clickListener; 131 } 132 133 @Override createInstance(Display display)134 protected MagnificationModeSwitch createInstance(Display display) { 135 final Context uiContext = mContext.createWindowContext(display, 136 TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null); 137 return new MagnificationModeSwitch(uiContext, mClickListener); 138 } 139 } 140 } 141