Merge changes from topic "audit-lock-pattern-utils" into tm-qpr-dev

* changes:
  Add executors to handle binder call.
  Remove lockpattern utils construction...
This commit is contained in:
Aaron Liu
2023-02-23 21:35:40 +00:00
committed by Android (Google) Code Review
6 changed files with 200 additions and 45 deletions

View File

@@ -24,7 +24,6 @@ import android.view.ViewConfiguration;
import android.widget.Button;
import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.widget.LockPatternUtils;
/**
* This class implements a smart emergency button that updates itself based
@@ -40,8 +39,6 @@ public class EmergencyButton extends Button {
private int mDownY;
private boolean mLongPressWasDragged;
private LockPatternUtils mLockPatternUtils;
private final boolean mEnableEmergencyCallWhileSimLocked;
public EmergencyButton(Context context) {
@@ -58,7 +55,6 @@ public class EmergencyButton extends Button {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mLockPatternUtils = new LockPatternUtils(mContext);
if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
setOnLongClickListener(v -> {
if (!mLongPressWasDragged
@@ -95,7 +91,8 @@ public class EmergencyButton extends Button {
return super.performLongClick();
}
void updateEmergencyCallButton(boolean isInCall, boolean hasTelephonyRadio, boolean simLocked) {
void updateEmergencyCallButton(boolean isInCall, boolean hasTelephonyRadio, boolean simLocked,
boolean isSecure) {
boolean visible = false;
if (hasTelephonyRadio) {
// Emergency calling requires a telephony radio.
@@ -107,7 +104,7 @@ public class EmergencyButton extends Button {
visible = mEnableEmergencyCallWhileSimLocked;
} else {
// Only show if there is a secure screen (pin/pattern/SIM pin/SIM puk);
visible = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
visible = isSecure;
}
}
}

View File

@@ -18,6 +18,7 @@ package com.android.keyguard;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.annotation.SuppressLint;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.content.Intent;
@@ -31,16 +32,22 @@ import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.dagger.KeyguardBouncerScope;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.util.EmergencyDialerConstants;
import com.android.systemui.util.ViewController;
import java.util.concurrent.Executor;
import javax.inject.Inject;
/** View Controller for {@link com.android.keyguard.EmergencyButton}. */
@@ -57,6 +64,9 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
private final MetricsLogger mMetricsLogger;
private EmergencyButtonCallback mEmergencyButtonCallback;
private LockPatternUtils mLockPatternUtils;
private Executor mMainExecutor;
private Executor mBackgroundExecutor;
private final KeyguardUpdateMonitorCallback mInfoCallback =
new KeyguardUpdateMonitorCallback() {
@@ -78,12 +88,15 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
}
};
private EmergencyButtonController(@Nullable EmergencyButton view,
@VisibleForTesting
public EmergencyButtonController(@Nullable EmergencyButton view,
ConfigurationController configurationController,
KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
PowerManager powerManager, ActivityTaskManager activityTaskManager,
ShadeController shadeController,
@Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
@Nullable TelecomManager telecomManager, MetricsLogger metricsLogger,
LockPatternUtils lockPatternUtils,
Executor mainExecutor, Executor backgroundExecutor) {
super(view);
mConfigurationController = configurationController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -93,6 +106,9 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
mShadeController = shadeController;
mTelecomManager = telecomManager;
mMetricsLogger = metricsLogger;
mLockPatternUtils = lockPatternUtils;
mMainExecutor = mainExecutor;
mBackgroundExecutor = backgroundExecutor;
}
@Override
@@ -113,13 +129,27 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
mConfigurationController.removeCallback(mConfigurationListener);
}
private void updateEmergencyCallButton() {
/**
* Updates the visibility of the emergency button.
*
* This method runs binder calls in a background thread.
*/
@VisibleForTesting
@SuppressLint("MissingPermission")
public void updateEmergencyCallButton() {
if (mView != null) {
mView.updateEmergencyCallButton(
mTelecomManager != null && mTelecomManager.isInCall(),
getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TELEPHONY),
mKeyguardUpdateMonitor.isSimPinVoiceSecure());
// Run in bg thread to avoid throttling the main thread with binder call.
mBackgroundExecutor.execute(() -> {
boolean isInCall = mTelecomManager != null && mTelecomManager.isInCall();
boolean isSecure = mLockPatternUtils
.isSecure(KeyguardUpdateMonitor.getCurrentUser());
mMainExecutor.execute(() -> mView.updateEmergencyCallButton(
/* isInCall= */ isInCall,
/* hasTelephonyRadio= */ getContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_TELEPHONY),
/* simLocked= */ mKeyguardUpdateMonitor.isSimPinVoiceSecure(),
/* isSecure= */ isSecure));
});
}
}
@@ -129,6 +159,7 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
/**
* Shows the emergency dialer or returns the user to the existing call.
*/
@SuppressLint("MissingPermission")
public void takeEmergencyCallAction() {
mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_CALL);
if (mPowerManager != null) {
@@ -136,29 +167,35 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
}
mActivityTaskManager.stopSystemLockTaskMode();
mShadeController.collapseShade(false);
if (mTelecomManager != null && mTelecomManager.isInCall()) {
mTelecomManager.showInCallScreen(false);
if (mEmergencyButtonCallback != null) {
mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
}
} else {
mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
if (mTelecomManager == null) {
Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
return;
}
Intent emergencyDialIntent =
mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_CLEAR_TOP)
.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
// Run in bg thread to avoid throttling the main thread with binder call.
mBackgroundExecutor.execute(() -> {
boolean isInCall = mTelecomManager != null && mTelecomManager.isInCall();
mMainExecutor.execute(() -> {
if (isInCall) {
mTelecomManager.showInCallScreen(false);
if (mEmergencyButtonCallback != null) {
mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
}
} else {
mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
if (mTelecomManager == null) {
Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
return;
}
Intent emergencyDialIntent =
mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_CLEAR_TOP)
.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
getContext().startActivityAsUser(emergencyDialIntent,
ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
}
getContext().startActivityAsUser(emergencyDialIntent,
ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
}
});
});
}
/** */
@@ -178,13 +215,19 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
@Nullable
private final TelecomManager mTelecomManager;
private final MetricsLogger mMetricsLogger;
private final LockPatternUtils mLockPatternUtils;
private final Executor mMainExecutor;
private final Executor mBackgroundExecutor;
@Inject
public Factory(ConfigurationController configurationController,
KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
PowerManager powerManager, ActivityTaskManager activityTaskManager,
ShadeController shadeController,
@Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
@Nullable TelecomManager telecomManager, MetricsLogger metricsLogger,
LockPatternUtils lockPatternUtils,
@Main Executor mainExecutor,
@Background Executor backgroundExecutor) {
mConfigurationController = configurationController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -194,14 +237,17 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> {
mShadeController = shadeController;
mTelecomManager = telecomManager;
mMetricsLogger = metricsLogger;
mLockPatternUtils = lockPatternUtils;
mMainExecutor = mainExecutor;
mBackgroundExecutor = backgroundExecutor;
}
/** Construct an {@link com.android.keyguard.EmergencyButtonController}. */
public EmergencyButtonController create(EmergencyButton view) {
return new EmergencyButtonController(view, mConfigurationController,
mKeyguardUpdateMonitor, mTelephonyManager, mPowerManager, mActivityTaskManager,
mShadeController,
mTelecomManager, mMetricsLogger);
mShadeController, mTelecomManager, mMetricsLogger, mLockPatternUtils,
mMainExecutor, mBackgroundExecutor);
}
}
}

