1 /* 2 * Copyright (C) 2020 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.statusbar.notification.row; 18 19 import android.os.SystemClock; 20 import android.view.MotionEvent; 21 import android.view.View; 22 import android.view.accessibility.AccessibilityManager; 23 24 import com.android.systemui.Gefingerpoken; 25 import com.android.systemui.classifier.FalsingCollector; 26 import com.android.systemui.plugins.FalsingManager; 27 import com.android.systemui.statusbar.phone.NotificationTapHelper; 28 import com.android.systemui.util.ViewController; 29 30 import javax.inject.Inject; 31 32 /** 33 * Controller for {@link ActivatableNotificationView} 34 */ 35 public class ActivatableNotificationViewController 36 extends ViewController<ActivatableNotificationView> { 37 private final ExpandableOutlineViewController mExpandableOutlineViewController; 38 private final AccessibilityManager mAccessibilityManager; 39 private final FalsingManager mFalsingManager; 40 private final FalsingCollector mFalsingCollector; 41 private final NotificationTapHelper mNotificationTapHelper; 42 private final TouchHandler mTouchHandler = new TouchHandler(); 43 44 private boolean mNeedsDimming; 45 46 @Inject ActivatableNotificationViewController(ActivatableNotificationView view, NotificationTapHelper.Factory notificationTapHelpFactory, ExpandableOutlineViewController expandableOutlineViewController, AccessibilityManager accessibilityManager, FalsingManager falsingManager, FalsingCollector falsingCollector)47 public ActivatableNotificationViewController(ActivatableNotificationView view, 48 NotificationTapHelper.Factory notificationTapHelpFactory, 49 ExpandableOutlineViewController expandableOutlineViewController, 50 AccessibilityManager accessibilityManager, FalsingManager falsingManager, 51 FalsingCollector falsingCollector) { 52 super(view); 53 mExpandableOutlineViewController = expandableOutlineViewController; 54 mAccessibilityManager = accessibilityManager; 55 mFalsingManager = falsingManager; 56 mFalsingCollector = falsingCollector; 57 58 mNotificationTapHelper = notificationTapHelpFactory.create( 59 (active) -> { 60 if (active) { 61 mView.makeActive(); 62 mFalsingCollector.onNotificationActive(); 63 } else { 64 mView.makeInactive(true /* animate */); 65 } 66 }, mView::performClick, mView::handleSlideBack); 67 68 mView.setOnActivatedListener(new ActivatableNotificationView.OnActivatedListener() { 69 @Override 70 public void onActivated(ActivatableNotificationView view) { 71 mFalsingCollector.onNotificationActive(); 72 } 73 74 @Override 75 public void onActivationReset(ActivatableNotificationView view) { 76 } 77 }); 78 } 79 80 /** 81 * Initialize the controller, setting up handlers and other behavior. 82 */ 83 @Override onInit()84 public void onInit() { 85 mExpandableOutlineViewController.init(); 86 mView.setOnTouchListener(mTouchHandler); 87 mView.setTouchHandler(mTouchHandler); 88 mView.setAccessibilityManager(mAccessibilityManager); 89 } 90 91 @Override onViewAttached()92 protected void onViewAttached() { 93 94 } 95 96 @Override onViewDetached()97 protected void onViewDetached() { 98 99 } 100 101 class TouchHandler implements Gefingerpoken, View.OnTouchListener { 102 private boolean mBlockNextTouch; 103 104 @Override onTouch(View v, MotionEvent ev)105 public boolean onTouch(View v, MotionEvent ev) { 106 boolean result = false; 107 if (mBlockNextTouch) { 108 mBlockNextTouch = false; 109 return true; 110 } 111 if (ev.getAction() == MotionEvent.ACTION_UP) { 112 mView.setLastActionUpTime(ev.getEventTime()); 113 } 114 // With a11y, just do nothing. 115 if (mAccessibilityManager.isTouchExplorationEnabled()) { 116 return false; 117 } 118 119 if (ev.getAction() == MotionEvent.ACTION_UP) { 120 // If this is a false tap, capture the even so it doesn't result in a click. 121 boolean falseTap = mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY); 122 if (!falseTap && v instanceof ActivatableNotificationView) { 123 ((ActivatableNotificationView) v).onTap(); 124 } 125 return falseTap; 126 } 127 return result; 128 } 129 130 @Override onInterceptTouchEvent(MotionEvent ev)131 public boolean onInterceptTouchEvent(MotionEvent ev) { 132 return false; 133 } 134 135 /** 136 * Use {@link #onTouch(View, MotionEvent) instead}. 137 */ 138 @Override onTouchEvent(MotionEvent ev)139 public boolean onTouchEvent(MotionEvent ev) { 140 return false; 141 } 142 } 143 } 144