1 /* 2 * Copyright (C) 2013 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.settings.accessibility; 18 19 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; 20 21 import android.app.Dialog; 22 import android.app.settings.SettingsEnums; 23 import android.content.ContentResolver; 24 import android.content.Context; 25 import android.content.res.Resources; 26 import android.graphics.Point; 27 import android.media.AudioManager; 28 import android.media.MediaPlayer; 29 import android.media.MediaPlayer.OnPreparedListener; 30 import android.net.Uri; 31 import android.os.Bundle; 32 import android.provider.Settings; 33 import android.text.TextUtils; 34 import android.view.Display; 35 import android.view.ViewTreeObserver.OnGlobalLayoutListener; 36 import android.view.WindowManager; 37 import android.widget.ImageView; 38 import android.widget.RelativeLayout.LayoutParams; 39 import android.widget.Switch; 40 import android.widget.VideoView; 41 42 import androidx.preference.Preference; 43 import androidx.preference.PreferenceScreen; 44 import androidx.preference.PreferenceViewHolder; 45 46 import com.android.settings.R; 47 import com.android.settings.widget.SwitchBar; 48 49 public class ToggleScreenMagnificationPreferenceFragment extends 50 ToggleFeaturePreferenceFragment implements SwitchBar.OnSwitchChangeListener { 51 52 private static final int DIALOG_ID_GESTURE_NAVIGATION_TUTORIAL = 1; 53 54 private Dialog mDialog; 55 56 protected class VideoPreference extends Preference { 57 private ImageView mVideoBackgroundView; 58 private OnGlobalLayoutListener mLayoutListener; 59 VideoPreference(Context context)60 public VideoPreference(Context context) { 61 super(context); 62 } 63 64 @Override onBindViewHolder(PreferenceViewHolder view)65 public void onBindViewHolder(PreferenceViewHolder view) { 66 super.onBindViewHolder(view); 67 Resources res = getPrefContext().getResources(); 68 final int backgroundAssetWidth = res.getDimensionPixelSize( 69 R.dimen.screen_magnification_video_background_width); 70 final int videoAssetWidth = res 71 .getDimensionPixelSize(R.dimen.screen_magnification_video_width); 72 final int videoAssetHeight = res 73 .getDimensionPixelSize(R.dimen.screen_magnification_video_height); 74 final int videoAssetMarginTop = res.getDimensionPixelSize( 75 R.dimen.screen_magnification_video_margin_top); 76 view.setDividerAllowedAbove(false); 77 view.setDividerAllowedBelow(false); 78 mVideoBackgroundView = (ImageView) view.findViewById(R.id.video_background); 79 final VideoView videoView = (VideoView) view.findViewById(R.id.video); 80 81 // Loop the video. 82 videoView.setOnPreparedListener(new OnPreparedListener() { 83 @Override 84 public void onPrepared(MediaPlayer mediaPlayer) { 85 mediaPlayer.setLooping(true); 86 } 87 }); 88 89 // Make sure the VideoView does not request audio focus. 90 videoView.setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE); 91 92 // Resolve and set the video content 93 Bundle args = getArguments(); 94 if ((args != null) && args.containsKey( 95 AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID)) { 96 videoView.setVideoURI(Uri.parse(String.format("%s://%s/%s", 97 ContentResolver.SCHEME_ANDROID_RESOURCE, 98 getPrefContext().getPackageName(), 99 args.getInt(AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID)))); 100 } 101 102 // Make sure video controls (e.g. for pausing) are not displayed. 103 videoView.setMediaController(null); 104 105 // LayoutListener for adjusting the position of the VideoView on the background image. 106 mLayoutListener = new OnGlobalLayoutListener() { 107 @Override 108 public void onGlobalLayout() { 109 final int backgroundViewWidth = mVideoBackgroundView.getWidth(); 110 111 LayoutParams videoLp = (LayoutParams) videoView.getLayoutParams(); 112 videoLp.width = videoAssetWidth * backgroundViewWidth / backgroundAssetWidth; 113 videoLp.height = videoAssetHeight * backgroundViewWidth / backgroundAssetWidth; 114 videoLp.setMargins(0, 115 videoAssetMarginTop * backgroundViewWidth / backgroundAssetWidth, 0, 0); 116 videoView.setLayoutParams(videoLp); 117 videoView.invalidate(); 118 videoView.start(); 119 } 120 }; 121 122 mVideoBackgroundView.getViewTreeObserver().addOnGlobalLayoutListener(mLayoutListener); 123 } 124 125 @Override onPrepareForRemoval()126 protected void onPrepareForRemoval() { 127 mVideoBackgroundView.getViewTreeObserver() 128 .removeOnGlobalLayoutListener(mLayoutListener); 129 } 130 } 131 132 protected VideoPreference mVideoPreference; 133 protected Preference mConfigWarningPreference; 134 135 private boolean mLaunchFromSuw = false; 136 private boolean mInitialSetting = false; 137 138 @Override onCreate(Bundle savedInstanceState)139 public void onCreate(Bundle savedInstanceState) { 140 super.onCreate(savedInstanceState); 141 142 mVideoPreference = new VideoPreference(getPrefContext()); 143 mVideoPreference.setSelectable(false); 144 mVideoPreference.setPersistent(false); 145 mVideoPreference.setLayoutResource(R.layout.magnification_video_preference); 146 147 mConfigWarningPreference = new Preference(getPrefContext()); 148 mConfigWarningPreference.setSelectable(false); 149 mConfigWarningPreference.setPersistent(false); 150 mConfigWarningPreference.setVisible(false); 151 mConfigWarningPreference.setIcon(R.drawable.ic_warning_24dp); 152 153 final PreferenceScreen preferenceScreen = getPreferenceManager().getPreferenceScreen(); 154 preferenceScreen.setOrderingAsAdded(false); 155 mVideoPreference.setOrder(0); 156 mConfigWarningPreference.setOrder(2); 157 preferenceScreen.addPreference(mVideoPreference); 158 preferenceScreen.addPreference(mConfigWarningPreference); 159 } 160 161 @Override onResume()162 public void onResume() { 163 super.onResume(); 164 165 VideoView videoView = (VideoView) getView().findViewById(R.id.video); 166 if (videoView != null) { 167 videoView.start(); 168 } 169 170 updateConfigurationWarningIfNeeded(); 171 } 172 173 @Override onCreateDialog(int dialogId)174 public Dialog onCreateDialog(int dialogId) { 175 if (dialogId == DIALOG_ID_GESTURE_NAVIGATION_TUTORIAL) { 176 if (isGestureNavigateEnabled()) { 177 mDialog = AccessibilityGestureNavigationTutorial 178 .showGestureNavigationTutorialDialog(getActivity()); 179 } else { 180 mDialog = AccessibilityGestureNavigationTutorial 181 .showAccessibilityButtonTutorialDialog(getActivity()); 182 } 183 } 184 185 return mDialog; 186 } 187 188 @Override getMetricsCategory()189 public int getMetricsCategory() { 190 // TODO: Distinguish between magnification modes 191 return SettingsEnums.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION; 192 } 193 194 @Override getDialogMetricsCategory(int dialogId)195 public int getDialogMetricsCategory(int dialogId) { 196 return SettingsEnums.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION; 197 } 198 199 @Override onSwitchChanged(Switch switchView, boolean isChecked)200 public void onSwitchChanged(Switch switchView, boolean isChecked) { 201 onPreferenceToggled(mPreferenceKey, isChecked); 202 } 203 204 @Override onPreferenceToggled(String preferenceKey, boolean enabled)205 protected void onPreferenceToggled(String preferenceKey, boolean enabled) { 206 if (enabled && TextUtils.equals( 207 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 208 preferenceKey)) { 209 showDialog(DIALOG_ID_GESTURE_NAVIGATION_TUTORIAL); 210 } 211 MagnificationPreferenceFragment.setChecked(getContentResolver(), preferenceKey, enabled); 212 updateConfigurationWarningIfNeeded(); 213 } 214 215 @Override onInstallSwitchBarToggleSwitch()216 protected void onInstallSwitchBarToggleSwitch() { 217 super.onInstallSwitchBarToggleSwitch(); 218 219 mSwitchBar.setCheckedInternal( 220 MagnificationPreferenceFragment.isChecked(getContentResolver(), mPreferenceKey)); 221 mSwitchBar.addOnSwitchChangeListener(this); 222 } 223 224 @Override onRemoveSwitchBarToggleSwitch()225 protected void onRemoveSwitchBarToggleSwitch() { 226 super.onRemoveSwitchBarToggleSwitch(); 227 mSwitchBar.removeOnSwitchChangeListener(this); 228 } 229 230 @Override onProcessArguments(Bundle arguments)231 protected void onProcessArguments(Bundle arguments) { 232 super.onProcessArguments(arguments); 233 if (arguments == null) { 234 return; 235 } 236 237 if (arguments.containsKey(AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID)) { 238 mVideoPreference.setVisible(true); 239 final int resId = arguments.getInt( 240 AccessibilitySettings.EXTRA_VIDEO_RAW_RESOURCE_ID); 241 } else { 242 mVideoPreference.setVisible(false); 243 } 244 245 if (arguments.containsKey(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW)) { 246 mLaunchFromSuw = arguments.getBoolean(AccessibilitySettings.EXTRA_LAUNCHED_FROM_SUW); 247 } 248 249 if (arguments.containsKey(AccessibilitySettings.EXTRA_CHECKED)) { 250 mInitialSetting = arguments.getBoolean(AccessibilitySettings.EXTRA_CHECKED); 251 } 252 253 if (arguments.containsKey(AccessibilitySettings.EXTRA_TITLE_RES)) { 254 final int titleRes = arguments.getInt(AccessibilitySettings.EXTRA_TITLE_RES); 255 if (titleRes > 0) { 256 getActivity().setTitle(titleRes); 257 } 258 } 259 } 260 isGestureNavigateEnabled()261 private boolean isGestureNavigateEnabled() { 262 return getContext().getResources().getInteger( 263 com.android.internal.R.integer.config_navBarInteractionMode) 264 == NAV_BAR_MODE_GESTURAL; 265 } 266 updateConfigurationWarningIfNeeded()267 private void updateConfigurationWarningIfNeeded() { 268 final CharSequence warningMessage = 269 MagnificationPreferenceFragment.getConfigurationWarningStringForSecureSettingsKey( 270 mPreferenceKey, getPrefContext()); 271 if (warningMessage != null) { 272 mConfigWarningPreference.setSummary(warningMessage); 273 } 274 mConfigWarningPreference.setVisible(warningMessage != null); 275 } 276 getScreenWidth(Context context)277 private static int getScreenWidth(Context context) { 278 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 279 Display display = wm.getDefaultDisplay(); 280 Point size = new Point(); 281 display.getSize(size); 282 return size.x; 283 } 284 } 285