diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6ff3a00df8f..111d9017789 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4894,49 +4894,57 @@
When magnification is turned on, you can zoom in on your screen.\n\nTo zoom, start magnification, then tap anywhere on the screen.\n- Drag 2 or more fingers to scroll
\n- Pinch 2 or more fingers to adjust zoom
\n\nTo zoom temporarily, start magnification, then touch & hold anywhere on the screen.\n- Drag to move around the screen
\n- Lift finger to zoom out
\n\nYou can’t zoom in on the keyboard or navigation bar.
-
+
Use accessibility button to open
-
+
+ Hold volume key to open
+
+ Triple tap screen to open
+
Use gesture to open
-
+
Use new accessibility gesture
-
- To turn this service on or off, tap the accessibility button %s on the bottom of your screen.\n\nTo switch between services, touch & hold the accessibility button.
-
- To turn this service on or off, swipe up from the bottom of the screen with two fingers.\n\nTo switch between services, swipe up with two fingers and hold.
-
- To turn this service on or off, swipe up from the bottom of the screen with three fingers.\n\nTo switch between services, swipe up with three fingers and hold.
-
- To turn an accessibility service on or off, swipe up from the bottom of the screen with two fingers.\n\nTo switch between services, swipe up with two fingers and hold.
-
- To turn an accessibility service on or off, swipe up from the bottom of the screen with three fingers.\n\nTo switch between services, swipe up with three fingers and hold.
-
+
+ To turn this app on or off, tap the accessibility button %s on the bottom of your screen.\n\nTo switch between apps, touch & hold the accessibility button.
+
+ To turn this app on or off, press & hold both volume keys for 1 second.
+
+ To start and stop magnification, triple-tap anywhere on your screen.
+
+ To turn this app on or off, swipe up from the bottom of the screen with two fingers.\n\nTo switch between apps, swipe up with two fingers and hold.
+
+ To turn this app on or off, swipe up from the bottom of the screen with three fingers.\n\nTo switch between apps, swipe up with three fingers and hold.
+
+ To turn an accessibility app on or off, swipe up from the bottom of the screen with two fingers.\n\nTo switch between apps, swipe up with two fingers and hold.
+
+ To turn an accessibility app on or off, swipe up from the bottom of the screen with three fingers.\n\nTo switch between apps, swipe up with three fingers and hold.
+
Got it
%1$s shortcut
-
+
Accessibility Button
-
+
Swipe up with 2 fingers
-
+
Swipe up with 3 fingers
Tap accessibility button
-
+
Tap the accessibility button %s at the bottom of your screen
-
+
Swipe up from the bottom of the screen with 2 fingers
-
+
Swipe up from the bottom of the screen with 3 fingers
-
+
Hold volume keys
-
+
Press & hold both volume keys for 1 second
-
+
Triple-tap screen
-
+
Quickly tap screen 3 times. This shortcut may slow down your device.
-
+
Advanced
The Accessibility button is set to %1$s. To use magnification, touch & hold the Accessibility button, then select magnification.
@@ -6997,7 +7005,7 @@
Expand settings for application
- Tap & pay
+ Contactless payments
How it works
diff --git a/src/com/android/settings/development/EnhancedConnectivityPreferenceController.java b/src/com/android/settings/development/EnhancedConnectivityPreferenceController.java
index 2dbd7d1ee2b..dc6597384d2 100644
--- a/src/com/android/settings/development/EnhancedConnectivityPreferenceController.java
+++ b/src/com/android/settings/development/EnhancedConnectivityPreferenceController.java
@@ -37,7 +37,7 @@ public class EnhancedConnectivityPreferenceController extends
@VisibleForTesting
static final int ENHANCED_CONNECTIVITY_ON = 1;
- // default is enhanced connectivity disabled.
+ // default is enhanced connectivity enabled.
@VisibleForTesting
static final int ENHANCED_CONNECTIVITY_OFF = 0;
@@ -65,7 +65,7 @@ public class EnhancedConnectivityPreferenceController extends
public void updateState(Preference preference) {
final int enhancedConnectivityEnabled = Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.ENHANCED_CONNECTIVITY_ENABLED,
- ENHANCED_CONNECTIVITY_OFF);
+ ENHANCED_CONNECTIVITY_ON);
((SwitchPreference) mPreference).setChecked(
enhancedConnectivityEnabled == ENHANCED_CONNECTIVITY_ON);
}
@@ -75,7 +75,7 @@ public class EnhancedConnectivityPreferenceController extends
super.onDeveloperOptionsSwitchDisabled();
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.ENHANCED_CONNECTIVITY_ENABLED,
- ENHANCED_CONNECTIVITY_OFF);
- ((SwitchPreference) mPreference).setChecked(false);
+ ENHANCED_CONNECTIVITY_ON);
+ ((SwitchPreference) mPreference).setChecked(true);
}
}
diff --git a/src/com/android/settings/network/ims/ImsQueryController.java b/src/com/android/settings/network/ims/ImsQueryController.java
index 8fdad4004fe..068a80537b9 100644
--- a/src/com/android/settings/network/ims/ImsQueryController.java
+++ b/src/com/android/settings/network/ims/ImsQueryController.java
@@ -20,6 +20,7 @@ import android.telephony.AccessNetworkConstants;
import android.telephony.SubscriptionManager;
import android.telephony.ims.ImsException;
import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -84,4 +85,20 @@ abstract class ImsQueryController {
boolean isProvisionedOnDevice(int subId) {
return (new ImsQueryProvisioningStat(subId, mCapability, mTech)).query();
}
+
+ @VisibleForTesting
+ boolean isServiceStateReady(int subId) throws InterruptedException, ImsException,
+ IllegalArgumentException {
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+ return false;
+ }
+
+ final ImsMmTelManager imsMmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
+ // TODO: have a shared thread pool instead of create ExecutorService
+ // everytime to improve performance.
+ final ExecutorService executor = Executors.newSingleThreadExecutor();
+ final IntegerConsumer intResult = new IntegerConsumer();
+ imsMmTelManager.getFeatureState(executor, intResult);
+ return (intResult.get(TIMEOUT_MILLIS) == ImsFeature.STATE_READY);
+ }
}
diff --git a/src/com/android/settings/network/ims/IntegerConsumer.java b/src/com/android/settings/network/ims/IntegerConsumer.java
new file mode 100644
index 00000000000..02c82275a86
--- /dev/null
+++ b/src/com/android/settings/network/ims/IntegerConsumer.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 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.settings.network.ims;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+
+class IntegerConsumer extends Semaphore implements Consumer {
+
+ private static final String TAG = "IntegerConsumer";
+
+ IntegerConsumer() {
+ super(0);
+ mValue = new AtomicInteger();
+ }
+
+ private volatile AtomicInteger mValue;
+
+ /**
+ * Get boolean value reported from callback
+ *
+ * @param timeout callback waiting time in milliseconds
+ * @return int value reported
+ * @throws InterruptedException when thread get interrupted
+ */
+ int get(long timeout) throws InterruptedException {
+ tryAcquire(timeout, TimeUnit.MILLISECONDS);
+ return mValue.get();
+ }
+
+ /**
+ * Implementation of {@link Consumer#accept(Integer)}
+ *
+ * @param value int reported from {@link Consumer#accept(Integer)}
+ */
+ public void accept(Integer value) {
+ if (value != null) {
+ mValue.set(value.intValue());
+ }
+ release();
+ }
+}
diff --git a/src/com/android/settings/network/ims/VtQueryImsState.java b/src/com/android/settings/network/ims/VtQueryImsState.java
index 60bd72988e3..c0776036bf1 100644
--- a/src/com/android/settings/network/ims/VtQueryImsState.java
+++ b/src/com/android/settings/network/ims/VtQueryImsState.java
@@ -20,20 +20,23 @@ import android.content.Context;
import android.telecom.TelecomManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.SubscriptionManager;
+import android.telephony.ims.ImsException;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.ims.ImsManager;
import com.android.settings.network.SubscriptionUtil;
-import com.android.settings.network.telephony.MobileNetworkUtils;
/**
* Controller class for querying VT status
*/
public class VtQueryImsState extends ImsQueryController {
+ private static final String LOG_TAG = "VtQueryImsState";
+
private Context mContext;
private int mSubId;
@@ -71,14 +74,25 @@ public class VtQueryImsState extends ImsQueryController {
* @return true when Video Call can be performed, otherwise false
*/
public boolean isReadyToVideoCall() {
+ if (!isProvisionedOnDevice(mSubId)) {
+ return false;
+ }
+
final ImsManager imsManager = getImsManager(mSubId);
if (imsManager == null) {
return false;
}
- return imsManager.isVtEnabledByPlatform()
- && isProvisionedOnDevice(mSubId)
- && MobileNetworkUtils.isImsServiceStateReady(imsManager);
+ if (!imsManager.isVtEnabledByPlatform()) {
+ return false;
+ }
+
+ try {
+ return isServiceStateReady(mSubId);
+ } catch (InterruptedException | IllegalArgumentException | ImsException exception) {
+ Log.w(LOG_TAG, "fail to get Vt service status. subId=" + mSubId, exception);
+ }
+ return false;
}
/**
diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java
index bc0e5c75231..7e783227362 100644
--- a/src/com/android/settings/password/BiometricFragment.java
+++ b/src/com/android/settings/password/BiometricFragment.java
@@ -70,6 +70,13 @@ public class BiometricFragment extends InstrumentedFragment {
});
cleanup();
}
+
+ @Override
+ public void onAuthenticationFailed() {
+ mClientExecutor.execute(() -> {
+ mClientCallback.onAuthenticationFailed();
+ });
+ }
};
private final DialogInterface.OnClickListener mNegativeButtonListener =
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 83368f95e0f..220b64929ad 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -111,6 +111,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
});
private AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() {
+ @Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
if (!mGoingToBackground) {
if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED
@@ -123,17 +124,24 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
}
}
+ @Override
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
mTrustManager.setDeviceLockedForUser(mUserId, false);
-
+ final boolean isStrongAuth = result.getAuthenticationType()
+ == BiometricPrompt.AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL;
ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils, mUserManager,
- mUserId);
+ mDevicePolicyManager, mUserId, isStrongAuth);
ConfirmDeviceCredentialUtils.checkForPendingIntent(
ConfirmDeviceCredentialActivity.this);
setResult(Activity.RESULT_OK);
finish();
}
+
+ @Override
+ public void onAuthenticationFailed() {
+ mDevicePolicyManager.reportFailedBiometricAttempt(mUserId);
+ }
};
private String getStringForError(int errorCode) {
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialUtils.java b/src/com/android/settings/password/ConfirmDeviceCredentialUtils.java
index 11d69246206..a5febebc198 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialUtils.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialUtils.java
@@ -20,6 +20,7 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.IActivityManager;
+import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import android.content.IntentSender;
import android.os.RemoteException;
@@ -54,8 +55,12 @@ public class ConfirmDeviceCredentialUtils {
}
public static void reportSuccessfulAttempt(LockPatternUtils utils, UserManager userManager,
- int userId) {
- utils.reportSuccessfulPasswordAttempt(userId);
+ DevicePolicyManager dpm, int userId, boolean isStrongAuth) {
+ if (isStrongAuth) {
+ utils.reportSuccessfulPasswordAttempt(userId);
+ } else {
+ dpm.reportSuccessfulBiometricAttempt(userId);
+ }
if (userManager.isManagedProfile(userId)) {
// Keyguard is responsible to disable StrongAuth for primary user. Disable StrongAuth
// for work challenge only here.
diff --git a/src/com/android/settings/password/ConfirmLockPassword.java b/src/com/android/settings/password/ConfirmLockPassword.java
index ce8813ffbad..260919dbcee 100644
--- a/src/com/android/settings/password/ConfirmLockPassword.java
+++ b/src/com/android/settings/password/ConfirmLockPassword.java
@@ -475,7 +475,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
if (matched) {
if (newResult) {
ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils,
- mUserManager, mEffectiveUserId);
+ mUserManager, mDevicePolicyManager, mEffectiveUserId,
+ /* isStrongAuth */ true);
}
startDisappearAnimation(intent);
ConfirmDeviceCredentialUtils.checkForPendingIntent(getActivity());
diff --git a/src/com/android/settings/password/ConfirmLockPattern.java b/src/com/android/settings/password/ConfirmLockPattern.java
index b2afb22da96..06f3d93d3c8 100644
--- a/src/com/android/settings/password/ConfirmLockPattern.java
+++ b/src/com/android/settings/password/ConfirmLockPattern.java
@@ -509,7 +509,8 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
if (matched) {
if (newResult) {
ConfirmDeviceCredentialUtils.reportSuccessfulAttempt(mLockPatternUtils,
- mUserManager, mEffectiveUserId);
+ mUserManager, mDevicePolicyManager, mEffectiveUserId,
+ /* isStrongAuth */ true);
}
startDisappearAnimation(intent);
ConfirmDeviceCredentialUtils.checkForPendingIntent(getActivity());
diff --git a/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java b/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
index a28f9907d6b..23971e717ac 100644
--- a/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
+++ b/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
@@ -71,7 +71,8 @@ public class ConfigureWifiEntryFragment extends InstrumentedFragment implements
private Button mSubmitBtn;
private Button mCancelBtn;
private WifiEntry mWifiEntry;
- private NetworkDetailsTracker mNetworkDetailsTracker;
+ @VisibleForTesting
+ NetworkDetailsTracker mNetworkDetailsTracker;
private HandlerThread mWorkerThread;
@Override
diff --git a/tests/robotests/src/com/android/settings/development/EnhancedConnectivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/EnhancedConnectivityPreferenceControllerTest.java
index 6fd6f553850..171fc6bc5de 100644
--- a/tests/robotests/src/com/android/settings/development/EnhancedConnectivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/EnhancedConnectivityPreferenceControllerTest.java
@@ -88,20 +88,20 @@ public class EnhancedConnectivityPreferenceControllerTest {
}
@Test
- public void onDeveloperOptionsDisabled_shouldDisablePreference() {
- mController.onDeveloperOptionsDisabled();
+ public void onDeveloperOptionsDisabled_shouldEnablePreference() {
+ mController.onDeveloperOptionsSwitchDisabled();
verify(mPreference).setEnabled(false);
- verify(mPreference).setChecked(false);
+ verify(mPreference).setChecked(true);
- assertThat(isSettingEnabled()).isFalse();
+ assertThat(isSettingEnabled()).isTrue();
}
private boolean isSettingEnabled() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ENHANCED_CONNECTIVITY_ENABLED,
- EnhancedConnectivityPreferenceController.ENHANCED_CONNECTIVITY_OFF
- /* default off */)
+ EnhancedConnectivityPreferenceController.ENHANCED_CONNECTIVITY_ON
+ /* default on */)
== EnhancedConnectivityPreferenceController.ENHANCED_CONNECTIVITY_ON;
}
}
diff --git a/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java
index 4fd7d0c6dfb..3daf6cb0f1e 100644
--- a/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java
+++ b/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java
@@ -17,6 +17,7 @@
package com.android.settings.network.ims;
import android.content.Context;
+import android.telephony.ims.ImsException;
import com.android.ims.ImsManager;
@@ -29,6 +30,7 @@ public class MockVtQueryImsState extends VtQueryImsState {
private Boolean mIsTtyOnVolteEnabled;
private Boolean mIsProvisionedOnDevice;
private Boolean mIsEnabledByUser;
+ private Boolean mIsServiceStateReady;
/**
* Constructor
@@ -68,6 +70,19 @@ public class MockVtQueryImsState extends VtQueryImsState {
return super.isProvisionedOnDevice(subId);
}
+ public void setServiceStateReady(boolean isReady) {
+ mIsServiceStateReady = isReady;
+ }
+
+ @Override
+ boolean isServiceStateReady(int subId) throws InterruptedException, ImsException,
+ IllegalArgumentException {
+ if (mIsServiceStateReady != null) {
+ return mIsServiceStateReady;
+ }
+ return super.isServiceStateReady(subId);
+ }
+
public void setIsEnabledByUser(boolean enabled) {
mIsEnabledByUser = enabled;
}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java
index c766289c2b6..04fc4b94889 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java
@@ -27,7 +27,6 @@ import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.ProvisioningManager;
-import android.telephony.ims.feature.ImsFeature;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
@@ -98,7 +97,7 @@ public class VideoCallingPreferenceControllerTest {
doReturn(true).when(mImsManager).isVtEnabledByPlatform();
mQueryImsState.setIsProvisionedOnDevice(true);
- doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceState();
+ mQueryImsState.setServiceStateReady(true);
doReturn(true).when(mTelephonyManager).isDataEnabled();
mController.mCallState = TelephonyManager.CALL_STATE_IDLE;
diff --git a/tests/robotests/src/com/android/settings/wifi/ConfigureWifiEntryFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/ConfigureWifiEntryFragmentTest.java
index 1f0c3127d55..ce9d10ca99d 100644
--- a/tests/robotests/src/com/android/settings/wifi/ConfigureWifiEntryFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/ConfigureWifiEntryFragmentTest.java
@@ -24,21 +24,17 @@ import static org.mockito.Mockito.verify;
import android.app.settings.SettingsEnums;
import android.os.Bundle;
-import com.android.settings.testutils.shadow.ShadowConnectivityManager;
+import com.android.wifitrackerlib.NetworkDetailsTracker;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
import org.robolectric.shadows.androidx.fragment.FragmentController;
-// TODO(b/70983952): Can't test because b/146802959, should remove @Ignore tag after it's fixed.
-@Ignore
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowConnectivityManager.class)
public class ConfigureWifiEntryFragmentTest {
private static final String KEY_SSID = "key_ssid";
@@ -46,6 +42,9 @@ public class ConfigureWifiEntryFragmentTest {
private ConfigureWifiEntryFragment mConfigureWifiEntryFragment;
+ @Mock
+ private NetworkDetailsTracker mNetworkDetailsTracker;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -55,6 +54,8 @@ public class ConfigureWifiEntryFragmentTest {
bundle.putInt(KEY_SECURITY, 1 /* WEP */);
mConfigureWifiEntryFragment = spy(new ConfigureWifiEntryFragment());
mConfigureWifiEntryFragment.setArguments(bundle);
+ mConfigureWifiEntryFragment.mNetworkDetailsTracker = mNetworkDetailsTracker;
+
FragmentController.setupFragment(mConfigureWifiEntryFragment);
}