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 
17 package com.android.wm.shell.compatui;
18 
19 import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
20 
21 import android.annotation.IdRes;
22 import android.app.CameraCompatTaskInfo.CameraCompatControlState;
23 import android.content.Context;
24 import android.util.AttributeSet;
25 import android.view.View;
26 import android.widget.ImageButton;
27 import android.widget.LinearLayout;
28 import android.widget.TextView;
29 
30 import com.android.wm.shell.R;
31 
32 /**
33  * Container for compat UI controls.
34  */
35 class CompatUILayout extends LinearLayout {
36 
37     private CompatUIWindowManager mWindowManager;
38 
CompatUILayout(Context context)39     public CompatUILayout(Context context) {
40         this(context, null);
41     }
42 
CompatUILayout(Context context, AttributeSet attrs)43     public CompatUILayout(Context context, AttributeSet attrs) {
44         this(context, attrs, 0);
45     }
46 
CompatUILayout(Context context, AttributeSet attrs, int defStyleAttr)47     public CompatUILayout(Context context, AttributeSet attrs, int defStyleAttr) {
48         this(context, attrs, defStyleAttr, 0);
49     }
50 
CompatUILayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)51     public CompatUILayout(Context context, AttributeSet attrs, int defStyleAttr,
52             int defStyleRes) {
53         super(context, attrs, defStyleAttr, defStyleRes);
54     }
55 
inject(CompatUIWindowManager windowManager)56     void inject(CompatUIWindowManager windowManager) {
57         mWindowManager = windowManager;
58     }
59 
updateCameraTreatmentButton(@ameraCompatControlState int newState)60     void updateCameraTreatmentButton(@CameraCompatControlState int newState) {
61         int buttonBkgId = newState == CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED
62                 ? R.drawable.camera_compat_treatment_suggested_ripple
63                 : R.drawable.camera_compat_treatment_applied_ripple;
64         int hintStringId = newState == CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED
65                 ? R.string.camera_compat_treatment_suggested_button_description
66                 : R.string.camera_compat_treatment_applied_button_description;
67         final ImageButton button = findViewById(R.id.camera_compat_treatment_button);
68         button.setImageResource(buttonBkgId);
69         button.setContentDescription(getResources().getString(hintStringId));
70         final LinearLayout hint = findViewById(R.id.camera_compat_hint);
71         ((TextView) hint.findViewById(R.id.compat_mode_hint_text)).setText(hintStringId);
72     }
73 
setSizeCompatHintVisibility(boolean show)74     void setSizeCompatHintVisibility(boolean show) {
75         setViewVisibility(R.id.size_compat_hint, show);
76     }
77 
setCameraCompatHintVisibility(boolean show)78     void setCameraCompatHintVisibility(boolean show) {
79         setViewVisibility(R.id.camera_compat_hint, show);
80     }
81 
setRestartButtonVisibility(boolean show)82     void setRestartButtonVisibility(boolean show) {
83         setViewVisibility(R.id.size_compat_restart_button, show);
84         // Hint should never be visible without button.
85         if (!show) {
86             setSizeCompatHintVisibility(/* show= */ false);
87         }
88     }
89 
setCameraControlVisibility(boolean show)90     void setCameraControlVisibility(boolean show) {
91         setViewVisibility(R.id.camera_compat_control, show);
92         // Hint should never be visible without button.
93         if (!show) {
94             setCameraCompatHintVisibility(/* show= */ false);
95         }
96     }
97 
setViewVisibility(@dRes int resId, boolean show)98     private void setViewVisibility(@IdRes int resId, boolean show) {
99         final View view = findViewById(resId);
100         int visibility = show ? View.VISIBLE : View.GONE;
101         if (view.getVisibility() == visibility) {
102             return;
103         }
104         view.setVisibility(visibility);
105     }
106 
107     @Override
onLayout(boolean changed, int left, int top, int right, int bottom)108     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
109         super.onLayout(changed, left, top, right, bottom);
110         // Need to relayout after changes like hiding / showing a hint since they affect size.
111         // Doing this directly in setSizeCompatHintVisibility can result in flaky animation.
112         mWindowManager.relayout();
113     }
114 
115     @Override
onFinishInflate()116     protected void onFinishInflate() {
117         super.onFinishInflate();
118 
119         final ImageButton restartButton = findViewById(R.id.size_compat_restart_button);
120         restartButton.setOnClickListener(view -> mWindowManager.onRestartButtonClicked());
121         restartButton.setOnLongClickListener(view -> {
122             mWindowManager.onRestartButtonLongClicked();
123             return true;
124         });
125 
126         final LinearLayout sizeCompatHint = findViewById(R.id.size_compat_hint);
127         ((TextView) sizeCompatHint.findViewById(R.id.compat_mode_hint_text))
128                 .setText(R.string.restart_button_description);
129         sizeCompatHint.setOnClickListener(view -> setSizeCompatHintVisibility(/* show= */ false));
130 
131         final ImageButton cameraTreatmentButton =
132                 findViewById(R.id.camera_compat_treatment_button);
133         cameraTreatmentButton.setOnClickListener(
134                 view -> mWindowManager.onCameraTreatmentButtonClicked());
135         cameraTreatmentButton.setOnLongClickListener(view -> {
136             mWindowManager.onCameraButtonLongClicked();
137             return true;
138         });
139 
140         final ImageButton cameraDismissButton = findViewById(R.id.camera_compat_dismiss_button);
141         cameraDismissButton.setOnClickListener(
142                 view -> mWindowManager.onCameraDismissButtonClicked());
143         cameraDismissButton.setOnLongClickListener(view -> {
144             mWindowManager.onCameraButtonLongClicked();
145             return true;
146         });
147 
148         final LinearLayout cameraCompatHint = findViewById(R.id.camera_compat_hint);
149         cameraCompatHint.setOnClickListener(
150                 view -> setCameraCompatHintVisibility(/* show= */ false));
151     }
152 }
153