Merge "Exclude webcam and MIDI USB preferences from requiring auth challenge" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
8569d2ade0
@@ -38,3 +38,13 @@ flag {
|
|||||||
purpose: PURPOSE_BUGFIX
|
purpose: PURPOSE_BUGFIX
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flag {
|
||||||
|
name: "exclude_webcam_auth_challenge"
|
||||||
|
namespace: "safety_center"
|
||||||
|
description: "Gates whether to exclude webcam from USB preferences auth challenge."
|
||||||
|
bug: "349370229"
|
||||||
|
metadata {
|
||||||
|
purpose: PURPOSE_BUGFIX
|
||||||
|
}
|
||||||
|
}
|
@@ -31,6 +31,7 @@ import androidx.preference.PreferenceScreen;
|
|||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
|
import com.android.settings.flags.Flags;
|
||||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -130,39 +131,54 @@ public class UsbDetailsFunctionsController extends UsbDetailsController
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRadioButtonClicked(SelectorWithWidgetPreference preference) {
|
public void onRadioButtonClicked(SelectorWithWidgetPreference preference) {
|
||||||
requireAuthAndExecute(() -> {
|
final long function = UsbBackend.usbFunctionsFromString(preference.getKey());
|
||||||
final long function = UsbBackend.usbFunctionsFromString(preference.getKey());
|
if (isAuthRequired(function)) {
|
||||||
final long previousFunction = mUsbBackend.getCurrentFunctions();
|
requireAuthAndExecute(()->handleRadioButtonClicked(preference, function));
|
||||||
if (DEBUG) {
|
} else {
|
||||||
Log.d(TAG, "onRadioButtonClicked() function : " + function + ", toString() : "
|
handleRadioButtonClicked(preference, function);
|
||||||
+ UsbManager.usbFunctionsToString(function) + ", previousFunction : "
|
}
|
||||||
+ previousFunction + ", toString() : "
|
}
|
||||||
+ UsbManager.usbFunctionsToString(previousFunction));
|
|
||||||
}
|
|
||||||
if (function != previousFunction && !Utils.isMonkeyRunning()
|
|
||||||
&& !isClickEventIgnored(function, previousFunction)) {
|
|
||||||
mPreviousFunction = previousFunction;
|
|
||||||
|
|
||||||
//Update the UI in advance to make it looks smooth
|
private void handleRadioButtonClicked(SelectorWithWidgetPreference preference, long function) {
|
||||||
final SelectorWithWidgetPreference prevPref =
|
final long previousFunction = mUsbBackend.getCurrentFunctions();
|
||||||
(SelectorWithWidgetPreference) mProfilesContainer.findPreference(
|
if (DEBUG) {
|
||||||
UsbBackend.usbFunctionsToString(mPreviousFunction));
|
Log.d(TAG, "onRadioButtonClicked() function : " + function + ", toString() : "
|
||||||
if (prevPref != null) {
|
+ UsbManager.usbFunctionsToString(function) + ", previousFunction : "
|
||||||
prevPref.setChecked(false);
|
+ previousFunction + ", toString() : "
|
||||||
preference.setChecked(true);
|
+ UsbManager.usbFunctionsToString(previousFunction));
|
||||||
}
|
}
|
||||||
|
if (function != previousFunction && !Utils.isMonkeyRunning()
|
||||||
|
&& !isClickEventIgnored(function, previousFunction)) {
|
||||||
|
mPreviousFunction = previousFunction;
|
||||||
|
|
||||||
if (function == UsbManager.FUNCTION_RNDIS || function == UsbManager.FUNCTION_NCM) {
|
//Update the UI in advance to make it looks smooth
|
||||||
// We need to have entitlement check for usb tethering, so use API in
|
final SelectorWithWidgetPreference prevPref =
|
||||||
// TetheringManager.
|
(SelectorWithWidgetPreference) mProfilesContainer.findPreference(
|
||||||
mTetheringManager.startTethering(
|
UsbBackend.usbFunctionsToString(mPreviousFunction));
|
||||||
TetheringManager.TETHERING_USB, new HandlerExecutor(mHandler),
|
if (prevPref != null) {
|
||||||
mOnStartTetheringCallback);
|
prevPref.setChecked(false);
|
||||||
} else {
|
preference.setChecked(true);
|
||||||
mUsbBackend.setCurrentFunctions(function);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
if (function == UsbManager.FUNCTION_RNDIS || function == UsbManager.FUNCTION_NCM) {
|
||||||
|
// We need to have entitlement check for usb tethering, so use API in
|
||||||
|
// TetheringManager.
|
||||||
|
mTetheringManager.startTethering(
|
||||||
|
TetheringManager.TETHERING_USB, new HandlerExecutor(mHandler),
|
||||||
|
mOnStartTetheringCallback);
|
||||||
|
} else {
|
||||||
|
mUsbBackend.setCurrentFunctions(function);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAuthRequired(long function) {
|
||||||
|
if (!Flags.excludeWebcamAuthChallenge()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Since webcam and MIDI don't transfer any persistent data over USB
|
||||||
|
// don't require authentication.
|
||||||
|
return !(function == UsbManager.FUNCTION_UVC || function == UsbManager.FUNCTION_MIDI);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isClickEventIgnored(long function, long previousFunction) {
|
private boolean isClickEventIgnored(long function, long previousFunction) {
|
||||||
|
@@ -35,6 +35,8 @@ import android.content.Context;
|
|||||||
import android.hardware.usb.UsbManager;
|
import android.hardware.usb.UsbManager;
|
||||||
import android.net.TetheringManager;
|
import android.net.TetheringManager;
|
||||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||||
|
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||||
|
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.preference.PreferenceCategory;
|
import androidx.preference.PreferenceCategory;
|
||||||
@@ -48,6 +50,7 @@ import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
|||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@@ -82,6 +85,8 @@ public class UsbDetailsFunctionsControllerTest {
|
|||||||
private FragmentActivity mActivity;
|
private FragmentActivity mActivity;
|
||||||
@Mock
|
@Mock
|
||||||
private TetheringManager mTetheringManager;
|
private TetheringManager mTetheringManager;
|
||||||
|
@Rule
|
||||||
|
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -349,6 +354,30 @@ public class UsbDetailsFunctionsControllerTest {
|
|||||||
assertThat(mFragment.isUserAuthenticated()).isTrue();
|
assertThat(mFragment.isUserAuthenticated()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RequiresFlagsEnabled(Flags.FLAG_EXCLUDE_WEBCAM_AUTH_CHALLENGE)
|
||||||
|
public void onRadioButtonClicked_webcamNoAuthNeeded() {
|
||||||
|
mRadioButtonPreference.setKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_UVC));
|
||||||
|
doReturn(UsbManager.FUNCTION_MTP).when(mUsbBackend).getCurrentFunctions();
|
||||||
|
setAuthPassesAutomatically();
|
||||||
|
|
||||||
|
mDetailsFunctionsController.onRadioButtonClicked(mRadioButtonPreference);
|
||||||
|
|
||||||
|
assertThat(mFragment.isUserAuthenticated()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RequiresFlagsEnabled(Flags.FLAG_EXCLUDE_WEBCAM_AUTH_CHALLENGE)
|
||||||
|
public void onRadioButtonClicked_MidiNoAuthNeeded() {
|
||||||
|
mRadioButtonPreference.setKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MIDI));
|
||||||
|
doReturn(UsbManager.FUNCTION_MTP).when(mUsbBackend).getCurrentFunctions();
|
||||||
|
setAuthPassesAutomatically();
|
||||||
|
|
||||||
|
mDetailsFunctionsController.onRadioButtonClicked(mRadioButtonPreference);
|
||||||
|
|
||||||
|
assertThat(mFragment.isUserAuthenticated()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
private void setAuthPassesAutomatically() {
|
private void setAuthPassesAutomatically() {
|
||||||
Shadows.shadowOf(mContext.getSystemService(KeyguardManager.class))
|
Shadows.shadowOf(mContext.getSystemService(KeyguardManager.class))
|
||||||
.setIsKeyguardSecure(false);
|
.setIsKeyguardSecure(false);
|
||||||
|
Reference in New Issue
Block a user