Merge "AR/FR: Keyboard challenge takes precedence."
This commit is contained in:
committed by
Android (Google) Code Review
commit
295a55b2fd
@@ -123,24 +123,34 @@ public class MasterClear extends InstrumentedPreferenceFragment {
|
|||||||
return !((requestCode != KEYGUARD_REQUEST) && (requestCode != CREDENTIAL_CONFIRM_REQUEST));
|
return !((requestCode != KEYGUARD_REQUEST) && (requestCode != CREDENTIAL_CONFIRM_REQUEST));
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
boolean isShowFinalConfirmation(int requestCode, int resultCode) {
|
|
||||||
return (resultCode == Activity.RESULT_OK) || (requestCode == CREDENTIAL_CONFIRM_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
onActivityResultInternal(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal method that allows easy testing without dealing with super references.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
void onActivityResultInternal(int requestCode, int resultCode, Intent data) {
|
||||||
if (!isValidRequestCode(requestCode)) {
|
if (!isValidRequestCode(requestCode)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user entered a valid keyguard trace, present the final
|
if (resultCode != Activity.RESULT_OK) {
|
||||||
// confirmation prompt; otherwise, go back to the initial state.
|
|
||||||
if (isShowFinalConfirmation(requestCode, resultCode)) {
|
|
||||||
showFinalConfirmation();
|
|
||||||
} else {
|
|
||||||
establishInitialState();
|
establishInitialState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent intent = null;
|
||||||
|
// If returning from a Keyguard request, try to show an account confirmation request if
|
||||||
|
// applciable.
|
||||||
|
if (CREDENTIAL_CONFIRM_REQUEST != requestCode
|
||||||
|
&& (intent = getAccountConfirmationIntent()) != null) {
|
||||||
|
showAccountCredentialConfirmation(intent);
|
||||||
|
} else {
|
||||||
|
showFinalConfirmation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +165,12 @@ public class MasterClear extends InstrumentedPreferenceFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean tryShowAccountConfirmation() {
|
void showAccountCredentialConfirmation(Intent intent) {
|
||||||
|
startActivityForResult(intent, CREDENTIAL_CONFIRM_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
Intent getAccountConfirmationIntent() {
|
||||||
final Context context = getActivity();
|
final Context context = getActivity();
|
||||||
final String accountType = context.getString(R.string.account_type);
|
final String accountType = context.getString(R.string.account_type);
|
||||||
final String packageName = context.getString(R.string.account_confirmation_package);
|
final String packageName = context.getString(R.string.account_confirmation_package);
|
||||||
@@ -163,7 +178,8 @@ public class MasterClear extends InstrumentedPreferenceFragment {
|
|||||||
if (TextUtils.isEmpty(accountType)
|
if (TextUtils.isEmpty(accountType)
|
||||||
|| TextUtils.isEmpty(packageName)
|
|| TextUtils.isEmpty(packageName)
|
||||||
|| TextUtils.isEmpty(className)) {
|
|| TextUtils.isEmpty(className)) {
|
||||||
return false;
|
Log.i(TAG, "Resources not set for account confirmation.");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
final AccountManager am = AccountManager.get(context);
|
final AccountManager am = AccountManager.get(context);
|
||||||
Account[] accounts = am.getAccountsByType(accountType);
|
Account[] accounts = am.getAccountsByType(accountType);
|
||||||
@@ -179,12 +195,14 @@ public class MasterClear extends InstrumentedPreferenceFragment {
|
|||||||
&& packageName.equals(resolution.activityInfo.packageName)) {
|
&& packageName.equals(resolution.activityInfo.packageName)) {
|
||||||
// Note that we need to check the packagename to make sure that an Activity resolver
|
// Note that we need to check the packagename to make sure that an Activity resolver
|
||||||
// wasn't returned.
|
// wasn't returned.
|
||||||
startActivityForResult(
|
return requestAccountConfirmation;
|
||||||
requestAccountConfirmation, CREDENTIAL_CONFIRM_REQUEST);
|
} else {
|
||||||
return true;
|
Log.i(TAG, "Unable to resolve Activity: " + packageName + "/" + className);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "No " + accountType + " accounts installed!");
|
||||||
}
|
}
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +228,14 @@ public class MasterClear extends InstrumentedPreferenceFragment {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tryShowAccountConfirmation() && !runKeyguardConfirmation(KEYGUARD_REQUEST)) {
|
if (runKeyguardConfirmation(KEYGUARD_REQUEST)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent intent = getAccountConfirmationIntent();
|
||||||
|
if (intent != null) {
|
||||||
|
showAccountCredentialConfirmation(intent);
|
||||||
|
} else {
|
||||||
showFinalConfirmation();
|
showFinalConfirmation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,7 +253,8 @@ public class MasterClear extends InstrumentedPreferenceFragment {
|
|||||||
* time, then simply reuse the inflated views directly whenever we need
|
* time, then simply reuse the inflated views directly whenever we need
|
||||||
* to change contents.
|
* to change contents.
|
||||||
*/
|
*/
|
||||||
private void establishInitialState() {
|
@VisibleForTesting
|
||||||
|
void establishInitialState() {
|
||||||
mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_master_clear);
|
mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_master_clear);
|
||||||
mInitiateButton.setOnClickListener(mInitiateListener);
|
mInitiateButton.setOnClickListener(mInitiateListener);
|
||||||
mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container);
|
mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container);
|
||||||
|
@@ -18,11 +18,14 @@ package com.android.settings;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.robolectric.Shadows.shadowOf;
|
import static org.robolectric.Shadows.shadowOf;
|
||||||
|
|
||||||
@@ -86,6 +89,9 @@ public class MasterClearTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Activity mMockActivity;
|
private Activity mMockActivity;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Intent mMockIntent;
|
||||||
|
|
||||||
private ShadowActivity mShadowActivity;
|
private ShadowActivity mShadowActivity;
|
||||||
private ShadowAccountManager mShadowAccountManager;
|
private ShadowAccountManager mShadowAccountManager;
|
||||||
private Activity mActivity;
|
private Activity mActivity;
|
||||||
@@ -110,7 +116,7 @@ public class MasterClearTest {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mMasterClear = spy(new MasterClear());
|
mMasterClear = spy(new MasterClear());
|
||||||
mActivity = Robolectric.setupActivity(Activity.class);
|
mActivity = Robolectric.setupActivity(Activity.class);
|
||||||
mShadowActivity = shadowOf(mActivity);
|
mShadowActivity = shadowOf(mActivity);https://stackoverflow.com/questions/14889951/how-to-verify-a-method-is-called-two-times-with-mockito-verify
|
||||||
// mShadowAccountManager = shadowOf(AccountManager.get(mActivity));
|
// mShadowAccountManager = shadowOf(AccountManager.get(mActivity));
|
||||||
mContentView = LayoutInflater.from(mActivity).inflate(R.layout.master_clear, null);
|
mContentView = LayoutInflater.from(mActivity).inflate(R.layout.master_clear, null);
|
||||||
|
|
||||||
@@ -213,38 +219,115 @@ public class MasterClearTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTryShowAccountConfirmation_unsupported() {
|
public void testOnActivityResultInternal_invalideRequest() {
|
||||||
when(mMasterClear.getActivity()).thenReturn(mActivity);
|
int invalidRequestCode = -1;
|
||||||
/* Using the default resources, account confirmation shouldn't trigger */
|
doReturn(false).when(mMasterClear).isValidRequestCode(eq(invalidRequestCode));
|
||||||
assertThat(mMasterClear.tryShowAccountConfirmation()).isFalse();
|
|
||||||
|
mMasterClear.onActivityResultInternal(invalidRequestCode, Activity.RESULT_OK, null);
|
||||||
|
|
||||||
|
verify(mMasterClear, times(1)).isValidRequestCode(eq(invalidRequestCode));
|
||||||
|
verify(mMasterClear, times(0)).establishInitialState();
|
||||||
|
verify(mMasterClear, times(0)).getAccountConfirmationIntent();
|
||||||
|
verify(mMasterClear, times(0)).showFinalConfirmation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTryShowAccountConfirmation_no_relevant_accounts() {
|
public void testOnActivityResultInternal_resultCanceled() {
|
||||||
|
doReturn(true).when(mMasterClear).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
|
||||||
|
doNothing().when(mMasterClear).establishInitialState();
|
||||||
|
|
||||||
|
mMasterClear.onActivityResultInternal(
|
||||||
|
MasterClear.KEYGUARD_REQUEST, Activity.RESULT_CANCELED, null);
|
||||||
|
|
||||||
|
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
|
||||||
|
verify(mMasterClear, times(1)).establishInitialState();
|
||||||
|
verify(mMasterClear, times(0)).getAccountConfirmationIntent();
|
||||||
|
verify(mMasterClear, times(0)).showFinalConfirmation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnActivityResultInternal_keyguardRequestTriggeringConfirmAccount() {
|
||||||
|
doReturn(true).when(mMasterClear).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
|
||||||
|
doReturn(mMockIntent).when(mMasterClear).getAccountConfirmationIntent();
|
||||||
|
doNothing().when(mMasterClear).showAccountCredentialConfirmation(eq(mMockIntent));
|
||||||
|
|
||||||
|
mMasterClear.onActivityResultInternal(
|
||||||
|
MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
|
||||||
|
|
||||||
|
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
|
||||||
|
verify(mMasterClear, times(0)).establishInitialState();
|
||||||
|
verify(mMasterClear, times(1)).getAccountConfirmationIntent();
|
||||||
|
verify(mMasterClear, times(1)).showAccountCredentialConfirmation(eq(mMockIntent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnActivityResultInternal_keyguardRequestTriggeringShowFinal() {
|
||||||
|
doReturn(true).when(mMasterClear).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
|
||||||
|
doReturn(null).when(mMasterClear).getAccountConfirmationIntent();
|
||||||
|
doNothing().when(mMasterClear).showFinalConfirmation();
|
||||||
|
|
||||||
|
mMasterClear.onActivityResultInternal(
|
||||||
|
MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
|
||||||
|
|
||||||
|
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
|
||||||
|
verify(mMasterClear, times(0)).establishInitialState();
|
||||||
|
verify(mMasterClear, times(1)).getAccountConfirmationIntent();
|
||||||
|
verify(mMasterClear, times(1)).showFinalConfirmation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnActivityResultInternal_confirmRequestTriggeringShowFinal() {
|
||||||
|
doReturn(true).when(mMasterClear)
|
||||||
|
.isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
|
||||||
|
doNothing().when(mMasterClear).showFinalConfirmation();
|
||||||
|
|
||||||
|
mMasterClear.onActivityResultInternal(
|
||||||
|
MasterClear.CREDENTIAL_CONFIRM_REQUEST, Activity.RESULT_OK, null);
|
||||||
|
|
||||||
|
verify(mMasterClear, times(1))
|
||||||
|
.isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
|
||||||
|
verify(mMasterClear, times(0)).establishInitialState();
|
||||||
|
verify(mMasterClear, times(0)).getAccountConfirmationIntent();
|
||||||
|
verify(mMasterClear, times(1)).showFinalConfirmation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAccountConfirmationIntent_unsupported() {
|
||||||
|
when(mMasterClear.getActivity()).thenReturn(mActivity);
|
||||||
|
/* Using the default resources, account confirmation shouldn't trigger */
|
||||||
|
assertThat(mMasterClear.getAccountConfirmationIntent()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAccountConfirmationIntent_no_relevant_accounts() {
|
||||||
when(mMasterClear.getActivity()).thenReturn(mMockActivity);
|
when(mMasterClear.getActivity()).thenReturn(mMockActivity);
|
||||||
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
||||||
when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
|
when(mMockActivity.getString(R.string.account_confirmation_package))
|
||||||
when(mMockActivity.getString(R.string.account_confirmation_class)).thenReturn(TEST_CONFIRMATION_CLASS);
|
.thenReturn(TEST_CONFIRMATION_PACKAGE);
|
||||||
|
when(mMockActivity.getString(R.string.account_confirmation_class))
|
||||||
|
.thenReturn(TEST_CONFIRMATION_CLASS);
|
||||||
|
|
||||||
Account[] accounts = new Account[0];
|
Account[] accounts = new Account[0];
|
||||||
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
||||||
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
|
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
|
||||||
assertThat(mMasterClear.tryShowAccountConfirmation()).isFalse();
|
assertThat(mMasterClear.getAccountConfirmationIntent()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTryShowAccountConfirmation_unresolved() {
|
public void testGetAccountConfirmationIntent_unresolved() {
|
||||||
when(mMasterClear.getActivity()).thenReturn(mMockActivity);
|
when(mMasterClear.getActivity()).thenReturn(mMockActivity);
|
||||||
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
||||||
when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
|
when(mMockActivity.getString(R.string.account_confirmation_package))
|
||||||
when(mMockActivity.getString(R.string.account_confirmation_class)).thenReturn(TEST_CONFIRMATION_CLASS);
|
.thenReturn(TEST_CONFIRMATION_PACKAGE);
|
||||||
|
when(mMockActivity.getString(R.string.account_confirmation_class))
|
||||||
|
.thenReturn(TEST_CONFIRMATION_CLASS);
|
||||||
Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
|
Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
|
||||||
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
||||||
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
|
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
|
||||||
// The package manager should not resolve the confirmation intent targeting the non-existent
|
// The package manager should not resolve the confirmation intent targeting the non-existent
|
||||||
// confirmation package.
|
// confirmation package.
|
||||||
when(mMockActivity.getPackageManager()).thenReturn(mPackageManager);
|
when(mMockActivity.getPackageManager()).thenReturn(mPackageManager);
|
||||||
assertThat(mMasterClear.tryShowAccountConfirmation()).isFalse();
|
assertThat(mMasterClear.getAccountConfirmationIntent()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -252,8 +335,10 @@ public class MasterClearTest {
|
|||||||
when(mMasterClear.getActivity()).thenReturn(mMockActivity);
|
when(mMasterClear.getActivity()).thenReturn(mMockActivity);
|
||||||
// Only try to show account confirmation if the appropriate resource overlays are available.
|
// Only try to show account confirmation if the appropriate resource overlays are available.
|
||||||
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
|
||||||
when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
|
when(mMockActivity.getString(R.string.account_confirmation_package))
|
||||||
when(mMockActivity.getString(R.string.account_confirmation_class)).thenReturn(TEST_CONFIRMATION_CLASS);
|
.thenReturn(TEST_CONFIRMATION_PACKAGE);
|
||||||
|
when(mMockActivity.getString(R.string.account_confirmation_class))
|
||||||
|
.thenReturn(TEST_CONFIRMATION_CLASS);
|
||||||
// Add accounts to trigger the search for a resolving intent.
|
// Add accounts to trigger the search for a resolving intent.
|
||||||
Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
|
Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
|
||||||
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
|
||||||
@@ -268,10 +353,18 @@ public class MasterClearTest {
|
|||||||
resolveInfo.activityInfo = activityInfo;
|
resolveInfo.activityInfo = activityInfo;
|
||||||
when(mPackageManager.resolveActivity(any(), eq(0))).thenReturn(resolveInfo);
|
when(mPackageManager.resolveActivity(any(), eq(0))).thenReturn(resolveInfo);
|
||||||
|
|
||||||
// Finally mock out the startActivityForResultCall
|
Intent actualIntent = mMasterClear.getAccountConfirmationIntent();
|
||||||
doNothing().when(mMasterClear).startActivityForResult(any(), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
|
assertEquals(TEST_CONFIRMATION_PACKAGE, actualIntent.getComponent().getPackageName());
|
||||||
|
assertEquals(TEST_CONFIRMATION_CLASS, actualIntent.getComponent().getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
assertThat(mMasterClear.tryShowAccountConfirmation()).isTrue();
|
public void testShowAccountCredentialConfirmation() {
|
||||||
|
// Finally mock out the startActivityForResultCall
|
||||||
|
doNothing().when(mMasterClear)
|
||||||
|
.startActivityForResult(eq(mMockIntent), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
|
||||||
|
mMasterClear.showAccountCredentialConfirmation(mMockIntent);
|
||||||
|
verify(mMasterClear, times(1))
|
||||||
|
.startActivityForResult(eq(mMockIntent), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Reference in New Issue
Block a user