Merge "Profile select only shows with multiple profiles present." into qt-r1-dev
diff --git a/res/layout-land/confirm_lock_pattern.xml b/res/layout-land/confirm_lock_pattern.xml
index 20a7bfc..6ca9be4 100644
--- a/res/layout-land/confirm_lock_pattern.xml
+++ b/res/layout-land/confirm_lock_pattern.xml
@@ -87,11 +87,9 @@
<com.android.internal.widget.LockPatternView
android:id="@+id/lockPattern"
- android:layout_width="288dp"
- android:layout_height="288dp"
- android:layout_marginStart="-42dp"
- android:layout_marginEnd="-42dp"
- android:layout_gravity="center_vertical"/>
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"/>
<TextView
style="@style/TextAppearance.ErrorText"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9d9ca7b..edc62c5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7976,6 +7976,15 @@
<!-- Configure Notifications: Title for the option controlling notifications on the lockscreen. [CHAR LIMIT=30] -->
<string name="lock_screen_notifications_title">Lock screen</string>
+ <!-- Configure lock screen: Title for the option of unlocking directly to home. [CHAR LIMIT=30] -->
+ <string name="lockscreen_bypass_title">Skip lock screen</string>
+
+ <!-- Configure lock screen: Summary for the option of unlocking directly to home. [CHAR LIMIT=60] -->
+ <string name="lockscreen_bypass_summary">After face unlock, go directly to last used screen</string>
+
+ <!-- Configure lock screen: Search keywords for the option of unlocking directly to home. [CHAR LIMIT=60] -->
+ <string name="keywords_lockscreen_bypass">Lock screen, Lockscreen, Skip, Bypass</string>
+
<!-- Configure Notifications: Title for the option controlling notifications for work profile. [CHAR LIMIT=30] -->
<string name="locked_work_profile_notification_title">When work profile is locked</string>
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index aa789b9..7057ec5 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -62,6 +62,14 @@
android:summary="@string/summary_placeholder"
settings:searchable="false"/>
+ <!-- Bypass lock screen -->
+ <SwitchPreference
+ android:key="privacy_lockscreen_bypass"
+ android:title="@string/lockscreen_bypass_title"
+ android:summary="@string/lockscreen_bypass_summary"
+ settings:keywords="@string/keywords_lockscreen_bypass"
+ settings:controller="com.android.settings.security.LockscreenBypassPreferenceController" />
+
<!-- Privacy Service -->
<PreferenceCategory
android:key="privacy_services"
diff --git a/res/xml/security_lockscreen_settings.xml b/res/xml/security_lockscreen_settings.xml
index 611d33f..69e8a3b 100644
--- a/res/xml/security_lockscreen_settings.xml
+++ b/res/xml/security_lockscreen_settings.xml
@@ -30,6 +30,13 @@
android:summary="@string/summary_placeholder"
settings:keywords="@string/keywords_lock_screen_notif"/>
+ <SwitchPreference
+ android:key="security_lockscreen_bypass"
+ android:title="@string/lockscreen_bypass_title"
+ android:summary="@string/lockscreen_bypass_summary"
+ settings:searchable="false"
+ settings:controller="com.android.settings.security.LockscreenBypassPreferenceController" />
+
<com.android.settingslib.RestrictedSwitchPreference
android:key="security_lockscreen_add_users_when_locked"
android:title="@string/user_add_on_lockscreen_menu"
diff --git a/src/com/android/settings/FallbackHome.java b/src/com/android/settings/FallbackHome.java
index 59347ad..e3944a6 100644
--- a/src/com/android/settings/FallbackHome.java
+++ b/src/com/android/settings/FallbackHome.java
@@ -25,6 +25,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ResolveInfo;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -65,7 +66,7 @@
@Override
public void onColorsChanged(WallpaperColors colors, int which) {
if (colors != null) {
- View decorView = getWindow().getDecorView();
+ final View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
updateVisibilityFlagsFromColors(colors, decorView.getSystemUiVisibility()));
mWallManager.removeOnColorsChangedListener(this);
@@ -81,7 +82,7 @@
// we don't flash the wallpaper before SUW
mProvisioned = Settings.Global.getInt(getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
- int flags;
+ final int flags;
if (!mProvisioned) {
setTheme(R.style.FallbackHome_SetupWizard);
flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
@@ -91,18 +92,11 @@
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
- // Set the system ui flags to light status bar if the wallpaper supports dark text to match
- // current system ui color tints. Use a listener to wait for colors if not ready yet.
mWallManager = getSystemService(WallpaperManager.class);
if (mWallManager == null) {
Log.w(TAG, "Wallpaper manager isn't ready, can't listen to color changes!");
} else {
- WallpaperColors colors = mWallManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
- if (colors == null) {
- mWallManager.addOnColorsChangedListener(mColorsChangedListener, null /* handler */);
- } else {
- flags = updateVisibilityFlagsFromColors(colors, flags);
- }
+ loadWallpaperColors(flags);
}
getWindow().getDecorView().setSystemUiVisibility(flags);
@@ -139,6 +133,33 @@
}
};
+ private void loadWallpaperColors(int flags) {
+ final AsyncTask loadWallpaperColorsTask = new AsyncTask<Object, Void, Integer>() {
+ @Override
+ protected Integer doInBackground(Object... params) {
+ final WallpaperColors colors =
+ mWallManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+
+ // Use a listener to wait for colors if not ready yet.
+ if (colors == null) {
+ mWallManager.addOnColorsChangedListener(mColorsChangedListener,
+ null /* handler */);
+ return null;
+ }
+ return updateVisibilityFlagsFromColors(colors, flags);
+ }
+
+ @Override
+ protected void onPostExecute(Integer flagsToUpdate) {
+ if (flagsToUpdate == null) {
+ return;
+ }
+ getWindow().getDecorView().setSystemUiVisibility(flagsToUpdate);
+ }
+ };
+ loadWallpaperColorsTask.execute();
+ }
+
private void maybeFinish() {
if (getSystemService(UserManager.class).isUserUnlocked()) {
final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
@@ -162,6 +183,8 @@
}
}
+ // Set the system ui flags to light status bar if the wallpaper supports dark text to match
+ // current system ui color tints.
private int updateVisibilityFlagsFromColors(WallpaperColors colors, int flags) {
if ((colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0) {
return flags | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
diff --git a/src/com/android/settings/network/MobileNetworkListFragment.java b/src/com/android/settings/network/MobileNetworkListFragment.java
index c90827e..4690a28 100644
--- a/src/com/android/settings/network/MobileNetworkListFragment.java
+++ b/src/com/android/settings/network/MobileNetworkListFragment.java
@@ -18,6 +18,7 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.os.UserManager;
import android.provider.SearchIndexableResource;
import com.android.settings.R;
@@ -66,5 +67,10 @@
result.add(sir);
return result;
}
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return context.getSystemService(UserManager.class).isAdminUser();
+ }
};
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index f8e5c3a..838aa12 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -277,5 +277,11 @@
result.add(sir);
return result;
}
+
+ /** suppress full page if user is not admin */
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return context.getSystemService(UserManager.class).isAdminUser();
+ }
};
}
diff --git a/src/com/android/settings/notification/AudioHelper.java b/src/com/android/settings/notification/AudioHelper.java
index d178113..01945fd 100644
--- a/src/com/android/settings/notification/AudioHelper.java
+++ b/src/com/android/settings/notification/AudioHelper.java
@@ -22,6 +22,7 @@
import android.media.AudioSystem;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.Log;
import com.android.settings.Utils;
@@ -30,6 +31,7 @@
*/
public class AudioHelper {
+ private static final String TAG = "AudioHelper";
private Context mContext;
private AudioManager mAudioManager;
@@ -76,6 +78,15 @@
}
public int getMinVolume(int stream) {
- return mAudioManager.getStreamMinVolume(stream);
+ int minVolume;
+ try {
+ minVolume = mAudioManager.getStreamMinVolume(stream);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "Invalid stream type " + stream);
+ // Fallback to STREAM_VOICE_CALL because CallVolumePreferenceController.java default
+ // return STREAM_VOICE_CALL in getAudioStream
+ minVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL);
+ }
+ return minVolume;
}
}
diff --git a/src/com/android/settings/security/LockscreenBypassPreferenceController.java b/src/com/android/settings/security/LockscreenBypassPreferenceController.java
new file mode 100644
index 0000000..e347a73
--- /dev/null
+++ b/src/com/android/settings/security/LockscreenBypassPreferenceController.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 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.security;
+
+import android.content.Context;
+import android.hardware.face.FaceManager;
+import android.provider.Settings;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.core.TogglePreferenceController;
+
+public class LockscreenBypassPreferenceController extends TogglePreferenceController {
+
+ @VisibleForTesting
+ protected FaceManager mFaceManager;
+
+ public LockscreenBypassPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ mFaceManager = context.getSystemService(FaceManager.class);
+ }
+
+ @Override
+ public boolean isChecked() {
+ boolean defaultValue = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_faceAuthDismissesKeyguard);
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, defaultValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, isChecked ? 1 : 0);
+ return true;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
+ return mFaceManager.hasEnrolledTemplates() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
+ } else {
+ return UNSUPPORTED_ON_DEVICE;
+ }
+ }
+}
diff --git a/src/com/android/settings/slices/SlicePreferenceController.java b/src/com/android/settings/slices/SlicePreferenceController.java
index 89294c7..2432c99 100644
--- a/src/com/android/settings/slices/SlicePreferenceController.java
+++ b/src/com/android/settings/slices/SlicePreferenceController.java
@@ -40,7 +40,8 @@
LifecycleObserver, OnStart, OnStop, Observer<Slice> {
@VisibleForTesting
LiveData<Slice> mLiveData;
- private SlicePreference mSlicePreference;
+ @VisibleForTesting
+ SlicePreference mSlicePreference;
private Uri mUri;
public SlicePreferenceController(Context context, String preferenceKey) {
@@ -82,8 +83,6 @@
@Override
public void onChanged(Slice slice) {
- if (slice != null) {
- mSlicePreference.onSliceUpdated(slice);
- }
+ mSlicePreference.onSliceUpdated(slice);
}
}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkListFragmentTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkListFragmentTest.java
new file mode 100644
index 0000000..a65ff24
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkListFragmentTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settings.search.BaseSearchIndexProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.util.ReflectionHelpers;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class MobileNetworkListFragmentTest {
+ @Mock
+ private Context mContext;
+ @Mock
+ private UserManager mUserManager;
+
+ private MobileNetworkListFragment mFragment;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mFragment = new MobileNetworkListFragment();
+ }
+
+ @Test
+ public void isPageSearchEnabled_adminUser_shouldReturnTrue() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ final BaseSearchIndexProvider provider =
+ (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
+
+ final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
+ ReflectionHelpers.ClassParameter.from(Context.class, mContext));
+ final boolean isEnabled = (Boolean) obj;
+
+ assertThat(isEnabled).isTrue();
+ }
+
+ @Test
+ public void isPageSearchEnabled_nonAdminUser_shouldReturnFalse() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ when(mUserManager.isAdminUser()).thenReturn(false);
+ final BaseSearchIndexProvider provider =
+ (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
+
+ final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
+ ReflectionHelpers.ClassParameter.from(Context.class, mContext));
+ final boolean isEnabled = (Boolean) obj;
+
+ assertThat(isEnabled).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
index a999a9e..4afe0fc 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
@@ -30,6 +30,7 @@
import android.content.Context;
import android.net.NetworkPolicyManager;
import android.os.Bundle;
+import android.os.UserManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
@@ -38,6 +39,7 @@
import com.android.settings.core.FeatureFlags;
import com.android.settings.datausage.DataUsageSummaryPreferenceController;
import com.android.settings.development.featureflags.FeatureFlagPersistent;
+import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -50,6 +52,7 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
import java.util.List;
@@ -135,4 +138,34 @@
mFragment.onActivityResult(REQUEST_CODE_DELETE_SUBSCRIPTION, 0, null);
verify(mActivity).finish();
}
+
+ @Test
+ public void isPageSearchEnabled_adminUser_shouldReturnTrue() {
+ final UserManager userManager = mock(UserManager.class);
+ when(mContext.getSystemService(UserManager.class)).thenReturn(userManager);
+ when(userManager.isAdminUser()).thenReturn(true);
+ final BaseSearchIndexProvider provider =
+ (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
+
+ final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
+ ReflectionHelpers.ClassParameter.from(Context.class, mContext));
+ final boolean isEnabled = (Boolean) obj;
+
+ assertThat(isEnabled).isTrue();
+ }
+
+ @Test
+ public void isPageSearchEnabled_nonAdminUser_shouldReturnFalse() {
+ final UserManager userManager = mock(UserManager.class);
+ when(mContext.getSystemService(UserManager.class)).thenReturn(userManager);
+ when(userManager.isAdminUser()).thenReturn(false);
+ final BaseSearchIndexProvider provider =
+ (BaseSearchIndexProvider) mFragment.SEARCH_INDEX_DATA_PROVIDER;
+
+ final Object obj = ReflectionHelpers.callInstanceMethod(provider, "isPageSearchEnabled",
+ ReflectionHelpers.ClassParameter.from(Context.class, mContext));
+ final boolean isEnabled = (Boolean) obj;
+
+ assertThat(isEnabled).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/notification/AudioHelperTest.java b/tests/robotests/src/com/android/settings/notification/AudioHelperTest.java
new file mode 100644
index 0000000..79d0198
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/AudioHelperTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 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.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class AudioHelperTest {
+
+ private static final int START = -10;
+ private static final int END = 10;
+ private static final int DEFAULT = -100;
+
+ private Context mContext;
+ private AudioHelper mAudioHelper;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mAudioHelper = new AudioHelper(mContext);
+ }
+
+ @Test
+ public void getMaxVolume_anyStreamType_getValue() {
+ int volume = DEFAULT;
+
+ for (int i = START; i < END; i++) {
+ volume = mAudioHelper.getMaxVolume(i);
+ assertThat(volume).isNotEqualTo(DEFAULT);
+ }
+ }
+
+ @Test
+ public void getMinVolume_anyStreamType_getValue() {
+ int volume = DEFAULT;
+
+ for (int i = START; i < END; i++) {
+ volume = mAudioHelper.getMinVolume(i);
+ assertThat(volume).isNotEqualTo(DEFAULT);
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/security/LockscreenBypassPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/LockscreenBypassPreferenceControllerTest.java
new file mode 100644
index 0000000..1b8817b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/LockscreenBypassPreferenceControllerTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 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.security;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.hardware.face.FaceManager;
+import android.provider.Settings;
+
+import androidx.preference.SwitchPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class LockscreenBypassPreferenceControllerTest {
+
+ @Mock
+ private FaceManager mFaceManager;
+ private SwitchPreference mPreference;
+
+ private Context mContext;
+ private LockscreenBypassPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mPreference = new SwitchPreference(mContext);
+
+ mController = new LockscreenBypassPreferenceController(mContext, "TestKey");
+ ReflectionHelpers.setField(mController, "mFaceManager", mFaceManager);
+ }
+
+ @Test
+ public void isAvailable_whenHardwareDetected() {
+ assertThat(mController.isAvailable()).isFalse();
+ when(mFaceManager.isHardwareDetected()).thenReturn(true);
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void onPreferenceChange_settingIsUpdated() {
+ boolean defaultValue = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_faceAuthDismissesKeyguard);
+ boolean state = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, defaultValue ? 1 : 0) != 0;
+
+ assertThat(mController.onPreferenceChange(mPreference, !state)).isTrue();
+ boolean newState = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0) != 0;
+ assertThat(newState).isEqualTo(!state);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
index 364fb60..65eaddd 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
@@ -41,6 +41,8 @@
@Mock
private LiveData<Slice> mLiveData;
+ @Mock
+ private SlicePreference mSlicePreference;
private Context mContext;
private SlicePreferenceController mController;
private Uri mUri;
@@ -53,6 +55,7 @@
mContext = spy(RuntimeEnvironment.application);
mController = new SlicePreferenceController(mContext, KEY);
mController.mLiveData = mLiveData;
+ mController.mSlicePreference = mSlicePreference;
mUri = Uri.EMPTY;
}
@@ -78,4 +81,11 @@
mController.onStop();
verify(mLiveData).removeObserver(mController);
}
+
+ @Test
+ public void onChanged_nullSlice_updateSlice() {
+ mController.onChanged(null);
+
+ verify(mController.mSlicePreference).onSliceUpdated(null);
+ }
}
\ No newline at end of file