• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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