View File

@@ -33,7 +33,6 @@ import android.widget.TextView;
import androidx.annotation.Nullable;
import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.Utils;
import com.android.systemui.R;
@@ -46,7 +45,6 @@ public class NumPadKey extends ViewGroup implements NumPadAnimationListener {
private final TextView mDigitText;
private final TextView mKlondikeText;
private final LockPatternUtils mLockPatternUtils;
private final PowerManager mPM;
private int mDigit = -1;
@@ -107,7 +105,6 @@ public class NumPadKey extends ViewGroup implements NumPadAnimationListener {
setOnHoverListener(new LiftToActivateListener(
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE)));
mLockPatternUtils = new LockPatternUtils(context);
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);

View File

@@ -213,7 +213,8 @@ public class NotificationLockscreenUserManagerImpl implements
DeviceProvisionedController deviceProvisionedController,
KeyguardStateController keyguardStateController,
SecureSettings secureSettings,
DumpManager dumpManager) {
DumpManager dumpManager,
LockPatternUtils lockPatternUtils) {
mContext = context;
mMainHandler = mainHandler;
mDevicePolicyManager = devicePolicyManager;
@@ -225,7 +226,7 @@ public class NotificationLockscreenUserManagerImpl implements
mClickNotifier = clickNotifier;
mOverviewProxyServiceLazy = overviewProxyServiceLazy;
statusBarStateController.addCallback(this);
mLockPatternUtils = new LockPatternUtils(context);
mLockPatternUtils = lockPatternUtils;
mKeyguardManager = keyguardManager;
mBroadcastDispatcher = broadcastDispatcher;
mDeviceProvisionedController = deviceProvisionedController;

View File

@@ -0,0 +1,112 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.keyguard
import android.app.ActivityTaskManager
import android.content.pm.PackageManager
import android.os.PowerManager
import android.telecom.TelecomManager
import android.telephony.TelephonyManager
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.shade.ShadeController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class EmergencyButtonControllerTest : SysuiTestCase() {
lateinit var underTest: EmergencyButtonController
@Mock lateinit var emergencyButton: EmergencyButton
@Mock lateinit var configurationController: ConfigurationController
@Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock lateinit var telephonyManager: TelephonyManager
@Mock lateinit var powerManager: PowerManager
@Mock lateinit var activityTaskManager: ActivityTaskManager
@Mock lateinit var shadeController: ShadeController
@Mock lateinit var telecomManager: TelecomManager
@Mock lateinit var metricsLogger: MetricsLogger
@Mock lateinit var lockPatternUtils: LockPatternUtils
@Mock lateinit var packageManager: PackageManager
val fakeSystemClock = FakeSystemClock()
val mainExecutor = FakeExecutor(fakeSystemClock)
val backgroundExecutor = FakeExecutor(fakeSystemClock)
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
underTest =
EmergencyButtonController(
emergencyButton,
configurationController,
keyguardUpdateMonitor,
telephonyManager,
powerManager,
activityTaskManager,
shadeController,
telecomManager,
metricsLogger,
lockPatternUtils,
mainExecutor,
backgroundExecutor
)
context.setMockPackageManager(packageManager)
Mockito.`when`(emergencyButton.context).thenReturn(context)
}
@Test
fun testUpdateEmergencyButton() {
Mockito.`when`(telecomManager.isInCall).thenReturn(true)
Mockito.`when`(lockPatternUtils.isSecure(anyInt())).thenReturn(true)
Mockito.`when`(packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY))
.thenReturn(true)
underTest.updateEmergencyCallButton()
backgroundExecutor.runAllReady()
verify(emergencyButton, never())
.updateEmergencyCallButton(
/* isInCall= */ any(),
/* hasTelephonyRadio= */ any(),
/* simLocked= */ any(),
/* isSecure= */ any()
)
mainExecutor.runAllReady()
verify(emergencyButton)
.updateEmergencyCallButton(
/* isInCall= */ eq(true),
/* hasTelephonyRadio= */ eq(true),
/* simLocked= */ any(),
/* isSecure= */ eq(true)
)
}
}

View File

@@ -44,6 +44,7 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -354,7 +355,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
mDeviceProvisionedController,
mKeyguardStateController,
mSettings,
mock(DumpManager.class));
mock(DumpManager.class),
mock(LockPatternUtils.class));
}
public BroadcastReceiver getBaseBroadcastReceiverForTest() {