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.systemui.screenshot; 18 19 import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS; 20 21 import android.content.Context; 22 import android.os.Handler; 23 import android.os.Looper; 24 import android.os.Message; 25 import android.util.Log; 26 import android.view.accessibility.AccessibilityManager; 27 28 import javax.inject.Inject; 29 30 /** 31 * Starts a configurable runnable on timeout. Can be cancelled. Used for automatically dismissing 32 * floating overlays. 33 */ 34 public class TimeoutHandler extends Handler { 35 private static final String TAG = "TimeoutHandler"; 36 37 private static final int MESSAGE_CORNER_TIMEOUT = 2; 38 private static final int DEFAULT_TIMEOUT_MILLIS = 6000; 39 40 private final Context mContext; 41 42 private Runnable mOnTimeout; 43 private int mDefaultTimeout = DEFAULT_TIMEOUT_MILLIS; 44 45 @Inject TimeoutHandler(Context context)46 public TimeoutHandler(Context context) { 47 super(Looper.getMainLooper()); 48 mContext = context; 49 mOnTimeout = () -> { 50 }; 51 } 52 setOnTimeoutRunnable(Runnable onTimeout)53 public void setOnTimeoutRunnable(Runnable onTimeout) { 54 mOnTimeout = onTimeout; 55 } 56 57 @Override handleMessage(Message msg)58 public void handleMessage(Message msg) { 59 switch (msg.what) { 60 case MESSAGE_CORNER_TIMEOUT: 61 mOnTimeout.run(); 62 break; 63 default: 64 break; 65 } 66 } 67 68 /** 69 * Set the default timeout (if not overridden by accessibility) 70 */ setDefaultTimeoutMillis(int timeout)71 public void setDefaultTimeoutMillis(int timeout) { 72 mDefaultTimeout = timeout; 73 } 74 getDefaultTimeoutMillis()75 int getDefaultTimeoutMillis() { 76 return mDefaultTimeout; 77 } 78 79 /** 80 * Cancel the current timeout, if any. To reset the delayed runnable use resetTimeout instead. 81 */ cancelTimeout()82 public void cancelTimeout() { 83 if (DEBUG_DISMISS) { 84 Log.d(TAG, "cancel timeout"); 85 } 86 removeMessages(MESSAGE_CORNER_TIMEOUT); 87 } 88 89 /** 90 * Reset the timeout. 91 */ resetTimeout()92 public void resetTimeout() { 93 cancelTimeout(); 94 95 AccessibilityManager accessibilityManager = (AccessibilityManager) 96 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 97 long timeoutMs = accessibilityManager.getRecommendedTimeoutMillis( 98 mDefaultTimeout, 99 AccessibilityManager.FLAG_CONTENT_CONTROLS); 100 101 sendMessageDelayed(obtainMessage(MESSAGE_CORNER_TIMEOUT), timeoutMs); 102 if (DEBUG_DISMISS) { 103 Log.d(TAG, "dismiss timeout: " + timeoutMs + " ms"); 104 } 105 } 106 } 107