1 /* 2 * Copyright (C) 2019 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.systemui.volume; 18 19 import android.content.Context; 20 import android.os.Handler; 21 import android.util.AttributeSet; 22 import android.view.GestureDetector; 23 import android.view.MotionEvent; 24 25 import androidx.core.view.ViewCompat; 26 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; 27 28 import com.android.keyguard.AlphaOptimizedImageButton; 29 import com.android.systemui.R; 30 31 /** Toggle button in Volume Dialog that allows extra state for when streams are opted-out */ 32 public class CaptionsToggleImageButton extends AlphaOptimizedImageButton { 33 34 private static final int[] OPTED_OUT_STATE = new int[] { R.attr.optedOut }; 35 36 private ConfirmedTapListener mConfirmedTapListener; 37 private boolean mCaptionsEnabled = false; 38 private boolean mOptedOut = false; 39 40 private GestureDetector mGestureDetector; 41 private GestureDetector.SimpleOnGestureListener mGestureListener = 42 new GestureDetector.SimpleOnGestureListener() { 43 @Override 44 public boolean onSingleTapConfirmed(MotionEvent e) { 45 return tryToSendTapConfirmedEvent(); 46 } 47 }; 48 CaptionsToggleImageButton(Context context, AttributeSet attrs)49 public CaptionsToggleImageButton(Context context, AttributeSet attrs) { 50 super(context, attrs); 51 this.setContentDescription( 52 getContext().getString(R.string.volume_odi_captions_content_description)); 53 } 54 55 @Override onTouchEvent(MotionEvent event)56 public boolean onTouchEvent(MotionEvent event) { 57 if (mGestureDetector != null) mGestureDetector.onTouchEvent(event); 58 return super.onTouchEvent(event); 59 } 60 61 @Override onCreateDrawableState(int extraSpace)62 public int[] onCreateDrawableState(int extraSpace) { 63 int[] state = super.onCreateDrawableState(extraSpace + 1); 64 if (mOptedOut) { 65 mergeDrawableStates(state, OPTED_OUT_STATE); 66 } 67 return state; 68 } 69 setCaptionsEnabled(boolean areCaptionsEnabled)70 Runnable setCaptionsEnabled(boolean areCaptionsEnabled) { 71 this.mCaptionsEnabled = areCaptionsEnabled; 72 73 ViewCompat.replaceAccessibilityAction( 74 this, 75 AccessibilityActionCompat.ACTION_CLICK, 76 mCaptionsEnabled 77 ? getContext().getString(R.string.volume_odi_captions_hint_disable) 78 : getContext().getString(R.string.volume_odi_captions_hint_enable), 79 (view, commandArguments) -> tryToSendTapConfirmedEvent()); 80 81 return this.setImageResourceAsync(mCaptionsEnabled 82 ? R.drawable.ic_volume_odi_captions 83 : R.drawable.ic_volume_odi_captions_disabled); 84 } 85 tryToSendTapConfirmedEvent()86 private boolean tryToSendTapConfirmedEvent() { 87 if (mConfirmedTapListener != null) { 88 mConfirmedTapListener.onConfirmedTap(); 89 return true; 90 } 91 return false; 92 } 93 getCaptionsEnabled()94 boolean getCaptionsEnabled() { 95 return this.mCaptionsEnabled; 96 } 97 98 /** Sets whether or not the current stream has opted out of captions */ setOptedOut(boolean isOptedOut)99 void setOptedOut(boolean isOptedOut) { 100 this.mOptedOut = isOptedOut; 101 refreshDrawableState(); 102 } 103 getOptedOut()104 boolean getOptedOut() { 105 return this.mOptedOut; 106 } 107 setOnConfirmedTapListener(ConfirmedTapListener listener, Handler handler)108 void setOnConfirmedTapListener(ConfirmedTapListener listener, Handler handler) { 109 mConfirmedTapListener = listener; 110 111 if (mGestureDetector == null) { 112 this.mGestureDetector = new GestureDetector(getContext(), mGestureListener, handler); 113 } 114 } 115 116 /** Listener for confirmed taps rather than normal on click listener. */ 117 interface ConfirmedTapListener { onConfirmedTap()118 void onConfirmedTap(); 119 } 120 } 121