1 /*
2  * Copyright (C) 2022 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 android.content.Context;
20 import android.os.Handler;
21 import android.os.Looper;
22 import android.provider.Settings;
23 import android.view.View;
24 import android.view.accessibility.CaptioningManager.CaptionStyle;
25 
26 import androidx.annotation.VisibleForTesting;
27 import androidx.preference.PreferenceScreen;
28 
29 import com.android.internal.widget.SubtitleView;
30 import com.android.settings.R;
31 import com.android.settings.core.BasePreferenceController;
32 import com.android.settingslib.accessibility.AccessibilityUtils;
33 import com.android.settingslib.core.lifecycle.LifecycleObserver;
34 import com.android.settingslib.core.lifecycle.events.OnStart;
35 import com.android.settingslib.core.lifecycle.events.OnStop;
36 import com.android.settingslib.widget.LayoutPreference;
37 
38 import java.util.Arrays;
39 import java.util.List;
40 import java.util.Locale;
41 
42 /** Controller that shows the captioning locale summary. */
43 public class CaptioningPreviewPreferenceController extends BasePreferenceController
44         implements LifecycleObserver, OnStart, OnStop {
45 
46     @VisibleForTesting
47     static final List<String> CAPTIONING_FEATURE_KEYS = Arrays.asList(
48             Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
49             Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
50             Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR,
51             Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
52             Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET,
53             Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
54             Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE,
55             Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE
56     );
57     private final Handler mHandler = new Handler(Looper.getMainLooper());
58     @VisibleForTesting
59     AccessibilitySettingsContentObserver mSettingsContentObserver;
60     private CaptionHelper mCaptionHelper;
61     private LayoutPreference mPreference;
62 
CaptioningPreviewPreferenceController(Context context, String preferenceKey)63     public CaptioningPreviewPreferenceController(Context context, String preferenceKey) {
64         super(context, preferenceKey);
65         mCaptionHelper = new CaptionHelper(context);
66         mSettingsContentObserver = new AccessibilitySettingsContentObserver(mHandler);
67         mSettingsContentObserver.registerKeysToObserverCallback(CAPTIONING_FEATURE_KEYS,
68                 key -> refreshPreviewText());
69     }
70 
71     @Override
onStart()72     public void onStart() {
73         mSettingsContentObserver.register(mContext.getContentResolver());
74     }
75 
76     @Override
onStop()77     public void onStop() {
78         mContext.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
79     }
80 
81     @Override
getAvailabilityStatus()82     public int getAvailabilityStatus() {
83         return AVAILABLE;
84     }
85 
86     @Override
displayPreference(PreferenceScreen screen)87     public void displayPreference(PreferenceScreen screen) {
88         super.displayPreference(screen);
89         mPreference = screen.findPreference(getPreferenceKey());
90         final View previewViewport = mPreference.findViewById(R.id.preview_viewport);
91         previewViewport.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
92             @Override
93             public void onLayoutChange(View v, int left, int top, int right,
94                     int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
95                 if ((oldRight - oldLeft) != (right - left)) {
96                     // Remove the listener once the callback is triggered.
97                     previewViewport.removeOnLayoutChangeListener(this);
98                     mHandler.post(() -> refreshPreviewText());
99                 }
100             }
101         });
102     }
103 
refreshPreviewText()104     private void refreshPreviewText() {
105         final SubtitleView previewText = mPreference.findViewById(R.id.preview_text);
106         if (previewText != null) {
107             final View previewViewport = mPreference.findViewById(R.id.preview_viewport);
108             final int styleId = mCaptionHelper.getRawUserStyle();
109             mCaptionHelper.applyCaptionProperties(previewText, previewViewport, styleId);
110 
111             final Locale locale = mCaptionHelper.getLocale();
112             if (locale != null) {
113                 final CharSequence localizedText = AccessibilityUtils.getTextForLocale(
114                         mContext, locale, R.string.captioning_preview_text);
115                 previewText.setText(localizedText);
116             } else {
117                 previewText.setText(R.string.captioning_preview_text);
118             }
119 
120             final View previewWindow = mPreference.findViewById(R.id.preview_window);
121             final CaptionStyle style = mCaptionHelper.getUserStyle();
122             if (style.hasWindowColor()) {
123                 previewWindow.setBackgroundColor(style.windowColor);
124             } else {
125                 final CaptionStyle defStyle = CaptionStyle.DEFAULT;
126                 previewWindow.setBackgroundColor(defStyle.windowColor);
127             }
128         }
129     }
130 }
131