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 android.annotation.IdRes; 20 import android.app.TaskInfo; 21 import android.app.TaskInfo.CameraCompatControlState; 22 import android.content.Context; 23 import android.util.AttributeSet; 24 import android.view.MotionEvent; 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 == TaskInfo.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 == TaskInfo.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 onInterceptTouchEvent(MotionEvent ev)116 public boolean onInterceptTouchEvent(MotionEvent ev) { 117 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 118 mWindowManager.relayout(); 119 } 120 return super.onInterceptTouchEvent(ev); 121 } 122 123 @Override onFinishInflate()124 protected void onFinishInflate() { 125 super.onFinishInflate(); 126 127 final ImageButton restartButton = findViewById(R.id.size_compat_restart_button); 128 restartButton.setOnClickListener(view -> mWindowManager.onRestartButtonClicked()); 129 restartButton.setOnLongClickListener(view -> { 130 mWindowManager.onRestartButtonLongClicked(); 131 return true; 132 }); 133 134 final LinearLayout sizeCompatHint = findViewById(R.id.size_compat_hint); 135 ((TextView) sizeCompatHint.findViewById(R.id.compat_mode_hint_text)) 136 .setText(R.string.restart_button_description); 137 sizeCompatHint.setOnClickListener(view -> setSizeCompatHintVisibility(/* show= */ false)); 138 139 final ImageButton cameraTreatmentButton = 140 findViewById(R.id.camera_compat_treatment_button); 141 cameraTreatmentButton.setOnClickListener( 142 view -> mWindowManager.onCameraTreatmentButtonClicked()); 143 cameraTreatmentButton.setOnLongClickListener(view -> { 144 mWindowManager.onCameraButtonLongClicked(); 145 return true; 146 }); 147 148 final ImageButton cameraDismissButton = findViewById(R.id.camera_compat_dismiss_button); 149 cameraDismissButton.setOnClickListener( 150 view -> mWindowManager.onCameraDismissButtonClicked()); 151 cameraDismissButton.setOnLongClickListener(view -> { 152 mWindowManager.onCameraButtonLongClicked(); 153 return true; 154 }); 155 156 final LinearLayout cameraCompatHint = findViewById(R.id.camera_compat_hint); 157 cameraCompatHint.setOnClickListener( 158 view -> setCameraCompatHintVisibility(/* show= */ false)); 159 } 160 } 161