• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.tv.ui.hideable;
2 
3 import android.content.Context;
4 import android.os.Looper;
5 import android.os.Message;
6 import android.support.annotation.NonNull;
7 import android.support.annotation.UiThread;
8 import android.support.annotation.VisibleForTesting;
9 import android.view.accessibility.AccessibilityManager;
10 import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
11 import com.android.tv.common.WeakHandler;
12 
13 /**
14  * Schedules a view element to be hidden after a delay.
15  *
16  * <p>When accessibility is turned on elements are not automatically hidden.
17  *
18  * <p>Users of this class must pass it to {@link
19  * AccessibilityManager#addAccessibilityStateChangeListener(AccessibilityStateChangeListener)} and
20  * {@link
21  * AccessibilityManager#removeAccessibilityStateChangeListener(AccessibilityStateChangeListener)}
22  * during the appropriate live cycle event, or handle calling {@link
23  * #onAccessibilityStateChanged(boolean)}.
24  */
25 @UiThread
26 public final class AutoHideScheduler implements AccessibilityStateChangeListener {
27     private static final int MSG_HIDE = 1;
28 
29     private final HideHandler mHandler;
30     private final Runnable mRunnable;
31 
AutoHideScheduler(Context context, Runnable runnable)32     public AutoHideScheduler(Context context, Runnable runnable) {
33         this(
34                 runnable,
35                 context.getSystemService(AccessibilityManager.class),
36                 Looper.getMainLooper());
37     }
38 
39     @VisibleForTesting
AutoHideScheduler(Runnable runnable, AccessibilityManager accessibilityManager, Looper looper)40     AutoHideScheduler(Runnable runnable, AccessibilityManager accessibilityManager, Looper looper) {
41         // Keep a reference here because HideHandler only has a weak reference to it.
42         mRunnable = runnable;
43         mHandler = new HideHandler(looper, mRunnable);
44         mHandler.setAllowAutoHide(!accessibilityManager.isEnabled());
45     }
46 
cancel()47     public void cancel() {
48         mHandler.removeMessages(MSG_HIDE);
49     }
50 
schedule(long delayMs)51     public void schedule(long delayMs) {
52         cancel();
53         if (mHandler.mAllowAutoHide) {
54             mHandler.sendEmptyMessageDelayed(MSG_HIDE, delayMs);
55         }
56     }
57 
58     @Override
onAccessibilityStateChanged(boolean enabled)59     public void onAccessibilityStateChanged(boolean enabled) {
60         mHandler.onAccessibilityStateChanged(enabled);
61     }
62 
isScheduled()63     public boolean isScheduled() {
64         return mHandler.hasMessages(MSG_HIDE);
65     }
66 
67     private static class HideHandler extends WeakHandler<Runnable>
68             implements AccessibilityStateChangeListener {
69 
70         private boolean mAllowAutoHide;
71 
HideHandler(Looper looper, Runnable hideRunner)72         public HideHandler(Looper looper, Runnable hideRunner) {
73             super(looper, hideRunner);
74         }
75 
76         @Override
handleMessage(Message msg, @NonNull Runnable runnable)77         protected void handleMessage(Message msg, @NonNull Runnable runnable) {
78             switch (msg.what) {
79                 case MSG_HIDE:
80                     if (mAllowAutoHide) {
81                         runnable.run();
82                     }
83                     break;
84                 default:
85                     // do nothing
86             }
87         }
88 
setAllowAutoHide(boolean mAllowAutoHide)89         public void setAllowAutoHide(boolean mAllowAutoHide) {
90             this.mAllowAutoHide = mAllowAutoHide;
91         }
92 
93         @Override
onAccessibilityStateChanged(boolean enabled)94         public void onAccessibilityStateChanged(boolean enabled) {
95             mAllowAutoHide = !enabled;
96         }
97     }
98 }
99