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.classifier; 18 19 import android.content.Context; 20 import android.net.Uri; 21 import android.provider.DeviceConfig; 22 23 import androidx.annotation.NonNull; 24 25 import com.android.systemui.Dumpable; 26 import com.android.systemui.dagger.SysUISingleton; 27 import com.android.systemui.dagger.qualifiers.Main; 28 import com.android.systemui.dump.DumpManager; 29 import com.android.systemui.plugins.FalsingManager; 30 import com.android.systemui.plugins.FalsingPlugin; 31 import com.android.systemui.plugins.PluginListener; 32 import com.android.systemui.shared.plugins.PluginManager; 33 import com.android.systemui.util.DeviceConfigProxy; 34 35 import java.io.FileDescriptor; 36 import java.io.PrintWriter; 37 import java.util.concurrent.Executor; 38 39 import javax.inject.Inject; 40 import javax.inject.Provider; 41 42 /** 43 * Simple passthrough implementation of {@link FalsingManager} allowing plugins to swap in. 44 * 45 * {@link BrightLineFalsingManager} is used when a Plugin is not loaded. 46 */ 47 @SysUISingleton 48 public class FalsingManagerProxy implements FalsingManager, Dumpable { 49 50 private static final String DUMPABLE_TAG = "FalsingManager"; 51 public static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts"; 52 public static final String FALSING_SUCCESS = "falsing_success_after_attempts"; 53 54 private final PluginManager mPluginManager; 55 private final DeviceConfigProxy mDeviceConfig; 56 private final Provider<BrightLineFalsingManager> mBrightLineFalsingManagerProvider; 57 private final DumpManager mDumpManager; 58 final PluginListener<FalsingPlugin> mPluginListener; 59 60 private FalsingManager mInternalFalsingManager; 61 62 private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigListener = 63 properties -> onDeviceConfigPropertiesChanged(properties.getNamespace()); 64 65 @Inject FalsingManagerProxy(PluginManager pluginManager, @Main Executor executor, DeviceConfigProxy deviceConfig, DumpManager dumpManager, Provider<BrightLineFalsingManager> brightLineFalsingManagerProvider)66 FalsingManagerProxy(PluginManager pluginManager, @Main Executor executor, 67 DeviceConfigProxy deviceConfig, DumpManager dumpManager, 68 Provider<BrightLineFalsingManager> brightLineFalsingManagerProvider) { 69 mPluginManager = pluginManager; 70 mDumpManager = dumpManager; 71 mDeviceConfig = deviceConfig; 72 mBrightLineFalsingManagerProvider = brightLineFalsingManagerProvider; 73 setupFalsingManager(); 74 mDeviceConfig.addOnPropertiesChangedListener( 75 DeviceConfig.NAMESPACE_SYSTEMUI, executor, mDeviceConfigListener 76 ); 77 78 mPluginListener = new PluginListener<FalsingPlugin>() { 79 public void onPluginConnected(FalsingPlugin plugin, Context context) { 80 FalsingManager pluginFalsingManager = plugin.getFalsingManager(context); 81 if (pluginFalsingManager != null) { 82 mInternalFalsingManager.cleanupInternal(); 83 mInternalFalsingManager = pluginFalsingManager; 84 } 85 } 86 87 public void onPluginDisconnected(FalsingPlugin plugin) { 88 setupFalsingManager(); 89 } 90 }; 91 92 mPluginManager.addPluginListener(mPluginListener, FalsingPlugin.class); 93 94 mDumpManager.registerDumpable(DUMPABLE_TAG, this); 95 } 96 onDeviceConfigPropertiesChanged(String namespace)97 private void onDeviceConfigPropertiesChanged(String namespace) { 98 if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) { 99 return; 100 } 101 102 setupFalsingManager(); 103 } 104 105 /** 106 * Setup the FalsingManager implementation. 107 * 108 * If multiple implementations are available, this is where the choice is made. 109 */ setupFalsingManager()110 private void setupFalsingManager() { 111 if (mInternalFalsingManager != null) { 112 mInternalFalsingManager.cleanupInternal(); 113 } 114 mInternalFalsingManager = mBrightLineFalsingManagerProvider.get(); 115 } 116 117 @Override onSuccessfulUnlock()118 public void onSuccessfulUnlock() { 119 mInternalFalsingManager.onSuccessfulUnlock(); 120 } 121 122 @Override isUnlockingDisabled()123 public boolean isUnlockingDisabled() { 124 return mInternalFalsingManager.isUnlockingDisabled(); 125 } 126 127 @Override isFalseTouch(@lassifier.InteractionType int interactionType)128 public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { 129 return mInternalFalsingManager.isFalseTouch(interactionType); 130 } 131 132 @Override isSimpleTap()133 public boolean isSimpleTap() { 134 return mInternalFalsingManager.isSimpleTap(); 135 } 136 137 @Override isFalseTap(@enalty int penalty)138 public boolean isFalseTap(@Penalty int penalty) { 139 return mInternalFalsingManager.isFalseTap(penalty); 140 } 141 142 @Override isFalseDoubleTap()143 public boolean isFalseDoubleTap() { 144 return mInternalFalsingManager.isFalseDoubleTap(); 145 } 146 147 @Override isClassifierEnabled()148 public boolean isClassifierEnabled() { 149 return mInternalFalsingManager.isClassifierEnabled(); 150 } 151 152 @Override shouldEnforceBouncer()153 public boolean shouldEnforceBouncer() { 154 return mInternalFalsingManager.shouldEnforceBouncer(); 155 } 156 157 @Override reportRejectedTouch()158 public Uri reportRejectedTouch() { 159 return mInternalFalsingManager.reportRejectedTouch(); 160 } 161 162 @Override isReportingEnabled()163 public boolean isReportingEnabled() { 164 return mInternalFalsingManager.isReportingEnabled(); 165 } 166 167 @Override addFalsingBeliefListener(FalsingBeliefListener listener)168 public void addFalsingBeliefListener(FalsingBeliefListener listener) { 169 mInternalFalsingManager.addFalsingBeliefListener(listener); 170 } 171 172 @Override removeFalsingBeliefListener(FalsingBeliefListener listener)173 public void removeFalsingBeliefListener(FalsingBeliefListener listener) { 174 mInternalFalsingManager.removeFalsingBeliefListener(listener); 175 } 176 177 @Override addTapListener(FalsingTapListener listener)178 public void addTapListener(FalsingTapListener listener) { 179 mInternalFalsingManager.addTapListener(listener); 180 } 181 182 @Override removeTapListener(FalsingTapListener listener)183 public void removeTapListener(FalsingTapListener listener) { 184 mInternalFalsingManager.removeTapListener(listener); 185 } 186 187 @Override onProximityEvent(ProximityEvent proximityEvent)188 public void onProximityEvent(ProximityEvent proximityEvent) { 189 mInternalFalsingManager.onProximityEvent(proximityEvent); 190 } 191 192 @Override dump(@onNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args)193 public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { 194 mInternalFalsingManager.dump(fd, pw, args); 195 } 196 197 @Override cleanupInternal()198 public void cleanupInternal() { 199 mDeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigListener); 200 mPluginManager.removePluginListener(mPluginListener); 201 mDumpManager.unregisterDumpable(DUMPABLE_TAG); 202 mInternalFalsingManager.cleanupInternal(); 203 } 204 } 205