1 /*
2  * Copyright (C) 2021 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 package com.android.settings.accessibility;
17 
18 import static com.android.settings.core.SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE;
19 
20 import android.app.settings.SettingsEnums;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.view.View;
24 import android.widget.LinearLayout;
25 import android.widget.ScrollView;
26 import android.widget.TextView;
27 
28 import androidx.annotation.IntDef;
29 import androidx.annotation.VisibleForTesting;
30 import androidx.preference.PreferenceFragmentCompat;
31 
32 import com.android.settings.R;
33 import com.android.settings.core.InstrumentedActivity;
34 import com.android.settings.display.FontSizePreferenceFragmentForSetupWizard;
35 import com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard;
36 import com.android.settingslib.transition.SettingsTransitionHelper.TransitionType;
37 
38 import com.google.android.setupcompat.template.FooterBarMixin;
39 import com.google.android.setupcompat.template.FooterButton;
40 import com.google.android.setupdesign.GlifLayout;
41 import com.google.android.setupdesign.util.ThemeHelper;
42 
43 import java.lang.annotation.Retention;
44 import java.lang.annotation.RetentionPolicy;
45 
46 /** Settings font/display size activity for SUW. */
47 public class AccessibilityScreenSizeForSetupWizardActivity extends InstrumentedActivity {
48     private static final String TAG = "ScreenSizeForSetup";
49 
50     // A parameter decides which fragment ({@link FontSizePreferenceFragmentForSetupWizard} or
51     // {@link ScreenZoomPreferenceFragmentForSetupWizard}) will be visioned.
52     static final String VISION_FRAGMENT_NO = "vision_fragment_no";
53     /**
54      * Flags indicating the type of the fragment.
55      */
56     @IntDef({
57         FragmentType.FONT_SIZE,
58         FragmentType.SCREEN_SIZE,
59     })
60     @Retention(RetentionPolicy.SOURCE)
61     public @interface FragmentType {
62         int FONT_SIZE = 1;
63         int SCREEN_SIZE = 2;
64     }
65 
66     // Keep the last height of the scroll view in the {@link GlifLayout}
67     private int mLastScrollViewHeight;
68 
69     @Override
onCreate(Bundle savedInstanceState)70     protected void onCreate(Bundle savedInstanceState) {
71         super.onCreate(savedInstanceState);
72         final int appliedTheme = ThemeHelper.trySetDynamicColor(this)
73                 ? R.style.SudDynamicColorThemeGlifV3_DayNight : R.style.SudThemeGlifV3_DayNight;
74         setTheme(appliedTheme);
75         setContentView(R.layout.accessibility_screen_size_setup_wizard);
76         updateHeaderLayout();
77         scrollToBottom();
78         initFooterButton();
79         if (savedInstanceState == null) {
80             final PreferenceFragmentCompat fragment =
81                     getFragmentType(getIntent()) == FragmentType.FONT_SIZE
82                             ? new FontSizePreferenceFragmentForSetupWizard()
83                             : new ScreenZoomPreferenceFragmentForSetupWizard();
84             getSupportFragmentManager()
85                     .beginTransaction()
86                     .replace(R.id.content_frame, fragment)
87                     .commit();
88         }
89     }
90 
91     @Override
onPause()92     protected void onPause() {
93         // For accessibility activities launched from setup wizard.
94         if (getTransitionType(getIntent()) == TransitionType.TRANSITION_FADE) {
95             overridePendingTransition(R.anim.sud_stay, android.R.anim.fade_out);
96         }
97         super.onPause();
98     }
99 
100     @Override
getMetricsCategory()101     public int getMetricsCategory() {
102         return getFragmentType(getIntent()) == FragmentType.FONT_SIZE
103                 ? SettingsEnums.SUW_ACCESSIBILITY_FONT_SIZE
104                 : SettingsEnums.SUW_ACCESSIBILITY_DISPLAY_SIZE;
105     }
106 
107     @VisibleForTesting
updateHeaderLayout()108     void updateHeaderLayout() {
109         if (ThemeHelper.shouldApplyExtendedPartnerConfig(this) && isSuwSupportedTwoPanes()) {
110             final GlifLayout layout = findViewById(R.id.setup_wizard_layout);
111             final LinearLayout headerLayout = layout.findManagedViewById(R.id.sud_layout_header);
112             if (headerLayout != null) {
113                 headerLayout.setPadding(0, layout.getPaddingTop(), 0,
114                         layout.getPaddingBottom());
115             }
116         }
117         ((TextView) findViewById(R.id.suc_layout_title)).setText(
118                 getFragmentType(getIntent()) == FragmentType.FONT_SIZE
119                         ? R.string.title_font_size
120                         : R.string.screen_zoom_title);
121         ((TextView) findViewById(R.id.sud_layout_subtitle)).setText(
122                 getFragmentType(getIntent()) == FragmentType.FONT_SIZE
123                         ? R.string.font_size_summary
124                         : R.string.screen_zoom_summary);
125     }
126 
isSuwSupportedTwoPanes()127     private boolean isSuwSupportedTwoPanes() {
128         return getResources().getBoolean(R.bool.config_suw_supported_two_panes);
129     }
130 
initFooterButton()131     private void initFooterButton() {
132         final GlifLayout layout = findViewById(R.id.setup_wizard_layout);
133         final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
134         final View.OnClickListener nextButtonListener = v -> onBackPressed();
135         final FooterButton primaryButton =
136                 new FooterButton.Builder(this)
137                         .setText(R.string.done)
138                         .setListener(nextButtonListener)
139                         .setButtonType(FooterButton.ButtonType.NEXT)
140                         .setTheme(R.style.SudGlifButton_Primary)
141                         .build();
142         mixin.setPrimaryButton(primaryButton);
143     }
144 
145     /**
146      * Scrolls to bottom while {@link ScrollView} layout changed.
147      */
scrollToBottom()148     private void scrollToBottom() {
149         mLastScrollViewHeight = 0;
150         final GlifLayout layout = findViewById(R.id.setup_wizard_layout);
151         final ScrollView scrollView = layout.getScrollView();
152         scrollView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
153             final int scrollViewHeight = scrollView.getHeight();
154             if (scrollViewHeight > 0 && scrollViewHeight != mLastScrollViewHeight) {
155                 mLastScrollViewHeight = scrollViewHeight;
156                 scrollView.post(() -> {
157                     // Here is no need to show the scrolling animation. So disabled first and
158                     // then enabled it after scrolling finished.
159                     scrollView.setSmoothScrollingEnabled(false);
160                     scrollView.fullScroll(View.FOCUS_DOWN);
161                     scrollView.setSmoothScrollingEnabled(true);
162                 });
163             }
164         });
165     }
166 
getTransitionType(Intent intent)167     private int getTransitionType(Intent intent) {
168         return intent.getIntExtra(EXTRA_PAGE_TRANSITION_TYPE, TransitionType.TRANSITION_NONE);
169     }
170 
getFragmentType(Intent intent)171     private int getFragmentType(Intent intent) {
172         return intent.getIntExtra(VISION_FRAGMENT_NO, FragmentType.FONT_SIZE);
173     }
174 }
175