Migrate robolectric tests to junit tests

This change do the 2 things:

1. Add new junit tests files which replace robolectric
   RobolectricTestRunner & RuntimeEnvironment with
   AndroidX objects without problem.
2. Remove the robolectric test files which have it's new junit files.

This change migrate 103 files, there are still 1209
files to go.

Bug: 174728471
Test: atest
      make RunSettingsRoboTests
Change-Id: I15ed3f4745b85862f720aabbf710ce1475aced93
This commit is contained in:
Arc Wang
2020-12-09 17:03:43 +08:00
parent f705f7933e
commit 62c78ff3fa
108 changed files with 3082 additions and 338 deletions

View File

@@ -0,0 +1,73 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import android.text.Spannable;
import android.text.style.ClickableSpan;
import android.widget.TextView;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class LinkifyUtilsTest {
private static final String TEST_STRING = "to LINK_BEGINscanning settingsLINK_END.";
private static final String WRONG_STRING = "to scanning settingsLINK_END.";
private final LinkifyUtils.OnClickListener mClickListener = () -> { /* Do nothing */ };
private StringBuilder mSpanStringBuilder;
private StringBuilder mWrongSpanStringBuilder;
TextView mTextView;
@Before
public void setUp() throws Exception {
mSpanStringBuilder = new StringBuilder(TEST_STRING);
mWrongSpanStringBuilder = new StringBuilder(WRONG_STRING);
mTextView = new TextView(ApplicationProvider.getApplicationContext());
}
@Test
public void linkify_whenSpanStringCorrect_shouldReturnTrue() {
final boolean linkifyResult = LinkifyUtils.linkify(mTextView, mSpanStringBuilder,
mClickListener);
assertThat(linkifyResult).isTrue();
}
@Test
public void linkify_whenSpanStringWrong_shouldReturnFalse() {
final boolean linkifyResult = LinkifyUtils.linkify(mTextView, mWrongSpanStringBuilder,
mClickListener);
assertThat(linkifyResult).isFalse();
}
@Test
public void linkify_whenSpanStringCorrect_shouldContainClickableSpan() {
LinkifyUtils.linkify(mTextView, mSpanStringBuilder, mClickListener);
final Spannable spannableContent = (Spannable) mTextView.getText();
final int len = spannableContent.length();
final Object[] spans = spannableContent.getSpans(0, len, Object.class);
assertThat(spans[1] instanceof ClickableSpan).isTrue();
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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;
/**
* Convenience methods and constants for testing.
*/
public class TestUtils {
public static final long KILOBYTE = 1024L; // TODO: Change to 1000 in O Robolectric.
public static final long MEGABYTE = KILOBYTE * KILOBYTE;
public static final long GIGABYTE = KILOBYTE * MEGABYTE;
}

View File

@@ -0,0 +1,92 @@
/*
* 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.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class AccessibilityShortcutPreferenceControllerTest {
private Context mContext;
private SwitchPreference mPreference;
private AccessibilityShortcutPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mPreference = new SwitchPreference(mContext);
mController = new AccessibilityShortcutPreferenceController(mContext,
"accessibility_shortcut_preference");
}
@Test
public void isChecked_enabledShortcutOnLockScreen_shouldReturnTrue() {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ON, UserHandle.USER_CURRENT);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void isChecked_disabledShortcutOnLockScreen_shouldReturnFalse() {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, OFF,
UserHandle.USER_CURRENT);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_setTrue_shouldEnableShortcutOnLockScreen() {
mController.setChecked(true);
assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, OFF,
UserHandle.USER_CURRENT)).isEqualTo(ON);
}
@Test
public void setChecked_setFalse_shouldDisableShortcutOnLockScreen() {
mController.setChecked(false);
assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ON,
UserHandle.USER_CURRENT)).isEqualTo(OFF);
}
}

View File

@@ -0,0 +1,103 @@
/*
* 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.accessibility;
import static com.android.settings.accessibility.DisableAnimationsPreferenceController.ANIMATION_OFF_VALUE;
import static com.android.settings.accessibility.DisableAnimationsPreferenceController.ANIMATION_ON_VALUE;
import static com.android.settings.accessibility.DisableAnimationsPreferenceController.TOGGLE_ANIMATION_TARGETS;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class DisableAnimationsPreferenceControllerTest {
private Context mContext;
private SwitchPreference mPreference;
private DisableAnimationsPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mPreference = new SwitchPreference(mContext);
mController = new DisableAnimationsPreferenceController(mContext, "disable_animation");
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void isChecked_enabledAnimation_shouldReturnFalse() {
for (String animationPreference : TOGGLE_ANIMATION_TARGETS) {
Settings.Global.putString(mContext.getContentResolver(), animationPreference,
ANIMATION_ON_VALUE);
}
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void isChecked_disabledAnimation_shouldReturnTrue() {
for (String animationPreference : TOGGLE_ANIMATION_TARGETS) {
Settings.Global.putString(mContext.getContentResolver(), animationPreference,
ANIMATION_OFF_VALUE);
}
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void setChecked_disabledAnimation_shouldDisableAnimationTargets() {
mController.setChecked(true);
for (String animationSetting : TOGGLE_ANIMATION_TARGETS) {
assertThat(Settings.Global.getString(mContext.getContentResolver(), animationSetting))
.isEqualTo(ANIMATION_OFF_VALUE);
}
}
@Test
public void setChecked_enabledAnimation_shouldEnableAnimationTargets() {
mController.setChecked(false);
for (String animationSetting : TOGGLE_ANIMATION_TARGETS) {
assertThat(Settings.Global.getString(mContext.getContentResolver(), animationSetting))
.isEqualTo(ANIMATION_ON_VALUE);
}
}
}

View File

@@ -0,0 +1,94 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class FontWeightAdjustmentPreferenceControllerTest {
private static final int ON = FontWeightAdjustmentPreferenceController.BOLD_TEXT_ADJUSTMENT;
private static final int OFF = 0;
private Context mContext;
private SwitchPreference mPreference;
private FontWeightAdjustmentPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mPreference = new SwitchPreference(mContext);
mController = new FontWeightAdjustmentPreferenceController(
mContext, "font_weight_adjustment");
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void isChecked_enabledBoldText_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.FONT_WEIGHT_ADJUSTMENT, ON);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void isChecked_disabledBoldText_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.FONT_WEIGHT_ADJUSTMENT, OFF);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_setTrue_shouldEnableBoldText() {
mController.setChecked(true);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FONT_WEIGHT_ADJUSTMENT, OFF)).isEqualTo(ON);
}
@Test
public void setChecked_setFalse_shouldDisableBoldText() {
mController.setChecked(false);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FONT_WEIGHT_ADJUSTMENT, OFF)).isEqualTo(OFF);
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class HighTextContrastPreferenceControllerTest {
private static final int ON = 1;
private static final int OFF = 0;
private static final int UNKNOWN = -1;
private Context mContext;
private SwitchPreference mPreference;
private HighTextContrastPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mPreference = new SwitchPreference(mContext);
mController = new HighTextContrastPreferenceController(mContext, "text_contrast");
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void isChecked_enabledTextContrast_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, ON);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void isChecked_disabledTextContrast_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, OFF);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_setTrue_shouldEnableTextContrast() {
mController.setChecked(true);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, UNKNOWN)).isEqualTo(ON);
}
@Test
public void setChecked_setFalse_shouldDisableTextContrast() {
mController.setChecked(false);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, UNKNOWN)).isEqualTo(OFF);
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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.accessibility;
import static com.android.settings.accessibility.LargePointerIconPreferenceController.OFF;
import static com.android.settings.accessibility.LargePointerIconPreferenceController.ON;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class LargePointerIconPreferenceControllerTest {
private static final int UNKNOWN = -1;
private Context mContext;
private SwitchPreference mPreference;
private LargePointerIconPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mPreference = new SwitchPreference(mContext);
mController = new LargePointerIconPreferenceController(mContext, "large_pointer");
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void isChecked_enabledLargePointer_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, ON);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void isChecked_disabledLargePointer_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, OFF);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_enabled_shouldEnableLargePointer() {
mController.setChecked(true);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, UNKNOWN)).isEqualTo(ON);
}
@Test
public void setChecked_disabled_shouldDisableLargePointer() {
mController.setChecked(false);
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, UNKNOWN)).isEqualTo(OFF);
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class MagnificationPreferenceControllerTest {
private Context mContext;
private MagnificationPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new MagnificationPreferenceController(mContext, "magnification");
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
}

View File

@@ -0,0 +1,63 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Tests for {@link PreferredShortcut} */
@RunWith(AndroidJUnit4.class)
public class PreferredShortcutTest {
private static final String STUB_COMPONENT_NAME = new ComponentName("com.example",
"com.example.testActivity").flattenToString();
private static final int STUB_TYPE = 3;
@Test
public void fromString_matchMemberObject() {
final String preferredShortcutString = STUB_COMPONENT_NAME + ":" + STUB_TYPE;
final PreferredShortcut shortcut = PreferredShortcut.fromString(preferredShortcutString);
assertThat(shortcut.getComponentName()).isEqualTo(STUB_COMPONENT_NAME);
assertThat(shortcut.getType()).isEqualTo(STUB_TYPE);
}
@Test
public void toString_matchString() {
final PreferredShortcut shortcut = new PreferredShortcut(STUB_COMPONENT_NAME, STUB_TYPE);
final String preferredShortcutString = shortcut.toString();
assertThat(preferredShortcutString).isEqualTo(STUB_COMPONENT_NAME + ":" + STUB_TYPE);
}
@Test
public void assertSameObject() {
final String preferredShortcutString = STUB_COMPONENT_NAME + ":" + STUB_TYPE;
final PreferredShortcut targetShortcut = PreferredShortcut.fromString(
preferredShortcutString);
assertThat(targetShortcut).isEqualTo(new PreferredShortcut(STUB_COMPONENT_NAME, STUB_TYPE));
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Tests for {@link PreferredShortcuts} */
@RunWith(AndroidJUnit4.class)
public class PreferredShortcutsTest {
private static final String PACKAGE_NAME_1 = "com.test1.example";
private static final String CLASS_NAME_1 = PACKAGE_NAME_1 + ".test1";
private static final ComponentName COMPONENT_NAME_1 = new ComponentName(PACKAGE_NAME_1,
CLASS_NAME_1);
private static final String PACKAGE_NAME_2 = "com.test2.example";
private static final String CLASS_NAME_2 = PACKAGE_NAME_2 + ".test2";
private static final ComponentName COMPONENT_NAME_2 = new ComponentName(PACKAGE_NAME_2,
CLASS_NAME_2);
private Context mContext = ApplicationProvider.getApplicationContext();
@Test
public void retrieveUserShortcutType_fromSingleData_matchSavedType() {
final int type = 1;
final PreferredShortcut shortcut = new PreferredShortcut(COMPONENT_NAME_1.flattenToString(),
type);
PreferredShortcuts.saveUserShortcutType(mContext, shortcut);
final int retrieveType = PreferredShortcuts.retrieveUserShortcutType(mContext,
COMPONENT_NAME_1.flattenToString(), 0);
assertThat(retrieveType).isEqualTo(type);
}
@Test
public void retrieveUserShortcutType_fromMultiData_matchSavedType() {
final int type1 = 1;
final int type2 = 2;
final PreferredShortcut shortcut1 = new PreferredShortcut(
COMPONENT_NAME_1.flattenToString(), type1);
final PreferredShortcut shortcut2 = new PreferredShortcut(
COMPONENT_NAME_2.flattenToString(), type2);
PreferredShortcuts.saveUserShortcutType(mContext, shortcut1);
PreferredShortcuts.saveUserShortcutType(mContext, shortcut2);
final int retrieveType = PreferredShortcuts.retrieveUserShortcutType(mContext,
COMPONENT_NAME_1.flattenToString(), 0);
assertThat(retrieveType).isEqualTo(type1);
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class PrimaryMonoPreferenceControllerTest {
private static final int ON = 1;
private static final int OFF = 0;
private static final int UNKNOWN = -1;
private Context mContext;
private SwitchPreference mPreference;
private PrimaryMonoPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mPreference = new SwitchPreference(mContext);
mController = new PrimaryMonoPreferenceController(mContext, "test_key");
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void isChecked_enabledMonoAudio_shouldReturnTrue() {
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.MASTER_MONO, ON, UserHandle.USER_CURRENT);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void isChecked_disabledMonoAudio_shouldReturnFalse() {
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.MASTER_MONO, OFF, UserHandle.USER_CURRENT);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_setTrue_shouldEnableMonoAudio() {
mController.setChecked(true);
assertThat(Settings.System.getIntForUser(mContext.getContentResolver(),
Settings.System.MASTER_MONO, UNKNOWN, UserHandle.USER_CURRENT)).isEqualTo(ON);
}
@Test
public void setChecked_setFalse_shouldDisableMonoAudio() {
mController.setChecked(false);
assertThat(Settings.System.getIntForUser(mContext.getContentResolver(),
Settings.System.MASTER_MONO, UNKNOWN, UserHandle.USER_CURRENT)).isEqualTo(OFF);
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
/** TODO(b/170970675): Update and add tests after ColorDisplayService work is integrated */
public class ReduceBrightColorsIntensityPreferenceControllerTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private final ReduceBrightColorsIntensityPreferenceController mPreferenceController =
new ReduceBrightColorsIntensityPreferenceController(mContext,
"rbc_intensity");
@Test
public void isAvailable_configuredRbcAvailable_enabledRbc_shouldReturnTrue() {
assertThat(mPreferenceController.isAvailable()).isTrue();
}
@Test
public void isAvailable_configuredRbcAvailable_disabledRbc_shouldReturnFalse() {
assertThat(mPreferenceController.isAvailable()).isTrue();
}
@Test
public void isAvailable_configuredRbcUnavailable_enabledRbc_shouldReturnFalse() {
assertThat(mPreferenceController.isAvailable()).isTrue();
}
}

View File

@@ -0,0 +1,82 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ReduceBrightColorsPersistencePreferenceControllerTest {
private static final String PREF_KEY = "rbc_persist";
private static final String RBC_PERSIST =
Settings.Secure.REDUCE_BRIGHT_COLORS_PERSIST_ACROSS_REBOOTS;
private static final int ON = 1;
private static final int OFF = 0;
private static final int UNKNOWN = -1;
private final Context mContext = ApplicationProvider.getApplicationContext();
private final SwitchPreference mPreference = new SwitchPreference(mContext);
private final ReduceBrightColorsPersistencePreferenceController mController =
new ReduceBrightColorsPersistencePreferenceController(mContext, PREF_KEY);
@Test
public void isChecked_enabledRbc_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), RBC_PERSIST, ON);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void isChecked_disabledRbc_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), RBC_PERSIST, OFF);
mController.updateState(mPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_setTrue_shouldEnableRbc() {
mController.setChecked(true);
assertThat(
Settings.Secure.getInt(mContext.getContentResolver(), RBC_PERSIST, UNKNOWN))
.isEqualTo(ON);
}
@Test
public void setChecked_setFalse_shouldDisableRbc() {
mController.setChecked(false);
assertThat(
Settings.Secure.getInt(mContext.getContentResolver(), RBC_PERSIST, UNKNOWN))
.isEqualTo(OFF);
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SelectLongPressTimeoutPreferenceControllerTest {
private static final int VALID_VALUE = 1500;
private static final int INVALID_VALUE = 0;
private static final int DEFAULT_VALUE = 400;
private Context mContext;
private SelectLongPressTimeoutPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new SelectLongPressTimeoutPreferenceController(mContext, "press_timeout");
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_byDefault_shouldReturnShort() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LONG_PRESS_TIMEOUT, DEFAULT_VALUE);
final String expected = "Short";
assertThat(mController.getSummary()).isEqualTo(expected);
}
@Test
public void getSummary_validValue_shouldReturnLong() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LONG_PRESS_TIMEOUT, VALID_VALUE);
final String expected = "Long";
assertThat(mController.getSummary()).isEqualTo(expected);
}
@Test
public void getSummary_invalidValue_shouldReturnNull() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LONG_PRESS_TIMEOUT, INVALID_VALUE);
assertThat(mController.getSummary()).isNull();
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.accounts;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.lang.reflect.Modifier;
@RunWith(AndroidJUnit4.class)
public class RemoveUserFragmentTest {
@Test
public void testClassModifier_shouldBePublic() {
final int modifiers = RemoveUserFragment.class.getModifiers();
assertThat(Modifier.isPublic(modifiers)).isTrue();
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.accounts;
import static com.google.common.truth.Truth.assertThat;
import android.accounts.Account;
import android.content.Context;
import android.os.UserHandle;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SyncStateSwitchPreferenceTest {
private Context mContext;
private SyncStateSwitchPreference mPreference;
@Before
public void setup() {
mContext = ApplicationProvider.getApplicationContext();
}
@Test
public void setup_validAuthority_shouldBeVisible() {
mPreference = new SyncStateSwitchPreference(mContext, null /* attrs */);
mPreference.setup(new Account("name", "type"), "authority", mContext.getPackageName(),
UserHandle.USER_CURRENT);
assertThat(mPreference.isVisible()).isTrue();
}
@Test
public void setup_emptyAuthority_shouldBeInvisible() {
mPreference = new SyncStateSwitchPreference(mContext, null /* attrs */);
mPreference.setup(new Account("name", "type"), null /* authority */,
mContext.getPackageName(), UserHandle.USER_CURRENT);
assertThat(mPreference.isVisible()).isFalse();
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.applications;
import static com.google.common.truth.Truth.assertThat;
import android.app.AppOpsManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class AppStateInstallAppsBridgeTest {
@Test
public void testInstallAppsStateCanInstallApps() {
AppStateInstallAppsBridge.InstallAppsState appState =
new AppStateInstallAppsBridge.InstallAppsState();
assertThat(appState.canInstallApps()).isFalse();
appState.permissionRequested = true;
assertThat(appState.canInstallApps()).isFalse();
appState.appOpMode = AppOpsManager.MODE_ALLOWED;
assertThat(appState.canInstallApps()).isTrue();
appState.appOpMode = AppOpsManager.MODE_ERRORED;
assertThat(appState.canInstallApps()).isFalse();
}
@Test
public void testInstallAppsStateIsPotentialAppSource() {
AppStateInstallAppsBridge.InstallAppsState appState =
new AppStateInstallAppsBridge.InstallAppsState();
assertThat(appState.isPotentialAppSource()).isFalse();
appState.appOpMode = AppOpsManager.MODE_ERRORED;
assertThat(appState.isPotentialAppSource()).isTrue();
appState.permissionRequested = true;
appState.appOpMode = AppOpsManager.MODE_DEFAULT;
assertThat(appState.isPotentialAppSource()).isTrue();
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.applications;
import static org.junit.Assert.assertTrue;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.R;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class EnterpriseDefaultAppsTest {
@Test
public void testNumberOfIntentsCorrelateWithUI() {
final int[] concatenation_templates =
new int[]{0 /* no need for single app name */,
R.string.app_names_concatenation_template_2,
R.string.app_names_concatenation_template_3};
for (EnterpriseDefaultApps app : EnterpriseDefaultApps.values()) {
assertTrue("Number of intents should be limited by number of apps the UI can show",
app.getIntents().length <= concatenation_templates.length);
}
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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.applications.assist;
import android.net.Uri;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class AssistSettingObserverTest {
@Test
public void callConstructor_shouldNotCrash() {
new AssistSettingObserver() {
@Override
protected List<Uri> getSettingUris() {
return null;
}
@Override
public void onSettingChange() {
}
};
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.applications.manageapplications;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_INSTALL_SOURCES;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_POWER_ALLOWLIST;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_RECENT;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_USAGE_ACCESS;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_WITH_OVERLAY;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_WRITE_SETTINGS;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_GAMES;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_HIGH_POWER;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MANAGE_SOURCES;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MOVIES;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_OVERLAY;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_PHOTOGRAPHY;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_STORAGE;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_USAGE_ACCESS;
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_WRITE_SETTINGS;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class AppFilterRegistryTest {
@Test
public void getDefaultType_shouldMatchForAllListType() {
final AppFilterRegistry registry = AppFilterRegistry.getInstance();
assertThat(registry.getDefaultFilterType(LIST_TYPE_USAGE_ACCESS))
.isEqualTo(FILTER_APPS_USAGE_ACCESS);
assertThat(registry.getDefaultFilterType(LIST_TYPE_HIGH_POWER))
.isEqualTo(FILTER_APPS_POWER_ALLOWLIST);
assertThat(registry.getDefaultFilterType(LIST_TYPE_OVERLAY))
.isEqualTo(FILTER_APPS_WITH_OVERLAY);
assertThat(registry.getDefaultFilterType(LIST_TYPE_WRITE_SETTINGS))
.isEqualTo(FILTER_APPS_WRITE_SETTINGS);
assertThat(registry.getDefaultFilterType(LIST_TYPE_MANAGE_SOURCES))
.isEqualTo(FILTER_APPS_INSTALL_SOURCES);
assertThat(registry.getDefaultFilterType(LIST_TYPE_MAIN)).isEqualTo(FILTER_APPS_ALL);
assertThat(registry.getDefaultFilterType(LIST_TYPE_NOTIFICATION))
.isEqualTo(FILTER_APPS_RECENT);
assertThat(registry.getDefaultFilterType(LIST_TYPE_STORAGE)).isEqualTo(FILTER_APPS_ALL);
assertThat(registry.getDefaultFilterType(LIST_TYPE_GAMES)).isEqualTo(FILTER_APPS_ALL);
assertThat(registry.getDefaultFilterType(LIST_TYPE_MOVIES)).isEqualTo(FILTER_APPS_ALL);
assertThat(registry.getDefaultFilterType(LIST_TYPE_PHOTOGRAPHY)).isEqualTo(FILTER_APPS_ALL);
}
}

View File

@@ -0,0 +1,46 @@
/*
* 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.biometrics.face;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class FaceSettingsAttentionPreferenceControllerTest {
private Context mContext;
private FaceSettingsAttentionPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new FaceSettingsAttentionPreferenceController(mContext);
}
@Test
public void isSliceable_returnFalse() {
assertThat(mController.isSliceable()).isFalse();
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.core;
import android.content.Context;
public class BadPreferenceController extends BasePreferenceController {
public BadPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
throw new IllegalArgumentException("error");
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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.core;
import static com.google.common.truth.Truth.assertWithMessage;
import android.content.Context;
import com.android.settings.core.codeinspection.CodeInspector;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
public class BasePreferenceControllerSignatureInspector extends CodeInspector {
private final List<String> mExemptList;
public BasePreferenceControllerSignatureInspector(List<Class<?>> classes) {
super(classes);
mExemptList = new ArrayList<>();
initializeExemptList(mExemptList,
"exempt_invalid_base_preference_controller_constructor");
}
@Override
public void run() {
StringBuilder badClasses = new StringBuilder();
for (Class c : mClasses) {
if (!isConcreteSettingsClass(c)) {
// Not a Settings class, or is abstract, don't care.
continue;
}
if (!BasePreferenceController.class.isAssignableFrom(c)) {
// Not a BasePreferenceController, don't care.
continue;
}
final String className = c.getName();
if (mExemptList.remove(className)) {
continue;
}
final Constructor[] constructors = c.getDeclaredConstructors();
if (constructors == null || constructors.length == 0) {
badClasses.append(c.getName()).append(",");
}
boolean hasValidConstructor = false;
for (Constructor constructor : constructors) {
if (hasValidConstructorSignature(constructor)) {
hasValidConstructor = true;
break;
}
}
if (!hasValidConstructor) {
badClasses.append(className).append(",");
}
}
assertWithMessage("All BasePreferenceController (and subclasses) constructor must either"
+ " only take Context, or (Context, String). No other types are allowed")
.that(badClasses.toString())
.isEmpty();
assertWithMessage("Something in the exempt list is no longer relevant. Please remove"
+ "it from packages/apps/Settings/tests/robotests/assets/"
+ "exempt_invalid_base_preference_controller_constructor")
.that(mExemptList)
.isEmpty();
}
private static boolean hasValidConstructorSignature(Constructor constructor) {
final Class[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length == 1) {
return Context.class.isAssignableFrom(parameterTypes[0]);
} else if (parameterTypes.length == 2) {
return Context.class.isAssignableFrom(parameterTypes[0])
&& String.class.isAssignableFrom(parameterTypes[1]);
}
return false;
}
}

View File

@@ -0,0 +1,109 @@
/*
* 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.core;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.slices.SliceData;
import com.android.settings.widget.SeekBarPreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SettingsSliderPreferenceControllerTest {
private FakeSliderPreferenceController mSliderController;
private SeekBarPreference mPreference;
@Before
public void setUp() {
mPreference = new SeekBarPreference(ApplicationProvider.getApplicationContext());
mSliderController = new FakeSliderPreferenceController(
ApplicationProvider.getApplicationContext(), "key");
mPreference.setContinuousUpdates(true);
mPreference.setMin(mSliderController.getMin());
mPreference.setMax(mSliderController.getMax());
}
@Test
public void onPreferenceChange_updatesPosition() {
final int newValue = 28;
mSliderController.onPreferenceChange(mPreference, newValue);
assertThat(mSliderController.getSliderPosition()).isEqualTo(newValue);
}
@Test
public void updateState_setsPreferenceToCurrentValue() {
final int newValue = 28;
mSliderController.setSliderPosition(newValue);
mSliderController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(newValue);
}
@Test
public void testSliceType_returnsSliceType() {
assertThat(mSliderController.getSliceType()).isEqualTo(SliceData.SliceType.SLIDER);
}
private class FakeSliderPreferenceController extends SliderPreferenceController {
private static final int MAX_STEPS = 2112;
private int mPosition;
private FakeSliderPreferenceController(Context context, String key) {
super(context, key);
}
@Override
public int getSliderPosition() {
return mPosition;
}
@Override
public boolean setSliderPosition(int position) {
mPosition = position;
return true;
}
@Override
public int getMax() {
return MAX_STEPS;
}
@Override
public int getMin() {
return 0;
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
}
}

View File

@@ -0,0 +1,127 @@
/*
* 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.core;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.slices.SliceData;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class TogglePreferenceControllerTest {
private FakeToggle mToggleController;
private Context mContext;
private SwitchPreference mPreference;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mPreference = new SwitchPreference(mContext);
mToggleController = new FakeToggle(mContext, "key");
}
@Test
public void testSetsPreferenceValue_setsChecked() {
mToggleController.setChecked(true);
mPreference.setChecked(false);
mToggleController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void testSetsPreferenceValue_setsNotChecked() {
mToggleController.setChecked(false);
mPreference.setChecked(true);
mToggleController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void testUpdatesPreferenceOnChange_turnsOn() {
boolean newValue = true;
mToggleController.setChecked(!newValue);
mToggleController.onPreferenceChange(mPreference, newValue);
assertThat(mToggleController.isChecked()).isEqualTo(newValue);
}
@Test
public void testUpdatesPreferenceOnChange_turnsOff() {
boolean newValue = false;
mToggleController.setChecked(!newValue);
mToggleController.onPreferenceChange(mPreference, newValue);
assertThat(mToggleController.isChecked()).isEqualTo(newValue);
}
@Test
public void testSliceType_returnsSliceType() {
assertThat(mToggleController.getSliceType()).isEqualTo(
SliceData.SliceType.SWITCH);
}
@Test
public void isSliceable_returnTrue() {
assertThat(mToggleController.isSliceable()).isTrue();
}
@Test
public void isPublicSlice_returnFalse() {
assertThat(mToggleController.isPublicSlice()).isFalse();
}
private static class FakeToggle extends TogglePreferenceController {
private boolean mCheckedFlag;
private FakeToggle(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public boolean isChecked() {
return mCheckedFlag;
}
@Override
public boolean setChecked(boolean isChecked) {
mCheckedFlag = isChecked;
return true;
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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.core.codeinspection;
import com.google.common.reflect.ClassPath;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Scans and builds all classes in current classloader.
*/
public class ClassScanner {
public List<Class<?>> getClassesForPackage(String packageName) throws ClassNotFoundException {
final List<Class<?>> classes = new ArrayList<>();
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ClassPath classPath = ClassPath.from(classLoader);
// Some anonymous classes don't return true when calling isAnonymousClass(), but they
// always seem to be nested anonymous classes like com.android.settings.Foo$1$2. In
// general we don't want any anonymous classes so we just filter these out by searching
// for $[0-9] in the name.
Pattern anonymousClassPattern = Pattern.compile(".*\\$\\d+.*");
Matcher anonymousClassMatcher = anonymousClassPattern.matcher("");
for (ClassPath.ClassInfo info : classPath.getAllClasses()) {
if (info.getPackageName().startsWith(packageName)) {
try {
Class clazz = classLoader.loadClass(info.getName());
if (clazz.isAnonymousClass() || anonymousClassMatcher.reset(
clazz.getName()).matches()) {
continue;
}
classes.add(clazz);
} catch (NoClassDefFoundError e) {
// do nothing. this class hasn't been found by the
// loader, and we don't care.
}
}
}
} catch (final IOException e) {
throw new ClassNotFoundException("Error when parsing " + packageName, e);
}
return classes;
}
}

View File

@@ -0,0 +1,94 @@
/*
* 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.core.codeinspection;
import static com.google.common.truth.Truth.assertWithMessage;
import androidx.test.core.app.ApplicationProvider;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Modifier;
import java.util.List;
/**
* Inspector takes a list of class objects and perform static code analysis in its {@link #run()}
* method.
*/
public abstract class CodeInspector {
protected static final String PACKAGE_NAME = "com.android.settings";
private static final String TEST_CLASS_SUFFIX = "Test";
private static final String TEST_INNER_CLASS_SIGNATURE = "Test$";
protected final List<Class<?>> mClasses;
public CodeInspector(List<Class<?>> classes) {
mClasses = classes;
}
/**
* Code inspection runner method.
*/
public abstract void run();
protected void assertNoObsoleteInExemptList(String listName, List<String> list) {
final StringBuilder obsoleteExemptItems = new StringBuilder(listName).append(
" contains item that should not be exempted.\n");
for (String c : list) {
obsoleteExemptItems.append(c).append("\n");
}
assertWithMessage(obsoleteExemptItems.toString()).that(list).isEmpty();
}
protected boolean isConcreteSettingsClass(Class clazz) {
// Abstract classes
if (Modifier.isAbstract(clazz.getModifiers())) {
return false;
}
final String packageName = clazz.getPackage().getName();
// Classes that are not in Settings
if (!packageName.contains(PACKAGE_NAME + ".") && !packageName.endsWith(PACKAGE_NAME)) {
return false;
}
final String className = clazz.getName();
// Classes from tests
if (className.endsWith(TEST_CLASS_SUFFIX)) {
return false;
}
if (className.contains(TEST_INNER_CLASS_SIGNATURE)) {
return false;
}
return true;
}
public static void initializeExemptList(List<String> exemptList, String filename) {
try {
final InputStream in = ApplicationProvider.getApplicationContext()
.getAssets().open(filename);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
exemptList.add(line);
}
} catch (Exception e) {
throw new IllegalArgumentException("Error initializing exempt list " + filename, e);
}
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.core.codeinspection;
import static org.junit.Assert.fail;
import android.util.ArraySet;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnAttach;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
import com.android.settingslib.core.lifecycle.events.OnDestroy;
import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.android.settingslib.core.lifecycle.events.SetPreferenceScreen;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public class LifecycleObserverCodeInspector extends CodeInspector {
private static final List<Class> LIFECYCLE_EVENTS = Arrays.asList(
OnAttach.class,
OnCreate.class,
OnCreateOptionsMenu.class,
OnDestroy.class,
OnOptionsItemSelected.class,
OnPause.class,
OnPrepareOptionsMenu.class,
OnResume.class,
OnSaveInstanceState.class,
OnStart.class,
OnStop.class,
SetPreferenceScreen.class
);
public LifecycleObserverCodeInspector(List<Class<?>> classes) {
super(classes);
}
@Override
public void run() {
final Set<String> notImplementingLifecycleObserver = new ArraySet<>();
for (Class clazz : mClasses) {
if (!isConcreteSettingsClass(clazz)) {
continue;
}
boolean classObservesLifecycleEvent = false;
for (Class event : LIFECYCLE_EVENTS) {
if (event.isAssignableFrom(clazz)) {
classObservesLifecycleEvent = true;
break;
}
}
if (classObservesLifecycleEvent && !LifecycleObserver.class.isAssignableFrom(clazz)) {
// Observes LifecycleEvent but not implementing LifecycleObserver. Something is
// wrong.
notImplementingLifecycleObserver.add(clazz.getName());
}
}
if (!notImplementingLifecycleObserver.isEmpty()) {
final String errorTemplate =
"The following class(es) implements lifecycle.events.*, but don't "
+ "implement LifecycleObserver. Something is wrong:\n";
final StringBuilder error = new StringBuilder(errorTemplate);
for (String name : notImplementingLifecycleObserver) {
error.append(name).append('\n');
}
fail(error.toString());
}
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.core.instrumentation;
import static com.google.common.truth.Truth.assertWithMessage;
import android.util.ArraySet;
import androidx.fragment.app.Fragment;
import com.android.settings.core.codeinspection.CodeInspector;
import com.android.settingslib.core.instrumentation.Instrumentable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* {@link CodeInspector} that verifies all fragments implements Instrumentable.
*/
public class InstrumentableFragmentCodeInspector extends CodeInspector {
private final List<String> mNotImplementingInstrumentableExemptList;
public InstrumentableFragmentCodeInspector(List<Class<?>> classes) {
super(classes);
mNotImplementingInstrumentableExemptList = new ArrayList<>();
initializeExemptList(mNotImplementingInstrumentableExemptList,
"exempt_not_implementing_instrumentable");
}
@Override
public void run() {
final Set<String> broken = new ArraySet<>();
for (Class clazz : mClasses) {
if (!isConcreteSettingsClass(clazz)) {
continue;
}
final String className = clazz.getName();
// If it's a fragment, it must also be instrumentable.
final boolean allowlisted =
mNotImplementingInstrumentableExemptList.remove(className);
if (Fragment.class.isAssignableFrom(clazz)
&& !Instrumentable.class.isAssignableFrom(clazz)
&& !allowlisted) {
broken.add(className);
}
}
final StringBuilder sb = new StringBuilder(
"All fragments should implement Instrumentable, but the following are not:\n");
for (String c : broken) {
sb.append(c).append("\n");
}
assertWithMessage(sb.toString()).that(broken.isEmpty()).isTrue();
assertNoObsoleteInExemptList("exempt_not_implementing_instrumentable",
mNotImplementingInstrumentableExemptList);
}
}

View File

@@ -0,0 +1,339 @@
/*
* 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.dashboard;
import static com.android.settingslib.drawer.CategoryKey.CATEGORY_HOMEPAGE;
import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ProviderInfo;
import android.os.Bundle;
import android.util.Pair;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settingslib.drawer.ActivityTile;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.ProviderTile;
import com.android.settingslib.drawer.Tile;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.HashMap;
import java.util.Map;
@RunWith(AndroidJUnit4.class)
public class CategoryManagerTest {
private ActivityInfo mActivityInfo;
private Context mContext;
private CategoryManager mCategoryManager;
private Map<Pair<String, String>, Tile> mTileByComponentCache;
private Map<String, DashboardCategory> mCategoryByKeyMap;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mActivityInfo = new ActivityInfo();
mActivityInfo.packageName = "pkg";
mActivityInfo.name = "class";
mActivityInfo.applicationInfo = new ApplicationInfo();
mTileByComponentCache = new HashMap<>();
mCategoryByKeyMap = new HashMap<>();
mCategoryManager = CategoryManager.get(mContext);
}
@Test
public void getInstance_shouldBeSingleton() {
assertThat(mCategoryManager).isSameInstanceAs(CategoryManager.get(mContext));
}
@Test
public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForNewKeys() {
final Tile tile1 = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT);
final Tile tile2 = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT);
final DashboardCategory category = new DashboardCategory(CategoryKey.CATEGORY_ACCOUNT);
category.addTile(tile1);
category.addTile(tile2);
mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category);
mTileByComponentCache.put(new Pair<>("PACKAGE", "1"), tile1);
mTileByComponentCache.put(new Pair<>("PACKAGE", "2"), tile2);
mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
assertThat(mCategoryByKeyMap.size()).isEqualTo(1);
assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT)).isNotNull();
}
@Test
public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForMixedKeys() {
final Tile tile1 = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_ACCOUNT);
final String oldCategory = "com.android.settings.category.wireless";
final Tile tile2 = new ActivityTile(mActivityInfo, oldCategory);
final DashboardCategory category1 = new DashboardCategory(CategoryKey.CATEGORY_ACCOUNT);
category1.addTile(tile1);
final DashboardCategory category2 = new DashboardCategory(oldCategory);
category2.addTile(tile2);
mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category1);
mCategoryByKeyMap.put(oldCategory, category2);
mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS2"), tile2);
mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
assertThat(mCategoryByKeyMap.size()).isEqualTo(2);
assertThat(
mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT).getTilesCount()).isEqualTo(1);
assertThat(mCategoryByKeyMap.get(oldCategory).getTilesCount()).isEqualTo(1);
}
@Test
public void backwardCompatCleanupForCategory_shouldChangeCategoryForOldKeys() {
final String oldCategory = "com.android.settings.category.wireless";
final Tile tile1 = new ActivityTile(mActivityInfo, oldCategory);
tile1.setCategory(oldCategory);
final DashboardCategory category1 = new DashboardCategory(oldCategory);
category1.addTile(tile1);
mCategoryByKeyMap.put(oldCategory, category1);
mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
// Added 1 more category to category map.
assertThat(mCategoryByKeyMap.size()).isEqualTo(2);
// The new category map has CATEGORY_NETWORK type now, which contains 1 tile.
assertThat(
mCategoryByKeyMap.get(CategoryKey.CATEGORY_NETWORK).getTilesCount()).isEqualTo(1);
// Old category still exists.
assertThat(mCategoryByKeyMap.get(oldCategory).getTilesCount()).isEqualTo(1);
}
@Test
public void sortCategories_singlePackage_shouldReorderBasedOnPriority() {
// Create some fake tiles that are not sorted.
final String testPackage = "com.android.test";
final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
final Tile tile1 = createActivityTile(category.key, testPackage, "class1", 100);
final Tile tile2 = createActivityTile(category.key, testPackage, "class2", 50);
final Tile tile3 = createActivityTile(category.key, testPackage, "class3", 200);
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(ApplicationProvider.getApplicationContext(),
mCategoryByKeyMap);
// Verify they are now sorted.
assertThat(category.getTile(0)).isSameInstanceAs(tile3);
assertThat(category.getTile(1)).isSameInstanceAs(tile1);
assertThat(category.getTile(2)).isSameInstanceAs(tile2);
}
@Test
public void sortCategories_multiPackage_shouldReorderBasedOnPackageAndPriority() {
// Create some fake tiles that are not sorted.
final String testPackage1 = "com.android.test1";
final String testPackage2 = "com.android.test2";
final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
final Tile tile1 = createActivityTile(category.key, testPackage2, "class1", 100);
final Tile tile2 = createActivityTile(category.key, testPackage1, "class2", 100);
final Tile tile3 = createActivityTile(category.key, testPackage1, "class3", 50);
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
// Verify they are now sorted.
assertThat(category.getTile(0)).isSameInstanceAs(tile2);
assertThat(category.getTile(1)).isSameInstanceAs(tile1);
assertThat(category.getTile(2)).isSameInstanceAs(tile3);
}
@Test
public void sortCategories_internalPackageTiles_shouldSkipTileForInternalPackage() {
// Create some fake tiles that are not sorted.
final String testPackage = mContext.getPackageName();
final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
final Tile tile1 = createActivityTile(category.key, testPackage, "class1", 100);
final Tile tile2 = createActivityTile(category.key, testPackage, "class2", 100);
final Tile tile3 = createActivityTile(category.key, testPackage, "class3", 50);
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
// Verify the sorting order is not changed
assertThat(category.getTile(0)).isSameInstanceAs(tile1);
assertThat(category.getTile(1)).isSameInstanceAs(tile2);
assertThat(category.getTile(2)).isSameInstanceAs(tile3);
}
@Test
public void sortCategories_internalAndExternalPackageTiles_shouldRetainPriorityOrdering() {
// Inject one external tile among internal tiles.
final String testPackage = mContext.getPackageName();
final String testPackage2 = "com.google.test2";
final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
final Tile tile1 = createActivityTile(category.key, testPackage, "class1", 2);
final Tile tile2 = createActivityTile(category.key, testPackage, "class2", 1);
final Tile tile3 = createActivityTile(category.key, testPackage2, "class0", 0);
final Tile tile4 = createActivityTile(category.key, testPackage, "class3", -1);
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
category.addTile(tile4);
mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
// Verify the sorting order is not changed
assertThat(category.getTile(0)).isSameInstanceAs(tile1);
assertThat(category.getTile(1)).isSameInstanceAs(tile2);
assertThat(category.getTile(2)).isSameInstanceAs(tile3);
assertThat(category.getTile(3)).isSameInstanceAs(tile4);
}
@Test
public void sortCategories_samePriority_internalPackageTileShouldTakePrecedence() {
// Inject one external tile among internal tiles with same priority.
final String testPackage = mContext.getPackageName();
final String testPackage2 = "com.google.test2";
final String testPackage3 = "com.abcde.test3";
final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
final Tile tile1 = createActivityTile(category.key, testPackage2, "class1", 1);
final Tile tile2 = createActivityTile(category.key, testPackage, "class2", 1);
final Tile tile3 = createActivityTile(category.key, testPackage3, "class3", 1);
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
// Sort their priorities
mCategoryManager.sortCategories(mContext, mCategoryByKeyMap);
// Verify the sorting order is internal first, follow by package name ordering
assertThat(category.getTile(0)).isSameInstanceAs(tile2);
assertThat(category.getTile(1)).isSameInstanceAs(tile3);
assertThat(category.getTile(2)).isSameInstanceAs(tile1);
}
@Test
public void filterTiles_noDuplicate_noChange() {
// Create some unique tiles
final String testPackage = mContext.getPackageName();
final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
final Tile tile1 = createActivityTile(category.key, testPackage, "class1", 100);
final Tile tile2 = createActivityTile(category.key, testPackage, "class2", 100);
final Tile tile3 = createActivityTile(category.key, testPackage, "class3", 50);
final Tile tile4 = createProviderTile(category.key, testPackage, "class1", "authority1",
"key1", 100);
final Tile tile5 = createProviderTile(category.key, testPackage, "class1", "authority2",
"key2", 100);
final Tile tile6 = createProviderTile(category.key, testPackage, "class1", "authority1",
"key2", 50);
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
category.addTile(tile4);
category.addTile(tile5);
category.addTile(tile6);
mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
assertThat(category.getTilesCount()).isEqualTo(6);
}
@Test
public void filterTiles_hasDuplicateActivityTiles_shouldOnlyKeepUniqueTiles() {
// Create tiles pointing to same intent.
final String testPackage = mContext.getPackageName();
final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
final Tile tile1 = createActivityTile(category.key, testPackage, "class1", 100);
final Tile tile2 = createActivityTile(category.key, testPackage, "class1", 100);
final Tile tile3 = createActivityTile(category.key, testPackage, "class1", 50);
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
assertThat(category.getTilesCount()).isEqualTo(1);
}
@Test
public void filterTiles_hasDuplicateProviderTiles_shouldOnlyKeepUniqueTiles() {
// Create tiles pointing to same authority and key.
final String testPackage = mContext.getPackageName();
final DashboardCategory category = new DashboardCategory(CATEGORY_HOMEPAGE);
final Tile tile1 = createProviderTile(category.key, testPackage, "class1", "authority1",
"key1", 100);
final Tile tile2 = createProviderTile(category.key, testPackage, "class2", "authority1",
"key1", 100);
final Tile tile3 = createProviderTile(category.key, testPackage, "class3", "authority1",
"key1", 50);
category.addTile(tile1);
category.addTile(tile2);
category.addTile(tile3);
mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category);
mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
assertThat(category.getTilesCount()).isEqualTo(1);
}
private Tile createActivityTile(String categoryKey, String packageName, String className,
int order) {
final ActivityInfo activityInfo = new ActivityInfo();
activityInfo.packageName = packageName;
activityInfo.name = className;
activityInfo.metaData = new Bundle();
activityInfo.metaData.putInt(META_DATA_KEY_ORDER, order);
return new ActivityTile(activityInfo, categoryKey);
}
private Tile createProviderTile(String categoryKey, String packageName, String className,
String authority, String key, int order) {
final ProviderInfo providerInfo = new ProviderInfo();
final Bundle metaData = new Bundle();
providerInfo.packageName = packageName;
providerInfo.name = className;
providerInfo.authority = authority;
metaData.putString(META_DATA_PREFERENCE_KEYHINT, key);
metaData.putInt(META_DATA_KEY_ORDER, order);
return new ProviderTile(providerInfo, categoryKey, metaData);
}
}

View File

@@ -0,0 +1,44 @@
/*
* 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.dashboard;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.accounts.AccountDashboardFragment;
import com.android.settingslib.drawer.CategoryKey;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class DashboardFragmentRegistryTest {
@Test
public void pageAndKeyShouldHave1to1Mapping() {
assertThat(DashboardFragmentRegistry.CATEGORY_KEY_TO_PARENT_MAP.size())
.isEqualTo(DashboardFragmentRegistry.PARENT_TO_CATEGORY_KEY_MAP.size());
}
@Test
public void accountDetailCategoryShouldRedirectToAccountDashboardFragment() {
final String fragment = DashboardFragmentRegistry.CATEGORY_KEY_TO_PARENT_MAP.get(
CategoryKey.CATEGORY_ACCOUNT_DETAIL);
assertThat(fragment).isEqualTo(AccountDashboardFragment.class.getName());
}
}

View File

@@ -0,0 +1,84 @@
/*
* 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.dashboard;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerListHelper;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.List;
public class DashboardFragmentSearchIndexProviderInspector {
public static boolean isSharingPreferenceControllers(Class clazz) {
final Context context = ApplicationProvider.getApplicationContext();
final Fragment fragment;
try {
fragment = Fragment.instantiate(context, clazz.getName());
} catch (Throwable e) {
// Can't do much with exception, assume the test passed.
return true;
}
if (!(fragment instanceof DashboardFragment)) {
return true;
}
final BaseSearchIndexProvider provider =
(BaseSearchIndexProvider) DatabaseIndexingUtils.getSearchIndexProvider(clazz);
if (provider == null) {
return true;
}
final List<AbstractPreferenceController> controllersFromSearchIndexProvider;
final List<AbstractPreferenceController> controllersFromFragment;
try {
controllersFromSearchIndexProvider = provider.getPreferenceControllers(context);
} catch (Throwable e) {
// Can't do much with exception, assume the test passed.
return true;
}
try {
controllersFromFragment =
((DashboardFragment) fragment).createPreferenceControllers(context);
List<BasePreferenceController> controllersFromXml = PreferenceControllerListHelper
.getPreferenceControllersFromXml(context,
((DashboardFragment) fragment).getPreferenceScreenResId());
final List<BasePreferenceController> uniqueControllerFromXml =
PreferenceControllerListHelper.filterControllers(
controllersFromXml, controllersFromFragment);
controllersFromFragment.addAll(uniqueControllerFromXml);
} catch (Throwable e) {
// Can't do much with exception, assume the test passed.
return true;
}
if (controllersFromFragment == controllersFromSearchIndexProvider) {
return true;
} else if (controllersFromFragment != null && controllersFromSearchIndexProvider != null) {
return controllersFromFragment.size() == controllersFromSearchIndexProvider.size();
} else {
return false;
}
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.datetime.timezone;
import static com.google.common.truth.Truth.assertThat;
import android.icu.text.Collator;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.datetime.timezone.RegionZonePicker.TimeZoneInfoComparator;
import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@RunWith(AndroidJUnit4.class)
public class RegionZonePickerTest {
@Test
public void compareTimeZoneInfo_matchGmtOrder() {
Date now = new Date(0); // 00:00 1, Jan 1970
Formatter formatter = new Formatter(Locale.US, now);
TimeZoneInfo timeZone1 = formatter.format("Pacific/Honolulu");
TimeZoneInfo timeZone2 = formatter.format("America/Los_Angeles");
TimeZoneInfo timeZone3 = formatter.format("America/Indiana/Marengo");
TimeZoneInfo timeZone4 = formatter.format("America/New_York");
TimeZoneInfoComparator comparator =
new TimeZoneInfoComparator(Collator.getInstance(Locale.US), now);
// Verify the sorted order
List<TimeZoneInfo> list = Arrays.asList(timeZone4, timeZone2, timeZone3, timeZone1);
Collections.sort(list, comparator);
assertThat(list).isEqualTo(Arrays.asList(timeZone1, timeZone2, timeZone3, timeZone4));
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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.datetime.timezone;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Date;
import java.util.Locale;
@RunWith(AndroidJUnit4.class)
public class TimeZoneInfoPreferenceControllerTest {
private TimeZoneInfo mTimeZoneInfo;
private TimeZoneInfoPreferenceController mController;
@Before
public void setUp() {
final Context context = ApplicationProvider.getApplicationContext();
final Date now = new Date(0L); // 00:00 1/1/1970
final Formatter formatter = new Formatter(Locale.US, now);
mTimeZoneInfo = formatter.format("America/Los_Angeles");
mController = new TimeZoneInfoPreferenceController(context, "key");
mController.mDate = now;
mController.setTimeZoneInfo(mTimeZoneInfo);
}
@Test
public void getSummary_matchExpectedFormattedText() {
assertThat(mController.getSummary().toString()).isEqualTo(
"Uses Pacific Time (GMT-08:00). "
+ "Pacific Daylight Time starts on April 26, 1970.");
}
@Test
public void getAvailabilityStatus_timeZoneInfoSet_shouldReturnAVAILABLE_UNSEARCHABLE() {
mController.setTimeZoneInfo(mTimeZoneInfo);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
public void getAvailabilityStatus_noTimeZoneInfoSet_shouldReturnUNSUPPORTED_ON_DEVICE() {
mController.setTimeZoneInfo(null);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.datetime.timezone;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Date;
import java.util.Locale;
@RunWith(AndroidJUnit4.class)
public class TimeZoneInfoTest {
@Test
public void testFormat() {
Date now = new Date(0L); // 00:00 1/1/1970
Formatter formatter = new Formatter(Locale.US, now);
TimeZoneInfo timeZoneInfo = formatter.format("America/Los_Angeles");
assertThat(timeZoneInfo.getId()).isEqualTo("America/Los_Angeles");
assertThat(timeZoneInfo.getExemplarLocation()).isEqualTo("Los Angeles");
assertThat(timeZoneInfo.getGmtOffset().toString()).isEqualTo("GMT-08:00");
assertThat(timeZoneInfo.getGenericName()).isEqualTo("Pacific Time");
assertThat(timeZoneInfo.getStandardName()).isEqualTo("Pacific Standard Time");
assertThat(timeZoneInfo.getDaylightName()).isEqualTo("Pacific Daylight Time");
}
@Test
public void getGmtOffset_zoneLordHowe_correctGmtOffset() {
Date date = new Date(1514764800000L); // 00:00 1/1/2018 GMT
Formatter formatter = new Formatter(Locale.US, date);
TimeZoneInfo timeZoneInfo = formatter.format("Australia/Lord_Howe");
assertThat(timeZoneInfo.getGmtOffset().toString()).isEqualTo("GMT+11:00");
}
}

View File

@@ -0,0 +1,120 @@
/*
* 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.development;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class OverlaySettingsPreferenceControllerTest {
private Context mContext;
private SwitchPreference mPreference;
private OverlaySettingsPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new OverlaySettingsPreferenceController(mContext);
mPreference = new SwitchPreference(mContext);
}
@Test
public void isAvailable_shouldReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void updateState_isOverlaySettingsEnabled_shouldCheckPreference() {
OverlaySettingsPreferenceController.setOverlaySettingsEnabled(mContext, true);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void updateState_isOverlaySettingsDisabled_shouldUncheckPreference() {
OverlaySettingsPreferenceController.setOverlaySettingsEnabled(mContext, false);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void onPreferenceChange_preferenceChecked_shouldEnableSettings() {
mController.onPreferenceChange(mPreference, true);
assertThat(OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isTrue();
}
@Test
public void onPreferenceChange_preferenceUnchecked_shouldDisableSettings() {
mController.onPreferenceChange(mPreference, false);
assertThat(
OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isFalse();
}
@Test
public void isOverlaySettingsEnabled_sharePreferenceSetTrue_shouldReturnTrue() {
final SharedPreferences editor = mContext.getSharedPreferences(
OverlaySettingsPreferenceController.SHARE_PERFS,
Context.MODE_PRIVATE);
editor.edit().putBoolean(OverlaySettingsPreferenceController.SHARE_PERFS, true).apply();
assertThat(OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isTrue();
}
@Test
public void isOverlaySettingsEnabled_sharePreferenceSetFalse_shouldReturnFalse() {
final SharedPreferences editor = mContext.getSharedPreferences(
OverlaySettingsPreferenceController.SHARE_PERFS,
Context.MODE_PRIVATE);
editor.edit().putBoolean(OverlaySettingsPreferenceController.SHARE_PERFS, false).apply();
assertThat(
OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isFalse();
}
@Test
public void setOverlaySettingsEnabled_setTrue_shouldStoreTrue() {
OverlaySettingsPreferenceController.setOverlaySettingsEnabled(mContext, true);
assertThat(
OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isTrue();
}
@Test
public void setOverlaySettingsEnabled_setFalse_shouldStoreTrue() {
OverlaySettingsPreferenceController.setOverlaySettingsEnabled(mContext, false);
assertThat(
OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isFalse();
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.development.autofill;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
final class AutofillTestingHelper {
private final ContentResolver mResolver;
AutofillTestingHelper(Context context) {
mResolver = context.getContentResolver();
}
public void setLoggingLevel(int max) {
setGlobal(Settings.Global.AUTOFILL_LOGGING_LEVEL, max);
}
public void setMaxPartitionsSize(int max) {
setGlobal(Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, max);
}
public void setMaxVisibleDatasets(int level) {
setGlobal(Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, level);
}
public int getLoggingLevel() throws SettingNotFoundException {
return getGlobal(Settings.Global.AUTOFILL_LOGGING_LEVEL);
}
public int getMaxPartitionsSize() throws SettingNotFoundException {
return getGlobal(Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE);
}
public int getMaxVisibleDatasets() throws SettingNotFoundException {
return getGlobal(Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS);
}
private void setGlobal(String key, int value) {
Settings.Global.putInt(mResolver, key, value);
}
private int getGlobal(String key) throws SettingNotFoundException {
return Settings.Global.getInt(mResolver, key);
}
}

View File

@@ -0,0 +1,160 @@
/*
* 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.development.featureflags;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.FeatureFlagUtils;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class FeatureFlagPersistentTest {
private static final String TEST_FEATURE_NAME = "test_feature";
private static final String PERSISTENT_FALSE_NAME = "false_persistent";
private static final String PERSISTENT_TRUE_NAME = "true_persistent";
private static final String VOLATILE_FALSE_NAME = "volatile_false_volatile";
private static final String VOLATILE_TRUE_NAME = "volatile_true_volatile";
private Context mContext;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
FeatureFlagPersistent.getAllPersistentFlags().add(TEST_FEATURE_NAME);
FeatureFlagUtils.getAllFeatureFlags().put(TEST_FEATURE_NAME, "false");
FeatureFlagUtils.getAllFeatureFlags().put(VOLATILE_FALSE_NAME, "false");
FeatureFlagUtils.getAllFeatureFlags().put(VOLATILE_TRUE_NAME, "true");
FeatureFlagPersistent.getAllPersistentFlags().add(PERSISTENT_FALSE_NAME);
FeatureFlagUtils.getAllFeatureFlags().put(PERSISTENT_FALSE_NAME, "false");
FeatureFlagPersistent.getAllPersistentFlags().add(PERSISTENT_TRUE_NAME);
FeatureFlagUtils.getAllFeatureFlags().put(PERSISTENT_TRUE_NAME, "true");
}
@After
public void tearDown() {
cleanup(PERSISTENT_FALSE_NAME);
cleanup(PERSISTENT_TRUE_NAME);
cleanup(VOLATILE_FALSE_NAME);
cleanup(VOLATILE_TRUE_NAME);
cleanup(TEST_FEATURE_NAME);
}
private void cleanup(String flagName) {
Settings.Global.putString(mContext.getContentResolver(), flagName, "");
SystemProperties.set(FeatureFlagUtils.FFLAG_PREFIX + flagName, "");
SystemProperties.set(FeatureFlagUtils.FFLAG_OVERRIDE_PREFIX + flagName, "");
SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + flagName, "");
}
/**
* Test to verify a non-persistent flag is indeed not persistent.
*/
@Test
public void isPersistent_notPersistent_shouldReturnFalse() {
assertThat(FeatureFlagPersistent.isPersistent(VOLATILE_FALSE_NAME)).isFalse();
}
/**
* Test to verify a persistent flag is indeed persistent.
*/
@Test
public void isPersistent_persistent_shouldReturnTrue() {
assertThat(FeatureFlagPersistent.isPersistent(PERSISTENT_TRUE_NAME)).isTrue();
}
/**
* Test to verify a persistent flag that is enabled should return true.
*/
@Test
public void isEnabled_enabled_shouldReturnTrue() {
assertThat(FeatureFlagPersistent.isEnabled(mContext, PERSISTENT_TRUE_NAME)).isTrue();
}
/**
* Test to verify a persistent flag that is disabled should return false.
*/
@Test
public void isEnabled_disabled_shouldReturnFalse() {
assertThat(FeatureFlagPersistent.isEnabled(mContext, PERSISTENT_FALSE_NAME)).isFalse();
}
/**
* Test to verify a persistent flag that has an enabled in system property should return true.
*/
@Test
public void isEnabled_sysPropEnabled_shouldReturnTrue() {
SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME, "true");
FeatureFlagUtils.setEnabled(mContext, TEST_FEATURE_NAME, false);
assertThat(FeatureFlagPersistent.isEnabled(mContext, TEST_FEATURE_NAME)).isTrue();
}
/**
* Test to verify a persistent flag that is disabled in system property should return false.
*/
@Test
public void isEnabled_sysPropDisabled_shouldReturnFalse() {
SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME, "false");
FeatureFlagUtils.setEnabled(mContext, TEST_FEATURE_NAME, true);
assertThat(FeatureFlagPersistent.isEnabled(mContext, TEST_FEATURE_NAME)).isFalse();
}
/**
* Test to verify setting persistent flag to enable works.
*/
@Test
public void setEnabled_sysPropTrue_shouldSetValues() {
SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME, "");
FeatureFlagPersistent.setEnabled(mContext, TEST_FEATURE_NAME, true);
assertThat(SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME))
.isEqualTo("true");
assertThat(FeatureFlagUtils.isEnabled(mContext, TEST_FEATURE_NAME)).isTrue();
}
/**
* Test to verify setting persistent flag to disable works.
*/
@Test
public void setEnabled_sysPropFalse_shouldSetValues() {
SystemProperties.set(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME, "");
FeatureFlagPersistent.setEnabled(mContext, TEST_FEATURE_NAME, false);
assertThat(SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME))
.isEqualTo("false");
assertThat(FeatureFlagUtils.isEnabled(mContext, TEST_FEATURE_NAME)).isFalse();
}
}

View File

@@ -0,0 +1,77 @@
/*
* 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.development.transcode;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class TranscodeDefaultOptionPreferenceControllerTest {
private static final String TRANSCODE_DEFAULT_SYS_PROP_KEY =
"persist.sys.fuse.transcode_default";
private TranscodeDefaultOptionPreferenceController mUnderTest;
@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeDefaultOptionPreferenceController(context, "some_key");
}
@Test
public void isChecked_whenSysPropSet_shouldReturnFalse() {
SystemProperties.set(TRANSCODE_DEFAULT_SYS_PROP_KEY, "true");
assertThat(mUnderTest.isChecked()).isFalse();
}
@Test
public void isChecked_whenSysPropUnset_shouldReturnTrue() {
SystemProperties.set(TRANSCODE_DEFAULT_SYS_PROP_KEY, "false");
assertThat(mUnderTest.isChecked()).isTrue();
}
@Test
public void setChecked_withTrue_shouldUnsetSysProp() {
mUnderTest.setChecked(true);
assertThat(
SystemProperties.getBoolean(TRANSCODE_DEFAULT_SYS_PROP_KEY, true)).isFalse();
}
@Test
public void setChecked_withFalse_shouldSetSysProp() {
mUnderTest.setChecked(false);
assertThat(
SystemProperties.getBoolean(TRANSCODE_DEFAULT_SYS_PROP_KEY, false)).isTrue();
}
@Test
public void getAvailabilityStatus_shouldReturn_isAvailable() {
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
}

View File

@@ -0,0 +1,78 @@
/*
* 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.development.transcode;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class TranscodeGlobalTogglePreferenceControllerTest {
private static final String TRANSCODE_ENABLED_PROP_KEY = "persist.sys.fuse.transcode_enabled";
private TranscodeGlobalTogglePreferenceController mController;
@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
mController = new TranscodeGlobalTogglePreferenceController(context, "test_key");
}
@Test
public void isAvailable_shouldReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isChecked_whenDisabled_shouldReturnFalse() {
SystemProperties.set(TRANSCODE_ENABLED_PROP_KEY, "false");
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_whenEnabled_shouldReturnTrue() {
SystemProperties.set(TRANSCODE_ENABLED_PROP_KEY, "true");
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked_withTrue_shouldUpdateSystemProperty() {
// Simulate the UI being clicked.
mController.setChecked(true);
// Verify the system property was updated.
assertThat(SystemProperties.getBoolean(TRANSCODE_ENABLED_PROP_KEY, false)).isTrue();
}
@Test
public void setChecked_withFalse_shouldUpdateSystemProperty() {
// Simulate the UI being clicked.
mController.setChecked(false);
// Verify the system property was updated.
assertThat(SystemProperties.getBoolean(TRANSCODE_ENABLED_PROP_KEY, true)).isFalse();
}
}

View File

@@ -0,0 +1,77 @@
/*
* 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.development.transcode;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class TranscodeUserControlPreferenceControllerTest {
private static final String TRANSCODE_USER_CONTROL_SYS_PROP_KEY =
"persist.sys.fuse.transcode_user_control";
private TranscodeUserControlPreferenceController mUnderTest;
@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeUserControlPreferenceController(context, "some_key");
}
@Test
public void isChecked_whenSysPropSet_shouldReturnTrue() {
SystemProperties.set(TRANSCODE_USER_CONTROL_SYS_PROP_KEY, "true");
assertThat(mUnderTest.isChecked()).isTrue();
}
@Test
public void isChecked_whenSysPropUnset_shouldReturnFalse() {
SystemProperties.set(TRANSCODE_USER_CONTROL_SYS_PROP_KEY, "false");
assertThat(mUnderTest.isChecked()).isFalse();
}
@Test
public void setChecked_withTrue_shouldSetSysProp() {
mUnderTest.setChecked(true);
assertThat(
SystemProperties.getBoolean(TRANSCODE_USER_CONTROL_SYS_PROP_KEY, false)).isTrue();
}
@Test
public void setChecked_withFalse_shouldUnsetSysProp() {
mUnderTest.setChecked(false);
assertThat(
SystemProperties.getBoolean(TRANSCODE_USER_CONTROL_SYS_PROP_KEY, true)).isFalse();
}
@Test
public void getAvailabilityStatus_shouldReturn_isAvailable() {
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.deviceinfo.storage;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.os.storage.VolumeInfo;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class VolumeSizesLoaderTest {
@Test
public void getVolumeSize_getsValidSizes() throws Exception {
VolumeInfo info = mock(VolumeInfo.class);
StorageVolumeProvider storageVolumeProvider = mock(StorageVolumeProvider.class);
when(storageVolumeProvider.getTotalBytes(any(), any())).thenReturn(10000L);
when(storageVolumeProvider.getFreeBytes(any(), any())).thenReturn(1000L);
PrivateStorageInfo storageInfo =
VolumeSizesLoader.getVolumeSize(storageVolumeProvider, null, info);
assertThat(storageInfo.freeBytes).isEqualTo(1000L);
assertThat(storageInfo.totalBytes).isEqualTo(10000L);
}
}

View File

@@ -0,0 +1,111 @@
/*
* 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.fuelgauge.batterysaver;
import static com.google.common.truth.Truth.assertThat;
import android.content.ContentResolver;
import android.content.Context;
import android.os.PowerManager;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class BatterySaverScheduleRadioButtonsControllerTest {
private Context mContext;
private ContentResolver mResolver;
private BatterySaverScheduleRadioButtonsController mController;
private BatterySaverScheduleSeekBarController mSeekBarController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mSeekBarController = new BatterySaverScheduleSeekBarController(mContext);
mController = new BatterySaverScheduleRadioButtonsController(
mContext, mSeekBarController);
mResolver = mContext.getContentResolver();
}
@Test
public void getDefaultKey_routine_returnsCorrectValue() {
Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
assertThat(mController.getDefaultKey())
.isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_ROUTINE);
}
@Test
public void getDefaultKey_automatic_returnsCorrectValue() {
Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 5);
assertThat(mController.getDefaultKey())
.isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_PERCENTAGE);
}
@Test
public void getDefaultKey_none_returnsCorrectValue() {
Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
assertThat(mController.getDefaultKey())
.isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_NO_SCHEDULE);
}
@Test
public void setDefaultKey_any_defaultsToNoScheduleIfWarningNotSeen() {
Secure.putString(
mContext.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
mController.setDefaultKey(BatterySaverScheduleRadioButtonsController.KEY_ROUTINE);
assertThat(mController.getDefaultKey())
.isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_NO_SCHEDULE);
}
@Test
public void setDefaultKey_percentage_shouldSuppressNotification() {
Secure.putInt(
mContext.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 5);
mController.setDefaultKey(BatterySaverScheduleRadioButtonsController.KEY_PERCENTAGE);
final int result = Settings.Secure.getInt(mResolver,
Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 0);
assertThat(result).isEqualTo(1);
}
@Test
public void setDefaultKey_routine_shouldSuppressNotification() {
Secure.putInt(
mContext.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
mController.setDefaultKey(BatterySaverScheduleRadioButtonsController.KEY_ROUTINE);
final int result = Settings.Secure.getInt(mResolver,
Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 0);
assertThat(result).isEqualTo(1);
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.fuelgauge.batterysaver;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import android.provider.Settings.Global;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class BatterySaverStickyPreferenceControllerTest {
private static final String PREF_KEY = "battery_saver_sticky";
private Context mContext;
private BatterySaverStickyPreferenceController mController;
@Before
public void setup() {
mContext = ApplicationProvider.getApplicationContext();
mController = new BatterySaverStickyPreferenceController(mContext, PREF_KEY);
}
private int getAutoDisableSetting() {
return Settings.Global.getInt(mContext.getContentResolver(),
Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED,
1);
}
@Test
public void testOnPreferenceChange_turnOnAutoOff_autoDisableOn() {
mController.setChecked(true);
final int isOn = getAutoDisableSetting();
assertThat(isOn).isEqualTo(1);
}
@Test
public void testOnPreferenceChange_TurnOffAutoOff_autoDisableOff() {
mController.setChecked(false);
final int isOn = getAutoDisableSetting();
assertThat(isOn).isEqualTo(0);
}
}

View File

@@ -0,0 +1,95 @@
/*
* 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.fuelgauge.batterytip;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import android.text.format.DateUtils;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class AppInfoTest {
private static final String PACKAGE_NAME = "com.android.app";
private static final int TYPE_WAKELOCK =
StatsManagerConfig.AnomalyType.EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF;
private static final int TYPE_WAKEUP =
StatsManagerConfig.AnomalyType.EXCESSIVE_WAKEUPS_IN_BACKGROUND;
private static final long SCREEN_TIME_MS = DateUtils.HOUR_IN_MILLIS;
private static final int UID = 3452;
private AppInfo mAppInfo;
@Before
public void setUp() {
mAppInfo = new AppInfo.Builder()
.setPackageName(PACKAGE_NAME)
.addAnomalyType(TYPE_WAKELOCK)
.addAnomalyType(TYPE_WAKEUP)
.setScreenOnTimeMs(SCREEN_TIME_MS)
.setUid(UID)
.build();
}
@Test
public void testParcel() {
Parcel parcel = Parcel.obtain();
mAppInfo.writeToParcel(parcel, mAppInfo.describeContents());
parcel.setDataPosition(0);
final AppInfo appInfo = new AppInfo(parcel);
assertThat(appInfo.packageName).isEqualTo(PACKAGE_NAME);
assertThat(appInfo.anomalyTypes).containsExactly(TYPE_WAKELOCK, TYPE_WAKEUP);
assertThat(appInfo.screenOnTimeMs).isEqualTo(SCREEN_TIME_MS);
assertThat(appInfo.uid).isEqualTo(UID);
}
@Test
public void testCompareTo_hasCorrectOrder() {
final AppInfo appInfo = new AppInfo.Builder()
.setPackageName(PACKAGE_NAME)
.addAnomalyType(TYPE_WAKELOCK)
.setScreenOnTimeMs(SCREEN_TIME_MS + 100)
.build();
List<AppInfo> appInfos = new ArrayList<>();
appInfos.add(appInfo);
appInfos.add(mAppInfo);
Collections.sort(appInfos);
assertThat(appInfos.get(0).screenOnTimeMs).isLessThan(appInfos.get(1).screenOnTimeMs);
}
@Test
public void testBuilder() {
assertThat(mAppInfo.packageName).isEqualTo(PACKAGE_NAME);
assertThat(mAppInfo.anomalyTypes).containsExactly(TYPE_WAKELOCK, TYPE_WAKEUP);
assertThat(mAppInfo.screenOnTimeMs).isEqualTo(SCREEN_TIME_MS);
assertThat(mAppInfo.uid).isEqualTo(UID);
}
}

View File

@@ -0,0 +1,116 @@
/*
* 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.fuelgauge.batterytip;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import android.text.format.DateUtils;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class BatteryTipPolicyTest {
private static final String BATTERY_TIP_CONSTANTS_VALUE = "battery_tip_enabled=true"
+ ",summary_enabled=false"
+ ",battery_saver_tip_enabled=false"
+ ",high_usage_enabled=true"
+ ",high_usage_app_count=5"
+ ",high_usage_period_ms=2000"
+ ",high_usage_battery_draining=30"
+ ",app_restriction_enabled=true"
+ ",reduced_battery_enabled=true"
+ ",reduced_battery_percent=30"
+ ",low_battery_enabled=false"
+ ",low_battery_hour=10"
+ ",data_history_retain_day=24"
+ ",excessive_bg_drain_percentage=25"
+ ",test_battery_saver_tip=true"
+ ",test_high_usage_tip=false"
+ ",test_smart_battery_tip=true"
+ ",test_low_battery_tip=true"
+ ",app_restriction_active_hour=6";
private Context mContext;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
}
@Test
public void testInit_usesConfigValues() {
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.BATTERY_TIP_CONSTANTS, BATTERY_TIP_CONSTANTS_VALUE);
final BatteryTipPolicy batteryTipPolicy = new BatteryTipPolicy(mContext);
assertThat(batteryTipPolicy.batteryTipEnabled).isTrue();
assertThat(batteryTipPolicy.summaryEnabled).isFalse();
assertThat(batteryTipPolicy.batterySaverTipEnabled).isFalse();
assertThat(batteryTipPolicy.highUsageEnabled).isTrue();
assertThat(batteryTipPolicy.highUsageAppCount).isEqualTo(5);
assertThat(batteryTipPolicy.highUsagePeriodMs).isEqualTo(2000);
assertThat(batteryTipPolicy.highUsageBatteryDraining).isEqualTo(30);
assertThat(batteryTipPolicy.appRestrictionEnabled).isTrue();
assertThat(batteryTipPolicy.appRestrictionActiveHour).isEqualTo(6);
assertThat(batteryTipPolicy.reducedBatteryEnabled).isTrue();
assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(30);
assertThat(batteryTipPolicy.lowBatteryEnabled).isFalse();
assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(10);
assertThat(batteryTipPolicy.dataHistoryRetainDay).isEqualTo(24);
assertThat(batteryTipPolicy.excessiveBgDrainPercentage).isEqualTo(25);
assertThat(batteryTipPolicy.testBatterySaverTip).isTrue();
assertThat(batteryTipPolicy.testHighUsageTip).isFalse();
assertThat(batteryTipPolicy.testSmartBatteryTip).isTrue();
assertThat(batteryTipPolicy.testLowBatteryTip).isTrue();
}
@Test
public void testInit_defaultValues() {
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.BATTERY_TIP_CONSTANTS, "");
final BatteryTipPolicy batteryTipPolicy = new BatteryTipPolicy(mContext);
assertThat(batteryTipPolicy.batteryTipEnabled).isTrue();
assertThat(batteryTipPolicy.summaryEnabled).isTrue();
assertThat(batteryTipPolicy.batterySaverTipEnabled).isTrue();
assertThat(batteryTipPolicy.highUsageEnabled).isTrue();
assertThat(batteryTipPolicy.highUsageAppCount).isEqualTo(3);
assertThat(batteryTipPolicy.highUsagePeriodMs).isEqualTo(2 * DateUtils.HOUR_IN_MILLIS);
assertThat(batteryTipPolicy.highUsageBatteryDraining).isEqualTo(25);
assertThat(batteryTipPolicy.appRestrictionEnabled).isTrue();
assertThat(batteryTipPolicy.appRestrictionActiveHour).isEqualTo(24);
assertThat(batteryTipPolicy.reducedBatteryEnabled).isFalse();
assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(50);
assertThat(batteryTipPolicy.lowBatteryEnabled).isTrue();
assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(3);
assertThat(batteryTipPolicy.dataHistoryRetainDay).isEqualTo(30);
assertThat(batteryTipPolicy.excessiveBgDrainPercentage).isEqualTo(10);
assertThat(batteryTipPolicy.testBatterySaverTip).isFalse();
assertThat(batteryTipPolicy.testHighUsageTip).isFalse();
assertThat(batteryTipPolicy.testSmartBatteryTip).isFalse();
assertThat(batteryTipPolicy.testLowBatteryTip).isFalse();
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.gestures;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.TogglePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class OneHandedAppTapsExitPreferenceControllerTest {
private static final String KEY = "gesture_app_taps_to_exit";
private Context mContext;
private SwitchPreference mSwitchPreference;
private OneHandedAppTapsExitPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new OneHandedAppTapsExitPreferenceController(mContext, KEY);
mSwitchPreference = new SwitchPreference(mContext);
mSwitchPreference.setKey(KEY);
}
@Test
public void setChecked_setBoolean_checkIsTrueOrFalse() {
mController.setChecked(false);
assertThat(mController.isChecked()).isFalse();
mController.setChecked(true);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void getAvailabilityStatus_enabledOneHanded_shouldAvailable() {
OneHandedSettingsUtils.setSettingsOneHandedModeEnabled(mContext, true);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(TogglePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_disabledOneHanded_shouldUnavailable() {
OneHandedSettingsUtils.setSettingsOneHandedModeEnabled(mContext, false);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(TogglePreferenceController.DISABLED_DEPENDENT_SETTING);
}
@Test
public void updateState_enableOneHanded_switchShouldEnabled() {
OneHandedSettingsUtils.setSettingsOneHandedModeEnabled(mContext, true);
mController.updateState(mSwitchPreference);
assertThat(mSwitchPreference.isEnabled()).isTrue();
}
@Test
public void updateState_disableOneHanded_switchShouldDisabled() {
OneHandedSettingsUtils.setSettingsOneHandedModeEnabled(mContext, false);
mController.updateState(mSwitchPreference);
assertThat(mSwitchPreference.isEnabled()).isFalse();
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.homepage.contextualcards;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class CardDatabaseHelperTest {
private Context mContext;
private CardDatabaseHelper mCardDatabaseHelper;
private SQLiteDatabase mDatabase;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mCardDatabaseHelper = CardDatabaseHelper.getInstance(mContext);
mDatabase = mCardDatabaseHelper.getReadableDatabase();
}
@After
public void cleanUp() {
CardDatabaseHelper.getInstance(mContext).close();
CardDatabaseHelper.sCardDatabaseHelper = null;
}
@Test
public void testDatabaseSchema() {
final Cursor cursor = mDatabase.rawQuery("SELECT * FROM " + CardDatabaseHelper.CARD_TABLE,
null);
final String[] columnNames = cursor.getColumnNames();
final String[] expectedNames = {
CardDatabaseHelper.CardColumns.NAME,
CardDatabaseHelper.CardColumns.TYPE,
CardDatabaseHelper.CardColumns.SCORE,
CardDatabaseHelper.CardColumns.SLICE_URI,
CardDatabaseHelper.CardColumns.CATEGORY,
CardDatabaseHelper.CardColumns.PACKAGE_NAME,
CardDatabaseHelper.CardColumns.APP_VERSION,
CardDatabaseHelper.CardColumns.DISMISSED_TIMESTAMP,
};
assertThat(columnNames).isEqualTo(expectedNames);
cursor.close();
}
}

View File

@@ -0,0 +1,101 @@
/*
* 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.homepage.contextualcards;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.homepage.contextualcards.ContextualCardLookupTable.ControllerRendererMapping;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class ContextualCardLookupTableTest {
private static final int UNSUPPORTED_CARD_TYPE = -99999;
private static final int UNSUPPORTED_VIEW_TYPE = -99999;
private List<ControllerRendererMapping> mOriginalLookupTable;
@Before
public void setUp() {
mOriginalLookupTable = new ArrayList<>();
ContextualCardLookupTable.LOOKUP_TABLE.stream()
.forEach(mapping -> mOriginalLookupTable.add(mapping));
}
@After
public void reset() {
ContextualCardLookupTable.LOOKUP_TABLE.clear();
ContextualCardLookupTable.LOOKUP_TABLE.addAll(mOriginalLookupTable);
}
@Test
public void getCardControllerClass_hasSupportedCardType_shouldGetCorrespondingController() {
for (ControllerRendererMapping mapping : ContextualCardLookupTable.LOOKUP_TABLE) {
assertThat(ContextualCardLookupTable.getCardControllerClass(mapping.mCardType))
.isEqualTo(mapping.mControllerClass);
}
}
@Test
public void getCardControllerClass_hasUnsupportedCardType_shouldAlwaysGetNull() {
assertThat(ContextualCardLookupTable.getCardControllerClass(UNSUPPORTED_CARD_TYPE))
.isNull();
}
@Test
public void
getCardRendererClassByViewType_hasSupportedViewType_shouldGetCorrespondingRenderer() {
for (ControllerRendererMapping mapping : ContextualCardLookupTable.LOOKUP_TABLE) {
assertThat(ContextualCardLookupTable.getCardRendererClassByViewType(mapping.mViewType))
.isEqualTo(mapping.mRendererClass);
}
}
@Test
public void getCardRendererClassByViewType_hasUnsupportedViewType_shouldAlwaysGetNull() {
assertThat(ContextualCardLookupTable.getCardRendererClassByViewType(
UNSUPPORTED_VIEW_TYPE)).isNull();
}
@Test(expected = IllegalStateException.class)
public void
getCardRendererClassByViewType_hasDuplicateViewType_shouldThrowsIllegalStateException() {
final ControllerRendererMapping mapping1 =
new ControllerRendererMapping(
1111 /* cardType */, UNSUPPORTED_VIEW_TYPE /* viewType */,
ContextualCardController.class, ContextualCardRenderer.class
);
final ControllerRendererMapping mapping2 =
new ControllerRendererMapping(
2222 /* cardType */, UNSUPPORTED_VIEW_TYPE /* viewType */,
ContextualCardController.class, ContextualCardRenderer.class
);
ContextualCardLookupTable.LOOKUP_TABLE.add(mapping1);
ContextualCardLookupTable.LOOKUP_TABLE.add(mapping2);
ContextualCardLookupTable.getCardRendererClassByViewType(UNSUPPORTED_VIEW_TYPE);
}
}

View File

@@ -0,0 +1,115 @@
/*
* 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.homepage.contextualcards;
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE;
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class ContextualCardsDiffCallbackTest {
private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
private ContextualCardsDiffCallback mDiffCallback;
private List<ContextualCard> mOldCards;
private List<ContextualCard> mNewCards;
@Before
public void setUp() {
mOldCards = new ArrayList<>();
mNewCards = new ArrayList<>();
mOldCards.add(getContextualCard("test1"));
mNewCards.add(getContextualCard("test1"));
mNewCards.add(getContextualCard("test2"));
mDiffCallback = new ContextualCardsDiffCallback(mOldCards, mNewCards);
}
@Test
public void getOldListSize_oneCard_returnOne() {
assertThat(mDiffCallback.getOldListSize()).isEqualTo(1);
}
@Test
public void getNewListSize_twoCards_returnTwo() {
assertThat(mDiffCallback.getNewListSize()).isEqualTo(2);
}
@Test
public void areItemsTheSame_sameItems_returnTrue() {
assertThat(mDiffCallback.areItemsTheSame(0, 0)).isTrue();
}
@Test
public void areItemsTheSame_differentItems_returnFalse() {
mOldCards.add(getContextualCard("test3"));
assertThat(mDiffCallback.areItemsTheSame(1, 1)).isFalse();
}
@Test
public void areContentsTheSame_sameContents_returnTrue() {
assertThat(mDiffCallback.areContentsTheSame(0, 0)).isTrue();
}
@Test
public void areContentsTheSame_sliceWithToggle_returnFalse() {
final ContextualCard card = getContextualCard("test1").mutate()
.setHasInlineAction(true).build();
mNewCards.add(0, card);
assertThat(mDiffCallback.areContentsTheSame(0, 0)).isFalse();
}
@Test
public void areContentsTheSame_stickySlice_returnFalse() {
final ContextualCard card = getContextualCard("test1").mutate()
.setCategory(STICKY_VALUE).build();
mNewCards.add(0, card);
assertThat(mDiffCallback.areContentsTheSame(0, 0)).isFalse();
}
@Test
public void areContentsTheSame_importantSlice_returnFalse() {
final ContextualCard card = getContextualCard("test1").mutate()
.setCategory(IMPORTANT_VALUE).build();
mNewCards.add(0, card);
assertThat(mDiffCallback.areContentsTheSame(0, 0)).isFalse();
}
private ContextualCard getContextualCard(String name) {
return new ContextualCard.Builder()
.setName(name)
.setRankingScore(0.5)
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(TEST_SLICE_URI)
.build();
}
}

View File

@@ -0,0 +1,43 @@
/*
* 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.homepage.contextualcards.conditional;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.homepage.contextualcards.ContextualCard;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ConditionFooterContextualCardTest {
@Test(expected = IllegalArgumentException.class)
public void newInstance_changeCardType_shouldCrash() {
new ConditionFooterContextualCard.Builder()
.setCardType(ContextualCard.CardType.LEGACY_SUGGESTION)
.build();
}
@Test
public void getCardType_shouldAlwaysBeConditionalFooter() {
assertThat(new ConditionFooterContextualCard.Builder().build().getCardType())
.isEqualTo(ContextualCard.CardType.CONDITIONAL_FOOTER);
}
}

View File

@@ -0,0 +1,43 @@
/*
* 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.homepage.contextualcards.conditional;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.homepage.contextualcards.ContextualCard;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ConditionHeaderContextualCardTest {
@Test(expected = IllegalArgumentException.class)
public void newInstance_changeCardType_shouldCrash() {
new ConditionHeaderContextualCard.Builder()
.setCardType(ContextualCard.CardType.LEGACY_SUGGESTION)
.build();
}
@Test
public void getCardType_shouldAlwaysBeConditionalHeader() {
assertThat(new ConditionHeaderContextualCard.Builder().build().getCardType())
.isEqualTo(ContextualCard.CardType.CONDITIONAL_HEADER);
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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.homepage.contextualcards.conditional;
import static com.android.settings.homepage.contextualcards.conditional.ConditionalContextualCard
.UNSUPPORTED_RANKING_SCORE;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.homepage.contextualcards.ContextualCard;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ConditionalContextualCardTest {
@Test(expected = IllegalArgumentException.class)
public void newInstance_changeCardType_shouldCrash() {
new ConditionalContextualCard.Builder()
.setCardType(ContextualCard.CardType.LEGACY_SUGGESTION)
.build();
}
@Test
public void getCardType_shouldAlwaysBeConditional() {
assertThat(new ConditionalContextualCard.Builder().build().getCardType())
.isEqualTo(ContextualCard.CardType.CONDITIONAL);
}
@Test
public void getRankingScore_shouldAlwaysBeUnsupportedScore() {
assertThat(new ConditionalContextualCard.Builder().build().getRankingScore())
.isEqualTo(UNSUPPORTED_RANKING_SCORE);
}
}

View File

@@ -0,0 +1,116 @@
/*
* 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.homepage.contextualcards.slices;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.face.FaceManager;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.widget.SliceLiveData;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class FaceSetupSliceTest {
private Context mContext;
private PackageManager mPackageManager;
@Before
public void setUp() {
// Set-up specs for SliceMetadata.
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
mContext = spy(ApplicationProvider.getApplicationContext());
mPackageManager = mock(PackageManager.class);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
}
@Test
public void getSlice_noFaceManager_shouldReturnNull() {
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(false);
final FaceSetupSlice setupSlice = new FaceSetupSlice(mContext);
final SliceMetadata metadata = SliceMetadata.from(mContext, setupSlice.getSlice());
assertThat(metadata.isErrorSlice()).isTrue();
}
@Test
public void getSlice_faceEnrolled_noReEnroll_shouldReturnNull() {
final FaceManager faceManager = mock(FaceManager.class);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
when(faceManager.hasEnrolledTemplates(UserHandle.myUserId())).thenReturn(true);
when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(faceManager);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.FACE_UNLOCK_RE_ENROLL,
0);
final FaceSetupSlice setupSlice = new FaceSetupSlice(mContext);
final SliceMetadata metadata = SliceMetadata.from(mContext, setupSlice.getSlice());
assertThat(metadata.isErrorSlice()).isTrue();
}
@Test
public void getSlice_faceNotEnrolled_shouldReturnSlice() {
final FaceManager faceManager = mock(FaceManager.class);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
when(faceManager.hasEnrolledTemplates(UserHandle.myUserId())).thenReturn(false);
when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(faceManager);
final FaceSetupSlice setupSlice = new FaceSetupSlice(mContext);
assertThat(setupSlice.getSlice()).isNotNull();
}
@Test
public void getSlice_faceEnrolled_shouldReEnroll_shouldReturnSlice() {
final FaceManager faceManager = mock(FaceManager.class);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
when(faceManager.hasEnrolledTemplates(UserHandle.myUserId())).thenReturn(true);
when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(faceManager);
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.FACE_UNLOCK_RE_ENROLL,
1);
final FaceSetupSlice setupSlice = new FaceSetupSlice(mContext);
assertThat(setupSlice.getSlice()).isNotNull();
}
@Test
public void getSlice_faceEnrolled_musteEnroll_shouldReturnSlice() {
final FaceManager faceManager = mock(FaceManager.class);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
when(faceManager.hasEnrolledTemplates(UserHandle.myUserId())).thenReturn(true);
when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(faceManager);
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.FACE_UNLOCK_RE_ENROLL,
3);
final FaceSetupSlice setupSlice = new FaceSetupSlice(mContext);
assertThat(setupSlice.getSlice()).isNotNull();
}
}

View File

@@ -0,0 +1,104 @@
/*
* 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 android.content.Context;
import android.telephony.ims.ImsException;
/**
* Controller class for mock VT status
*/
public class MockVtQueryImsState extends VtQueryImsState {
private Boolean mIsTtyOnVolteEnabled;
private Boolean mIsEnabledOnPlatform;
private Boolean mIsProvisionedOnDevice;
private Boolean mIsEnabledByUser;
private Boolean mIsServiceStateReady;
/**
* Constructor
*
* @param context {@link Context}
* @param subId subscription's id
*/
public MockVtQueryImsState(Context context, int subId) {
super(context, subId);
}
public void setIsTtyOnVolteEnabled(boolean enabled) {
mIsTtyOnVolteEnabled = enabled;
}
@Override
boolean isTtyOnVolteEnabled(int subId) {
if (mIsTtyOnVolteEnabled != null) {
return mIsTtyOnVolteEnabled;
}
return super.isTtyOnVolteEnabled(subId);
}
public void setIsEnabledByPlatform(boolean isEnabled) {
mIsEnabledOnPlatform = isEnabled;
}
@Override
boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException,
IllegalArgumentException {
if (mIsEnabledOnPlatform != null) {
return mIsEnabledOnPlatform;
}
return super.isEnabledByPlatform(subId);
}
public void setIsProvisionedOnDevice(boolean isProvisioned) {
mIsProvisionedOnDevice = isProvisioned;
}
@Override
boolean isProvisionedOnDevice(int subId) {
if (mIsProvisionedOnDevice != null) {
return mIsProvisionedOnDevice;
}
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;
}
@Override
boolean isEnabledByUser(int subId) {
if (mIsEnabledByUser != null) {
return mIsEnabledByUser;
}
return super.isEnabledByUser(subId);
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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 android.content.Context;
import android.telephony.ims.ImsException;
/**
* Controller class for mock Wifi calling status
*/
public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
private Boolean mIsTtyOnVolteEnabled;
private Boolean mIsEnabledOnPlatform;
private Boolean mIsProvisionedOnDevice;
private Boolean mIsServiceStateReady;
private Boolean mIsEnabledByUser;
/**
* Constructor
*
* @param context {@code Context}
* @param subId subscription's id
*/
public MockWifiCallingQueryImsState(Context context, int subId) {
super(context, subId);
}
public void setIsTtyOnVolteEnabled(boolean enabled) {
mIsTtyOnVolteEnabled = enabled;
}
@Override
boolean isTtyOnVolteEnabled(int subId) {
if (mIsTtyOnVolteEnabled != null) {
return mIsTtyOnVolteEnabled;
}
return super.isTtyOnVolteEnabled(subId);
}
public void setIsEnabledByPlatform(boolean isEnabled) {
mIsEnabledOnPlatform = isEnabled;
}
@Override
boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException,
IllegalArgumentException {
if (mIsEnabledOnPlatform != null) {
return mIsEnabledOnPlatform;
}
return super.isEnabledByPlatform(subId);
}
public void setIsProvisionedOnDevice(boolean isProvisioned) {
mIsProvisionedOnDevice = isProvisioned;
}
@Override
boolean isProvisionedOnDevice(int subId) {
if (mIsProvisionedOnDevice != null) {
return mIsProvisionedOnDevice;
}
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;
}
@Override
boolean isEnabledByUser(int subId) {
if (mIsEnabledByUser != null) {
return mIsEnabledByUser;
}
return super.isEnabledByUser(subId);
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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.nfc;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class NfcDetectionPointControllerTest {
private NfcDetectionPointController mController;
@Before
public void setUp() {
mController = new NfcDetectionPointController(ApplicationProvider.getApplicationContext(),
"fakeKey");
}
@Test
public void getAvailabilityStatus_withConfigIsTrue_returnAvailable() {
mController.setConfig(true);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(NfcDetectionPointController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_withConfigIsFalse_returnUnavailable() {
mController.setConfig(false);
assertThat(mController.getAvailabilityStatus())
.isNotEqualTo(NfcDetectionPointController.AVAILABLE);
}
}

View File

@@ -0,0 +1,46 @@
/*
* 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.nfc;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SecureNfcPreferenceControllerTest {
private Context mContext;
private SecureNfcPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new SecureNfcPreferenceController(mContext, "nfc_secure_settings");
}
@Test
public void isPublicSlice_returnsTrue() {
assertThat(mController.isPublicSlice()).isTrue();
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.notification.zen;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.service.notification.ZenPolicy;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
abstract class ZenRuleCustomPrefContrTestBase {
public static final String RULE_ID = "test_rule_id";
public static final String PREF_KEY = "main_pref";
AutomaticZenRule mRule = new AutomaticZenRule("test", null, null, null, null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
abstract AbstractZenCustomRulePreferenceController getController();
void updateControllerZenPolicy(ZenPolicy policy) {
mRule.setZenPolicy(policy);
getController().onResume(mRule, RULE_ID);
}
}

View File

@@ -0,0 +1,119 @@
/*
* 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.panel;
import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.net.Uri;
import androidx.core.graphics.drawable.IconCompat;
import java.util.Arrays;
import java.util.List;
/**
* Fake PanelContent for testing.
*/
public class FakePanelContent implements PanelContent {
public static final String FAKE_ACTION = "fake_action";
public static final CharSequence TITLE = "title";
public static final List<Uri> SLICE_URIS = Arrays.asList(
WIFI_SLICE_URI
);
public static final Intent INTENT = new Intent();
private CharSequence mTitle = TITLE;
private CharSequence mSubTitle;
private IconCompat mIcon;
private int mViewType;
private boolean mIsCustomizedButtonUsed = false;
private CharSequence mCustomizedButtonTitle;
@Override
public IconCompat getIcon() {
return mIcon;
}
public void setIcon(IconCompat icon) {
mIcon = icon;
}
@Override
public CharSequence getSubTitle() {
return mSubTitle;
}
public void setSubTitle(CharSequence subTitle) {
mSubTitle = subTitle;
}
@Override
public CharSequence getTitle() {
return mTitle;
}
public void setTitle(CharSequence title) {
mTitle = title;
}
@Override
public List<Uri> getSlices() {
return SLICE_URIS;
}
@Override
public Intent getSeeMoreIntent() {
return INTENT;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.TESTING;
}
public void setViewType(int viewType) {
mViewType = viewType;
}
@Override
public int getViewType() {
return mViewType;
}
@Override
public boolean isCustomizedButtonUsed() {
return mIsCustomizedButtonUsed;
}
public void setIsCustomizedButtonUsed(boolean isUsed) {
mIsCustomizedButtonUsed = isUsed;
}
@Override
public CharSequence getCustomizedButtonTitle() {
return mCustomizedButtonTitle;
}
public void setCustomizedButtonTitle(CharSequence title) {
mCustomizedButtonTitle = title;
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.panel;
import android.content.ComponentName;
import android.content.Intent;
public class FakeSettingsPanelActivity extends SettingsPanelActivity {
@Override
public ComponentName getCallingActivity() {
return new ComponentName("fake-package", "fake-class");
}
@Override
public Intent getIntent() {
final Intent intent = new Intent(FakePanelContent.FAKE_ACTION);
return intent;
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.panel;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.slices.CustomSliceRegistry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class NfcPanelTest {
private NfcPanel mPanel;
@Before
public void setUp() {
mPanel = NfcPanel.create(ApplicationProvider.getApplicationContext());
}
@Test
public void getSlices_containsNecessarySlices() {
final List<Uri> uris = mPanel.getSlices();
assertThat(uris).containsExactly(
CustomSliceRegistry.NFC_SLICE_URI);
}
@Test
public void getSeeMoreIntent_notNull() {
assertThat(mPanel.getSeeMoreIntent()).isNotNull();
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.panel;
import static com.android.settings.panel.SettingsPanelActivity.KEY_MEDIA_PACKAGE_NAME;
import static com.android.settings.panel.SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.Bundle;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class PanelFeatureProviderImplTest {
private static final String TEST_PACKAGENAME = "com.test.packagename";
private Context mContext;
private PanelFeatureProviderImpl mProvider;
private Bundle mBundle;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mProvider = new PanelFeatureProviderImpl();
mBundle = new Bundle();
mBundle.putString(KEY_MEDIA_PACKAGE_NAME, TEST_PACKAGENAME);
}
@Test
public void getPanel_internetConnectivityKey_returnsCorrectPanel() {
mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
final PanelContent panel = mProvider.getPanel(mContext, mBundle);
assertThat(panel).isInstanceOf(InternetConnectivityPanel.class);
}
@Test
public void getPanel_volume_returnsCorrectPanel() {
mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, Settings.Panel.ACTION_VOLUME);
final PanelContent panel = mProvider.getPanel(mContext, mBundle);
assertThat(panel).isInstanceOf(VolumePanel.class);
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.panel;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class PanelSlicesLoaderCountdownLatchTest {
private Context mContext;
private PanelSlicesLoaderCountdownLatch mSliceCountdownLatch;
private static final Uri[] URIS = new Uri[] {
Uri.parse("content://testUri"),
Uri.parse("content://wowUri"),
Uri.parse("content://boxTurtle")
};
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mSliceCountdownLatch = new PanelSlicesLoaderCountdownLatch(URIS.length);
}
@Test
public void hasLoaded_newObject_returnsFalse() {
assertThat(mSliceCountdownLatch.isSliceLoaded(URIS[0])).isFalse();
}
@Test
public void hasLoaded_markSliceLoaded_returnsTrue() {
mSliceCountdownLatch.markSliceLoaded(URIS[0]);
assertThat(mSliceCountdownLatch.isSliceLoaded(URIS[0])).isTrue();
}
@Test
public void markSliceLoaded_onlyCountsDownUniqueUris() {
for (int i = 0; i < URIS.length; i++) {
mSliceCountdownLatch.markSliceLoaded(URIS[0]);
}
assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isFalse();
}
@Test
public void areSlicesReadyToLoad_allSlicesLoaded_returnsTrue() {
for (int i = 0; i < URIS.length; i++) {
mSliceCountdownLatch.markSliceLoaded(URIS[i]);
}
assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isTrue();
}
@Test
public void areSlicesReadyToLoad_onlyReturnsTrueOnce() {
for (int i = 0; i < URIS.length; i++) {
mSliceCountdownLatch.markSliceLoaded(URIS[i]);
}
// Verify that it returns true once
assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isTrue();
// Verify the second call returns false without external state change
assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isFalse();
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.panel;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.slices.CustomSliceRegistry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class WifiPanelTest {
private WifiPanel mPanel;
@Before
public void setUp() {
mPanel = WifiPanel.create(ApplicationProvider.getApplicationContext());
}
@Test
public void getSlices_containsNecessarySlices() {
final List<Uri> uris = mPanel.getSlices();
assertThat(uris).containsExactly(
CustomSliceRegistry.WIFI_SLICE_URI);
}
@Test
public void getSeeMoreIntent_notNull() {
assertThat(mPanel.getSeeMoreIntent()).isNotNull();
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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.password;
import static com.google.common.truth.Truth.assertThat;
import android.app.admin.DevicePolicyManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ScreenLockTypeTest {
@Test
public void fromQuality_shouldReturnLockWithAssociatedQuality() {
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC))
.isEqualTo(ScreenLockType.PASSWORD);
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC))
.isEqualTo(ScreenLockType.PASSWORD);
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK))
.isNull();
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX))
.isEqualTo(ScreenLockType.PASSWORD);
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_MANAGED))
.isEqualTo(ScreenLockType.MANAGED);
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC))
.isEqualTo(ScreenLockType.PIN);
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX))
.isEqualTo(ScreenLockType.PIN);
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING))
.isEqualTo(ScreenLockType.PATTERN);
assertThat(ScreenLockType.fromQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(ScreenLockType.SWIPE);
}
@Test
public void fromKey_shouldReturnLockWithGivenKey() {
for (ScreenLockType lock : ScreenLockType.values()) {
assertThat(ScreenLockType.fromKey(lock.preferenceKey)).isEqualTo(lock);
}
assertThat(ScreenLockType.fromKey("nonexistent")).isNull();
}
}

View File

@@ -0,0 +1,107 @@
/*
* 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.search;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.DisplaySettings;
import com.android.settings.backup.UserBackupSettingsActivity;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.usb.UsbDetailsFragment;
import com.android.settings.fuelgauge.PowerUsageAdvanced;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.gestures.GestureNavigationSettingsFragment;
import com.android.settings.gestures.SystemNavigationGestureSettings;
import com.android.settings.location.LocationSettings;
import com.android.settings.location.RecentLocationRequestSeeAllFragment;
import com.android.settings.network.NetworkDashboardFragment;
import com.android.settings.notification.zen.ZenModeBlockedEffectsSettings;
import com.android.settings.notification.zen.ZenModeRestrictNotificationsSettings;
import com.android.settings.security.SecuritySettings;
import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.system.SystemDashboardFragment;
import com.android.settings.wallpaper.WallpaperSuggestionActivity;
import com.android.settings.wifi.WifiSettings;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class CustomSiteMapRegistryTest {
@Test
public void shouldContainScreenLockSettingsPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(ScreenLockSettings.class.getName()))
.isEqualTo(SecuritySettings.class.getName());
}
@Test
public void shouldContainWallpaperSuggestionActivityPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(
WallpaperSuggestionActivity.class.getName()))
.isEqualTo(DisplaySettings.class.getName());
}
@Test
public void shouldContainWifiSettingsPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(WifiSettings.class.getName()))
.isEqualTo(NetworkDashboardFragment.class.getName());
}
@Test
public void shouldContainPowerUsageAdvancedPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(PowerUsageAdvanced.class.getName()))
.isEqualTo(PowerUsageSummary.class.getName());
}
@Test
public void shouldContainRecentLocationRequestSeeAllFragmentPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(
RecentLocationRequestSeeAllFragment.class.getName())).isEqualTo(
LocationSettings.class.getName());
}
@Test
public void shouldContainUsbDetailsFragmentPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(
UsbDetailsFragment.class.getName())).isEqualTo(
ConnectedDeviceDashboardFragment.class.getName());
}
@Test
public void shouldContainUserBackupSettingsActivityPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(
UserBackupSettingsActivity.class.getName())).isEqualTo(
SystemDashboardFragment.class.getName());
}
@Test
public void shouldContainZenModeBlockedEffectsSettingsPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(
ZenModeBlockedEffectsSettings.class.getName())).isEqualTo(
ZenModeRestrictNotificationsSettings.class.getName());
}
@Test
public void shouldContainGestureNavigationSettingsFragmentPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(
GestureNavigationSettingsFragment.class.getName())).isEqualTo(
SystemNavigationGestureSettings.class.getName());
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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.search;
import android.util.Log;
import com.android.settingslib.search.Indexable;
import java.lang.reflect.Field;
/**
* Utility class for {@like DatabaseIndexingManager} to handle the mapping between Payloads
* and Preference controllers, and managing indexable classes.
*/
public class DatabaseIndexingUtils {
private static final String TAG = "IndexingUtil";
public static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER =
"SEARCH_INDEX_DATA_PROVIDER";
public static Indexable.SearchIndexProvider getSearchIndexProvider(final Class<?> clazz) {
try {
final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER);
return (Indexable.SearchIndexProvider) f.get(null);
} catch (NoSuchFieldException e) {
Log.d(TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
} catch (SecurityException se) {
Log.d(TAG,
"Security exception for field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
} catch (IllegalAccessException e) {
Log.d(TAG, "Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
} catch (IllegalArgumentException e) {
Log.d(TAG, "Illegal argument when accessing field '"
+ FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
}
return null;
}
}

View File

@@ -0,0 +1,117 @@
/*
* 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.search;
import android.content.Context;
import android.provider.SearchIndexableResource;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexableRaw;
import java.util.ArrayList;
import java.util.List;
/**
* Test class for Settings Search Indexing.
* If you change this class, please run robotests to make sure they still pass.
*/
public class FakeSettingsFragment extends DashboardFragment {
public static final String TITLE = "raw title";
public static final String SUMMARY_ON = "raw summary on";
public static final String SUMMARY_OFF = "raw summary off";
public static final String ENTRIES = "rawentries";
public static final String KEYWORDS = "keywords, keywordss, keywordsss";
public static final String SPACE_KEYWORDS = "keywords keywordss keywordsss";
public static final String SCREEN_TITLE = "raw screen title";
public static final String CLASS_NAME = FakeSettingsFragment.class.getName();
public static final int ICON = 0xff;
public static final String INTENT_ACTION = "raw action";
public static final String PACKAGE_NAME = "raw target package";
public static final String TARGET_CLASS = "raw target class";
public static final String TARGET_PACKAGE = "raw package name";
public static final String KEY = "raw key";
public static final boolean ENABLED = true;
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.DISPLAY;
}
@Override
protected String getLogTag() {
return "";
}
@Override
protected int getPreferenceScreenResId() {
return com.android.settings.R.xml.display_settings;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return null;
}
/** Index provider used to expose this fragment in search. */
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context,
boolean enabled) {
final SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = TITLE;
data.summaryOn = SUMMARY_ON;
data.summaryOff = SUMMARY_OFF;
data.entries = ENTRIES;
data.keywords = KEYWORDS;
data.screenTitle = SCREEN_TITLE;
data.packageName = PACKAGE_NAME;
data.intentAction = INTENT_ACTION;
data.intentTargetClass = TARGET_CLASS;
data.intentTargetPackage = TARGET_PACKAGE;
data.key = KEY;
data.iconResId = ICON;
data.enabled = ENABLED;
final List<SearchIndexableRaw> result = new ArrayList<>(1);
result.add(data);
return result;
}
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
final ArrayList<SearchIndexableResource> result = new ArrayList<>();
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = com.android.settings.R.xml.display_settings;
result.add(sir);
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
keys.add("pref_key_1");
keys.add("pref_key_3");
return keys;
}
};
}

View File

@@ -0,0 +1,204 @@
/*
* 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.search;
import static com.google.common.truth.Truth.assertWithMessage;
import android.provider.SearchIndexableResource;
import android.util.ArraySet;
import android.util.Log;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.core.codeinspection.CodeInspector;
import com.android.settings.dashboard.DashboardFragmentSearchIndexProviderInspector;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexableData;
import com.android.settingslib.search.SearchIndexableResources;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* {@link CodeInspector} to ensure fragments implement search components correctly.
*/
public class SearchIndexProviderCodeInspector extends CodeInspector {
private static final String TAG = "SearchCodeInspector";
private static final String NOT_CONTAINING_PROVIDER_OBJECT_ERROR =
"Indexable should have public field "
+ DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
+ " but these are not:\n";
private static final String NOT_SHARING_PREF_CONTROLLERS_BETWEEN_FRAG_AND_PROVIDER =
"DashboardFragment should share pref controllers with its SearchIndexProvider, but "
+ " these are not: \n";
private static final String NOT_IN_INDEXABLE_PROVIDER_REGISTRY =
"Class containing " + DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
+ " must be added to " + SearchIndexableResources.class.getName()
+ " but these are not: \n";
private static final String NOT_PROVIDING_VALID_RESOURCE_ERROR =
"SearchIndexableProvider must either provide no resource to index, or valid ones. "
+ "But the followings contain resource with xml id = 0\n";
private final List<String> mNotImplementingIndexProviderExemptList;
private final List<String> mNotInSearchIndexableRegistryExemptList;
private final List<String> mNotSharingPrefControllersExemptList;
public SearchIndexProviderCodeInspector(List<Class<?>> classes) {
super(classes);
mNotImplementingIndexProviderExemptList = new ArrayList<>();
mNotInSearchIndexableRegistryExemptList = new ArrayList<>();
mNotSharingPrefControllersExemptList = new ArrayList<>();
initializeExemptList(mNotImplementingIndexProviderExemptList,
"exempt_not_implementing_index_provider");
initializeExemptList(mNotInSearchIndexableRegistryExemptList,
"exempt_not_in_search_index_provider_registry");
initializeExemptList(mNotSharingPrefControllersExemptList,
"exempt_not_sharing_pref_controllers_with_search_provider");
}
@Override
public void run() {
final Set<String> notImplementingIndexProvider = new ArraySet<>();
final Set<String> notInSearchProviderRegistry = new ArraySet<>();
final Set<String> notSharingPreferenceControllers = new ArraySet<>();
final Set<String> notProvidingValidResource = new ArraySet<>();
final Set<Class> providerClasses = new ArraySet<>();
final SearchFeatureProvider provider = new SearchFeatureProviderImpl();
for (SearchIndexableData bundle :
provider.getSearchIndexableResources().getProviderValues()) {
providerClasses.add(bundle.getTargetClass());
}
for (Class clazz : mClasses) {
if (!isConcreteSettingsClass(clazz)) {
continue;
}
final String className = clazz.getName();
// Skip fragments if it's not SettingsPreferenceFragment.
if (!SettingsPreferenceFragment.class.isAssignableFrom(clazz)) {
continue;
}
final boolean hasSearchIndexProvider = hasSearchIndexProvider(clazz);
// If it implements Indexable, it must also implement the index provider field.
if (!hasSearchIndexProvider) {
if (!mNotImplementingIndexProviderExemptList.remove(className)) {
notImplementingIndexProvider.add(className);
}
continue;
}
// If it implements index provider field AND it's a DashboardFragment, its fragment and
// search provider must share the same set of PreferenceControllers.
final boolean isSharingPrefControllers = DashboardFragmentSearchIndexProviderInspector
.isSharingPreferenceControllers(clazz);
if (!isSharingPrefControllers) {
if (!mNotSharingPrefControllersExemptList.remove(className)) {
notSharingPreferenceControllers.add(className);
}
continue;
}
// Must be in SearchProviderRegistry
if (!providerClasses.contains(clazz)) {
if (!mNotInSearchIndexableRegistryExemptList.remove(className)) {
notInSearchProviderRegistry.add(className);
}
}
// Search provider must either don't provider resource xml, or provide valid ones.
if (!hasValidResourceFromProvider(clazz)) {
notProvidingValidResource.add(className);
}
}
// Build error messages
final String indexProviderError = buildErrorMessage(NOT_CONTAINING_PROVIDER_OBJECT_ERROR,
notImplementingIndexProvider);
final String notSharingPrefControllerError = buildErrorMessage(
NOT_SHARING_PREF_CONTROLLERS_BETWEEN_FRAG_AND_PROVIDER,
notSharingPreferenceControllers);
final String notInProviderRegistryError =
buildErrorMessage(NOT_IN_INDEXABLE_PROVIDER_REGISTRY, notInSearchProviderRegistry);
final String notProvidingValidResourceError = buildErrorMessage(
NOT_PROVIDING_VALID_RESOURCE_ERROR, notProvidingValidResource);
assertWithMessage(indexProviderError)
.that(notImplementingIndexProvider)
.isEmpty();
assertWithMessage(notSharingPrefControllerError)
.that(notSharingPreferenceControllers)
.isEmpty();
assertWithMessage(notInProviderRegistryError)
.that(notInSearchProviderRegistry)
.isEmpty();
assertWithMessage(notProvidingValidResourceError)
.that(notProvidingValidResource)
.isEmpty();
assertNoObsoleteInExemptList("exempt_not_implementing_index_provider",
mNotImplementingIndexProviderExemptList);
assertNoObsoleteInExemptList("exempt_not_in_search_index_provider_registry",
mNotInSearchIndexableRegistryExemptList);
assertNoObsoleteInExemptList(
"exempt_not_sharing_pref_controllers_with_search_provider",
mNotSharingPrefControllersExemptList);
}
private boolean hasSearchIndexProvider(Class clazz) {
try {
final Field f = clazz.getField(
DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER);
return f != null;
} catch (NoClassDefFoundError e) {
// Cannot find class def, ignore
return true;
} catch (NoSuchFieldException e) {
Log.e(TAG, "error fetching search provider from class " + clazz.getName());
return false;
}
}
private boolean hasValidResourceFromProvider(Class clazz) {
try {
final Indexable.SearchIndexProvider provider =
DatabaseIndexingUtils.getSearchIndexProvider(clazz);
final List<SearchIndexableResource> resources = provider.getXmlResourcesToIndex(
ApplicationProvider.getApplicationContext(), true /* enabled */);
if (resources == null) {
// No resource, that's fine.
return true;
}
for (SearchIndexableResource res : resources) {
if (res.xmlResId == 0) {
// Invalid resource
return false;
}
}
} catch (Exception e) {
// Ignore.
}
return true;
}
private String buildErrorMessage(String errorSummary, Set<String> errorClasses) {
final StringBuilder error = new StringBuilder(errorSummary);
for (String c : errorClasses) {
error.append(c).append("\n");
}
return error.toString();
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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.security;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class CredentialManagementAppButtonsControllerTest {
private Context mContext;
private CredentialManagementAppButtonsController mController;
private static final String PREF_KEY_CREDENTIAL_MANAGEMENT_APP = "certificate_management_app";
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new CredentialManagementAppButtonsController(
mContext, PREF_KEY_CREDENTIAL_MANAGEMENT_APP);
}
@Test
public void getAvailabilityStatus_shouldAlwaysReturnAvailableUnsearchable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE_UNSEARCHABLE);
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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.security;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class CredentialManagementAppHeaderControllerTest {
private Context mContext;
private CredentialManagementAppHeaderController mController;
private static final String PREF_KEY_CREDENTIAL_MANAGEMENT_APP = "certificate_management_app";
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new CredentialManagementAppHeaderController(
mContext, PREF_KEY_CREDENTIAL_MANAGEMENT_APP);
}
@Test
public void getAvailabilityStatus_shouldAlwaysReturnAvailableUnsearchable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE_UNSEARCHABLE);
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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.slices;
import android.content.Context;
import com.android.settings.core.BasePreferenceController;
public class FakeContextOnlyPreferenceController extends BasePreferenceController {
public static final String KEY = "fakeController2";
public FakeContextOnlyPreferenceController(Context context) {
super(context, KEY);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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.slices;
import android.content.Context;
import com.android.settings.core.BasePreferenceController;
public class FakePreferenceController extends BasePreferenceController {
public FakePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public int getSliceType() {
return SliceData.SliceType.SLIDER;
}
@Override
public boolean isSliceable() {
return true;
}
@Override
public boolean isPublicSlice() {
return true;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
}

View File

@@ -0,0 +1,174 @@
/*
* 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.slices;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_CONTROLLER;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.content.Context;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.text.TextUtils;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.PreferenceXmlParserUtils;
import com.android.settings.core.SliderPreferenceController;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.core.codeinspection.CodeInspector;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settings.search.SearchFeatureProviderImpl;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexableData;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class SliceControllerInXmlCodeInspector extends CodeInspector {
private static final List<Class> sSliceControllerClasses = Arrays.asList(
TogglePreferenceController.class,
SliderPreferenceController.class
);
private final List<String> mXmlDeclaredControllers = new ArrayList<>();
private final List<String> mExemptedClasses = new ArrayList<>();
private static final String ERROR_MISSING_CONTROLLER =
"The following controllers were expected to be declared by "
+ "'settings:controller=Controller_Class_Name' in their corresponding Xml. "
+ "If it should not appear in XML, add the controller's classname to "
+ "exempt_slice_controller_not_in_xml. Controllers:\n";
private final Context mContext;
private final SearchFeatureProvider mSearchProvider;
private final FakeFeatureFactory mFakeFeatureFactory;
public SliceControllerInXmlCodeInspector(List<Class<?>> classes) throws Exception {
super(classes);
mContext = ApplicationProvider.getApplicationContext();
mSearchProvider = new SearchFeatureProviderImpl();
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
mFakeFeatureFactory.searchFeatureProvider = mSearchProvider;
CodeInspector.initializeExemptList(mExemptedClasses,
"exempt_slice_controller_not_in_xml");
initDeclaredControllers();
}
private void initDeclaredControllers() throws IOException, XmlPullParserException {
final List<Integer> xmlResources = getIndexableXml();
for (int xmlResId : xmlResources) {
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
xmlResId, PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_PREF_CONTROLLER);
for (Bundle bundle : metadata) {
final String controllerClassName = bundle.getString(METADATA_CONTROLLER);
if (TextUtils.isEmpty(controllerClassName)) {
continue;
}
mXmlDeclaredControllers.add(controllerClassName);
}
}
// We definitely have some controllers in xml, so assert not-empty here as a proxy to
// make sure the parser didn't fail
assertThat(mXmlDeclaredControllers).isNotEmpty();
}
@Override
public void run() {
final List<String> missingControllersInXml = new ArrayList<>();
for (Class<?> clazz : mClasses) {
if (!isConcreteSettingsClass(clazz)) {
// Only care about non-abstract classes.
continue;
}
if (!isInlineSliceClass(clazz)) {
// Only care about inline-slice controller classes.
continue;
}
if (!mXmlDeclaredControllers.contains(clazz.getName())) {
// Class clazz should have been declared in XML (unless allowlisted).
missingControllersInXml.add(clazz.getName());
}
}
// Removed allowlisted classes
missingControllersInXml.removeAll(mExemptedClasses);
final String missingControllerError =
buildErrorMessage(ERROR_MISSING_CONTROLLER, missingControllersInXml);
assertWithMessage(missingControllerError).that(missingControllersInXml).isEmpty();
}
private boolean isInlineSliceClass(Class clazz) {
while (clazz != null) {
clazz = clazz.getSuperclass();
if (sSliceControllerClasses.contains(clazz)) {
return true;
}
}
return false;
}
private String buildErrorMessage(String errorSummary, List<String> errorClasses) {
final StringBuilder error = new StringBuilder(errorSummary);
for (String c : errorClasses) {
error.append(c).append("\n");
}
return error.toString();
}
private List<Integer> getIndexableXml() {
final List<Integer> xmlResSet = new ArrayList<>();
final Collection<SearchIndexableData> bundles = FeatureFactory.getFactory(
mContext).getSearchFeatureProvider().getSearchIndexableResources()
.getProviderValues();
for (SearchIndexableData bundle : bundles) {
Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
if (provider == null) {
continue;
}
List<SearchIndexableResource> resources = provider.getXmlResourcesToIndex(mContext,
true);
if (resources == null) {
continue;
}
for (SearchIndexableResource resource : resources) {
// Add '0's anyway. It won't break the test.
xmlResSet.add(resource.xmlResId);
}
}
return xmlResSet;
}
}

View File

@@ -0,0 +1,287 @@
/*
* 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.slices;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SliceDataTest {
private static final String KEY = "KEY";
private static final String TITLE = "title";
private static final String SUMMARY = "summary";
private static final String SCREEN_TITLE = "screen title";
private static final String KEYWORDS = "a, b, c";
private static final String FRAGMENT_NAME = "fragment name";
private static final int ICON = 1234; // I declare a thumb war
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
private static final String PREF_CONTROLLER = "com.android.settings.slices.tester";
private static final int SLICE_TYPE = SliceData.SliceType.SWITCH;
private static final String UNAVAILABLE_SLICE_SUBTITLE = "subtitleOfUnavailableSlice";
@Test
public void testBuilder_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setKeywords(KEYWORDS)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.setSliceType(SLICE_TYPE)
.setUnavailableSliceSubtitle(UNAVAILABLE_SLICE_SUBTITLE)
.setIsPublicSlice(true);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isEqualTo(SUMMARY);
assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
assertThat(data.getKeywords()).isEqualTo(KEYWORDS);
assertThat(data.getIconResource()).isEqualTo(ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
assertThat(data.getSliceType()).isEqualTo(SLICE_TYPE);
assertThat(data.getUnavailableSliceSubtitle()).isEqualTo(UNAVAILABLE_SLICE_SUBTITLE);
assertThat(data.isPublicSlice()).isEqualTo(true);
}
@Test(expected = SliceData.InvalidSliceDataException.class)
public void testBuilder_noKey_throwsIllegalStateException() {
new SliceData.Builder()
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.build();
}
@Test(expected = SliceData.InvalidSliceDataException.class)
public void testBuilder_noTitle_throwsIllegalStateException() {
new SliceData.Builder()
.setKey(KEY)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.build();
}
@Test(expected = SliceData.InvalidSliceDataException.class)
public void testBuilder_noFragment_throwsIllegalStateException() {
new SliceData.Builder()
.setKey(KEY)
.setFragmentName(FRAGMENT_NAME)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.build();
}
@Test(expected = SliceData.InvalidSliceDataException.class)
public void testBuilder_noPrefController_throwsIllegalStateException() {
new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setUri(URI)
.setFragmentName(FRAGMENT_NAME)
.build();
}
@Test
public void testBuilder_noSubtitle_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isNull();
assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
assertThat(data.getIconResource()).isEqualTo(ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test
public void testBuilder_noScreenTitle_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isEqualTo(SUMMARY);
assertThat(data.getScreenTitle()).isNull();
assertThat(data.getIconResource()).isEqualTo(ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test
public void testBuilder_noIcon_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isEqualTo(SUMMARY);
assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
assertThat(data.getIconResource()).isEqualTo(0);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test
public void testBuilder_noUri_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(null)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isEqualTo(SUMMARY);
assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
assertThat(data.getIconResource()).isEqualTo(ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isNull();
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test
public void testEquality_identicalObjects() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData dataOne = builder.build();
SliceData dataTwo = builder.build();
assertThat(dataOne.hashCode()).isEqualTo(dataTwo.hashCode());
assertThat(dataOne).isEqualTo(dataTwo);
}
@Test
public void testEquality_matchingKey_EqualObjects() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData dataOne = builder.build();
builder.setTitle(TITLE + " diff")
.setSummary(SUMMARY + " diff")
.setScreenTitle(SCREEN_TITLE + " diff")
.setIcon(ICON + 1)
.setFragmentName(FRAGMENT_NAME + " diff")
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER + " diff");
SliceData dataTwo = builder.build();
assertThat(dataOne.hashCode()).isEqualTo(dataTwo.hashCode());
assertThat(dataOne).isEqualTo(dataTwo);
}
@Test
public void testEquality_differentKey_differentObjects() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData dataOne = builder.build();
builder.setKey("not key");
SliceData dataTwo = builder.build();
assertThat(dataOne.hashCode()).isNotEqualTo(dataTwo.hashCode());
assertThat(dataOne).isNotEqualTo(dataTwo);
}
}

View File

@@ -0,0 +1,82 @@
/*
* 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.slices;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.SettingsSlicesContract;
import com.android.settings.testutils.FakeIndexProvider;
import com.android.settings.testutils.FakeToggleController;
class SliceTestUtils {
public static final String FAKE_TITLE = "title";
public static final String FAKE_SUMMARY = "summary";
public static final String FAKE_SCREEN_TITLE = "screen_title";
public static final String FAKE_KEYWORDS = "a, b, c";
public static final int FAKE_ICON = 1234;
public static final String FAKE_FRAGMENT_NAME = FakeIndexProvider.class.getName();
public static final String FAKE_CONTROLLER_NAME = FakeToggleController.class.getName();
public static void insertSliceToDb(Context context, String key) {
insertSliceToDb(context, key, true /* isPlatformSlice */);
}
public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice) {
insertSliceToDb(context, key, isPlatformSlice, null /*customizedUnavailableSliceSubtitle*/);
}
public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice,
String customizedUnavailableSliceSubtitle) {
insertSliceToDb(context, key, isPlatformSlice, customizedUnavailableSliceSubtitle, false);
}
public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice,
String customizedUnavailableSliceSubtitle, boolean isPublicSlice) {
final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(context).getWritableDatabase();
ContentValues values = new ContentValues();
values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
values.put(SlicesDatabaseHelper.IndexColumns.SLICE_URI,
new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(isPlatformSlice
? SettingsSlicesContract.AUTHORITY
: SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath(key)
.build().toSafeString());
values.put(SlicesDatabaseHelper.IndexColumns.TITLE, FAKE_TITLE);
values.put(SlicesDatabaseHelper.IndexColumns.SUMMARY, FAKE_SUMMARY);
values.put(SlicesDatabaseHelper.IndexColumns.SCREENTITLE, FAKE_SCREEN_TITLE);
values.put(SlicesDatabaseHelper.IndexColumns.KEYWORDS, FAKE_KEYWORDS);
values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, FAKE_ICON);
values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, FAKE_FRAGMENT_NAME);
values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, FAKE_CONTROLLER_NAME);
values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
values.put(SlicesDatabaseHelper.IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
customizedUnavailableSliceSubtitle);
values.put(SlicesDatabaseHelper.IndexColumns.PUBLIC_SLICE, isPublicSlice);
db.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
db.close();
}
}

View File

@@ -0,0 +1,147 @@
/*
* 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.slices;
import static com.google.common.truth.Truth.assertThat;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.provider.SettingsSlicesContract;
import androidx.slice.Slice;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SpecialCaseSliceManagerTest {
private static final String FAKE_PARAMETER_KEY = "fake_parameter_key";
private static final String FAKE_PARAMETER_VALUE = "fake_value";
private Context mContext;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
CustomSliceRegistry.sUriToSlice.clear();
CustomSliceRegistry.sUriToSlice.put(FakeSliceable.URI, FakeSliceable.class);
}
@Test
public void getSliceableFromUri_returnsCorrectObject() {
final CustomSliceable sliceable = CustomSliceable.createInstance(
mContext, CustomSliceRegistry.getSliceClassByUri(FakeSliceable.URI));
assertThat(sliceable).isInstanceOf(FakeSliceable.class);
}
@Test
public void getSliceableFromUriWithParameter_returnsCorrectObject() {
final Uri parameterUri = FakeSliceable.URI
.buildUpon()
.clearQuery()
.appendQueryParameter(FAKE_PARAMETER_KEY, FAKE_PARAMETER_VALUE)
.build();
final CustomSliceable sliceable = CustomSliceable.createInstance(
mContext, CustomSliceRegistry.getSliceClassByUri(parameterUri));
assertThat(sliceable).isInstanceOf(FakeSliceable.class);
}
@Test
public void isValidUri_validUri_returnsTrue() {
final boolean isValidUri = CustomSliceRegistry.isValidUri(FakeSliceable.URI);
assertThat(isValidUri).isTrue();
}
@Test
public void isValidUri_invalidUri_returnsFalse() {
final boolean isValidUri = CustomSliceRegistry.isValidUri(null);
assertThat(isValidUri).isFalse();
}
@Test
public void isValidAction_validActions_returnsTrue() {
final boolean isValidAction =
CustomSliceRegistry.isValidAction(FakeSliceable.URI.toString());
assertThat(isValidAction).isTrue();
}
@Test
public void isValidAction_invalidAction_returnsFalse() {
final boolean isValidAction = CustomSliceRegistry.isValidAction("action");
assertThat(isValidAction).isFalse();
}
static class FakeSliceable implements CustomSliceable {
static final String KEY = "magic key of khazad dum";
static final Uri URI = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
.appendPath(KEY)
.build();
static final Slice SLICE = new Slice.Builder(URI).build();
static boolean sBackingData = false;
final Context mContext;
public FakeSliceable(Context context) {
mContext = context;
}
@Override
public Slice getSlice() {
return SLICE;
}
@Override
public Uri getUri() {
return URI;
}
@Override
public void onNotifyChange(Intent intent) {
sBackingData = !sBackingData;
}
@Override
public IntentFilter getIntentFilter() {
return new IntentFilter();
}
@Override
public Intent getIntent() {
return null;
}
}
}

View File

@@ -0,0 +1,97 @@
/*
* 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.sound;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class MediaControlsPreferenceControllerTest {
private static final String KEY = "media_controls_resume_switch";
private Context mContext;
private int mOriginalQs;
private int mOriginalResume;
private ContentResolver mContentResolver;
private MediaControlsPreferenceController mController;
@Before
public void setUp() {
mContext = spy(ApplicationProvider.getApplicationContext());
mContentResolver = mContext.getContentResolver();
mOriginalQs = Settings.Global.getInt(mContentResolver,
Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1);
mOriginalResume = Settings.Secure.getInt(mContentResolver,
Settings.Secure.MEDIA_CONTROLS_RESUME, 1);
mController = new MediaControlsPreferenceController(mContext, KEY);
}
@After
public void tearDown() {
Settings.Global.putInt(mContentResolver, Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS,
mOriginalQs);
Settings.Secure.putInt(mContentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME,
mOriginalResume);
}
@Test
public void getAvailability_returnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void setChecked_enable_shouldTurnOn() {
Settings.Global.putInt(mContentResolver, Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1);
Settings.Secure.putInt(mContentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME, 1);
assertThat(mController.isChecked()).isTrue();
mController.setChecked(false);
assertThat(Settings.Secure.getInt(mContentResolver,
Settings.Secure.MEDIA_CONTROLS_RESUME, -1)).isEqualTo(0);
}
@Test
public void setChecked_disable_shouldTurnOff() {
Settings.Global.putInt(mContentResolver, Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1);
Settings.Secure.putInt(mContentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME, 0);
assertThat(mController.isChecked()).isFalse();
mController.setChecked(true);
assertThat(Settings.Secure.getInt(mContentResolver,
Settings.Secure.MEDIA_CONTROLS_RESUME, -1)).isEqualTo(1);
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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.testutils;
import android.content.pm.ApplicationInfo;
/**
* Helper for mocking installed applications.
*/
public class ApplicationTestUtils {
/**
* Create and populate an {@link android.content.pm.ApplicationInfo} object that describes an
* installed app.
*
* @param uid The app's uid
* @param packageName The app's package name.
* @param flags Flags describing the app. See {@link android.content.pm.ApplicationInfo#flags}
* for possible values.
* @param targetSdkVersion The app's target SDK version
*
* @see android.content.pm.ApplicationInfo
*/
public static ApplicationInfo buildInfo(int uid, String packageName, int flags,
int targetSdkVersion) {
final ApplicationInfo info = new ApplicationInfo();
info.uid = uid;
info.packageName = packageName;
info.flags = flags;
info.targetSdkVersion = targetSdkVersion;
return info;
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.testutils;
import android.content.Intent;
import android.os.BatteryManager;
public class BatteryTestUtils {
public static Intent getChargingIntent() {
return getCustomBatteryIntent(
BatteryManager.BATTERY_PLUGGED_AC,
50 /* level */,
100 /* scale */,
BatteryManager.BATTERY_STATUS_CHARGING);
}
public static Intent getDischargingIntent() {
return getCustomBatteryIntent(
0 /* plugged */,
10 /* level */,
100 /* scale */,
BatteryManager.BATTERY_STATUS_DISCHARGING);
}
private static Intent getCustomBatteryIntent(int plugged, int level, int scale, int status) {
Intent intent = new Intent();
intent.putExtra(BatteryManager.EXTRA_PLUGGED, plugged);
intent.putExtra(BatteryManager.EXTRA_LEVEL, level);
intent.putExtra(BatteryManager.EXTRA_SCALE, scale);
intent.putExtra(BatteryManager.EXTRA_STATUS, status);
return intent;
}
}

View File

@@ -0,0 +1,26 @@
/*
* 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.testutils;
import android.app.Activity;
import android.content.Intent;
import android.os.UserHandle;
public class CustomActivity extends Activity {
@Override
public void startActivityAsUser(Intent intent, UserHandle user) {}
}

View File

@@ -0,0 +1,43 @@
/*
* 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.testutils;
import android.content.Context;
import com.android.settings.core.BasePreferenceController;
public class FakeCopyableController extends BasePreferenceController {
public FakeCopyableController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public boolean isSliceable() {
return true;
}
@Override
public boolean isCopyableSlice() {
return true;
}
}

View File

@@ -0,0 +1,46 @@
/*
* 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.testutils;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.Indexable;
import java.util.List;
public class FakeIndexProvider implements Indexable {
public static final String KEY = "TestKey";
/**
* The fake SearchIndexProvider. Note that the use of location_settings below implies that tests
* using this should be using the res/xml-mcc999/location_settings.xml or
* res/xml-mcc998/location_settings.xml. Annotate tests with
* {@code @Config(qualifiers = "mcc999")}.
*/
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.location_settings) {
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> result = super.getNonIndexableKeys(context);
result.add(KEY);
return result;
}
};
}

View File

@@ -0,0 +1,31 @@
/*
* 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.testutils;
import android.content.Context;
public class FakeInvalidSliderController extends FakeSliderController {
public FakeInvalidSliderController(Context context, String key) {
super(context, key);
}
@Override
public int getMax() {
// Return 0 to make it invalid
return 0;
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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.testutils;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.core.SliderPreferenceController;
public class FakeSliderController extends SliderPreferenceController {
public static final String AVAILABILITY_KEY = "fake_slider_availability_key";
public static final int MAX_VALUE = 9;
private static final String SETTING_KEY = "fake_slider_key";
public FakeSliderController(Context context, String key) {
super(context, key);
}
@Override
public int getSliderPosition() {
return Settings.System.getInt(mContext.getContentResolver(), SETTING_KEY, 0);
}
@Override
public boolean setSliderPosition(int position) {
return Settings.System.putInt(mContext.getContentResolver(), SETTING_KEY, position);
}
@Override
public int getMax() {
return MAX_VALUE;
}
@Override
public int getMin() {
return 0;
}
@Override
public int getAvailabilityStatus() {
return Settings.Global.getInt(mContext.getContentResolver(), AVAILABILITY_KEY, AVAILABLE);
}
@Override
public boolean isSliceable() {
return true;
}
}

View File

@@ -0,0 +1,105 @@
/*
* 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.testutils;
import android.content.Context;
import android.content.IntentFilter;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.slices.SliceBackgroundWorker;
public class FakeToggleController extends TogglePreferenceController {
public static final String AVAILABILITY_KEY = "fake_toggle_availability_key";
public static final IntentFilter INTENT_FILTER = new IntentFilter(
WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
private static final String SETTING_KEY = "toggle_key";
private static final int ON = 1;
private static final int OFF = 0;
private boolean mIsAsyncUpdate = false;
public FakeToggleController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public boolean isChecked() {
return Settings.System.getInt(mContext.getContentResolver(),
SETTING_KEY, OFF) == ON;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.System.putInt(mContext.getContentResolver(), SETTING_KEY,
isChecked ? ON : OFF);
}
@Override
public int getAvailabilityStatus() {
return Settings.Global.getInt(mContext.getContentResolver(),
AVAILABILITY_KEY, AVAILABLE);
}
@Override
public IntentFilter getIntentFilter() {
return INTENT_FILTER;
}
@Override
public boolean isSliceable() {
return true;
}
@Override
public Class<? extends SliceBackgroundWorker> getBackgroundWorkerClass() {
return TestWorker.class;
}
@Override
public boolean hasAsyncUpdate() {
return mIsAsyncUpdate;
}
public void setAsyncUpdate(boolean isAsyncUpdate) {
mIsAsyncUpdate = isAsyncUpdate;
}
public static class TestWorker extends SliceBackgroundWorker<Void> {
public TestWorker(Context context, Uri uri) {
super(context, uri);
}
@Override
protected void onSlicePinned() {
}
@Override
protected void onSliceUnpinned() {
}
@Override
public void close() {
}
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.testutils;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.core.BasePreferenceController;
public class FakeUnavailablePreferenceController extends BasePreferenceController {
public static final String AVAILABILITY_KEY = "fake_availability_key";
public FakeUnavailablePreferenceController(Context context) {
super(context, "key");
}
@Override
public int getAvailabilityStatus() {
return Settings.Global.getInt(mContext.getContentResolver(), AVAILABILITY_KEY, 0);
}
@Override
public boolean isSliceable() {
return true;
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.testutils;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import com.google.common.base.Preconditions;
/**
* Helper for building {@link ResolveInfo}s to be used in Robolectric tests.
*
* <p>The resulting {@link PackageInfo}s should typically be added to {@link
* org.robolectric.shadows.ShadowPackageManager#addResolveInfoForIntent(Intent, ResolveInfo)}.
*/
public final class ResolveInfoBuilder {
private final String mPackageName;
private ActivityInfo mActivityInfo;
private ProviderInfo mProviderInfo;
public ResolveInfoBuilder(String packageName) {
this.mPackageName = Preconditions.checkNotNull(packageName);
}
public ResolveInfoBuilder setActivity(String packageName, String className) {
mActivityInfo = new ActivityInfo();
mActivityInfo.packageName = packageName;
mActivityInfo.name = className;
return this;
}
public ResolveInfoBuilder setProvider(
String packageName, String className, String authority, boolean isSystemApp) {
mProviderInfo = new ProviderInfo();
mProviderInfo.authority = authority;
mProviderInfo.applicationInfo = new ApplicationInfo();
if (isSystemApp) {
mProviderInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
}
mProviderInfo.packageName = mPackageName;
mProviderInfo.applicationInfo.packageName = mPackageName;
mProviderInfo.name = className;
return this;
}
public ResolveInfo build() {
ResolveInfo info = new ResolveInfo();
info.activityInfo = mActivityInfo;
info.resolvePackageName = mPackageName;
info.providerInfo = mProviderInfo;
return info;
}
}

View File

@@ -0,0 +1,324 @@
/*
* 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.testutils;
import static android.app.slice.Slice.HINT_TITLE;
import static android.app.slice.Slice.SUBTYPE_COLOR;
import static android.app.slice.SliceItem.FORMAT_IMAGE;
import static android.app.slice.SliceItem.FORMAT_INT;
import static android.app.slice.SliceItem.FORMAT_TEXT;
import static com.google.common.truth.Truth.assertThat;
import android.app.PendingIntent;
import android.content.Context;
import android.text.TextUtils;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.builders.ListBuilder;
import androidx.slice.core.SliceAction;
import androidx.slice.core.SliceQuery;
import androidx.slice.widget.EventInfo;
import com.android.settings.Utils;
import com.android.settings.slices.SettingsSliceProvider;
import com.android.settings.slices.SliceBuilderUtils;
import com.android.settings.slices.SliceData;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Testing utility class to verify the contents of the different Settings Slices.
*
* TODO (77712944) check Summary, range (metadata.getRange()), toggle icons.
*/
public class SliceTester {
/**
* Test the contents of an intent based slice, including:
* - No toggles
* - Correct intent
* - Correct title
* - Correct keywords
* - TTL
* - Color
*/
public static void testSettingsIntentSlice(Context context, Slice slice, SliceData sliceData) {
final SliceMetadata metadata = SliceMetadata.from(context, slice);
final long sliceTTL = metadata.getExpiry();
assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
final int color = colorItem.getInt();
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).isEmpty();
final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
/**
* Test the contents of an toggle based slice, including:
* - Contains one toggle
* - Correct toggle intent
* - Correct content intent
* - Correct title
* - Correct keywords
* - TTL
* - Color
*/
public static void testSettingsToggleSlice(Context context, Slice slice, SliceData sliceData) {
final SliceMetadata metadata = SliceMetadata.from(context, slice);
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
final int color = colorItem.getInt();
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).hasSize(1);
final long sliceTTL = metadata.getExpiry();
assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
final SliceAction mainToggleAction = toggles.get(0);
assertThat(mainToggleAction.getIcon()).isNull();
// Check intent in Toggle Action
final PendingIntent togglePendingIntent = mainToggleAction.getAction();
assertThat(togglePendingIntent).isEqualTo(SliceBuilderUtils.getActionIntent(context,
SettingsSliceProvider.ACTION_TOGGLE_CHANGED, sliceData));
// Check primary intent
final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
/**
* Test the contents of an slider based slice, including:
* - No intent
* - Correct title
* - Correct keywords
* - TTL
* - Color
*/
public static void testSettingsSliderSlice(Context context, Slice slice, SliceData sliceData) {
final SliceMetadata metadata = SliceMetadata.from(context, slice);
final SliceAction primaryAction = metadata.getPrimaryAction();
final IconCompat icon = primaryAction.getIcon();
if (icon == null) {
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
final int color = colorItem.getInt();
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
} else {
final IconCompat expectedIcon = IconCompat.createWithResource(context,
sliceData.getIconResource());
assertThat(expectedIcon.toString()).isEqualTo(icon.toString());
}
final long sliceTTL = metadata.getExpiry();
assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
final int headerType = metadata.getHeaderType();
assertThat(headerType).isEqualTo(EventInfo.ROW_TYPE_SLIDER);
// Check primary intent
final PendingIntent primaryPendingIntent = primaryAction.getAction();
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
/**
* Test the copyable slice, including:
* - No intent
* - Correct title
* - Correct intent
* - Correct keywords
* - TTL
* - Color
*/
public static void testSettingsCopyableSlice(Context context, Slice slice,
SliceData sliceData) {
final SliceMetadata metadata = SliceMetadata.from(context, slice);
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
final int color = colorItem.getInt();
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
final SliceAction primaryAction = metadata.getPrimaryAction();
final IconCompat expectedIcon = IconCompat.createWithResource(context,
sliceData.getIconResource());
assertThat(expectedIcon.toString()).isEqualTo(primaryAction.getIcon().toString());
final long sliceTTL = metadata.getExpiry();
assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
// Check primary intent
final PendingIntent primaryPendingIntent = primaryAction.getAction();
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
/**
* Test the contents of an unavailable slice, including:
* - No toggles
* - Correct title
* - Correct intent
* - Correct keywords
* - Color
* - TTL
*/
public static void testSettingsUnavailableSlice(Context context, Slice slice,
SliceData sliceData) {
final SliceMetadata metadata = SliceMetadata.from(context, slice);
final long sliceTTL = metadata.getExpiry();
assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
final int color = colorItem.getInt();
assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).isEmpty();
final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
assertThat(primaryPendingIntent).isEqualTo(SliceBuilderUtils.getContentPendingIntent(
context, sliceData));
assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
/**
* Assert any slice item contains title.
*
* @param sliceItems All slice items of a Slice.
* @param title Title for asserting.
*/
public static void assertAnySliceItemContainsTitle(List<SliceItem> sliceItems, String title) {
assertThat(hasText(sliceItems, title, HINT_TITLE)).isTrue();
}
/**
* Assert any slice item contains subtitle.
*
* @param sliceItems All slice items of a Slice.
* @param subtitle Subtitle for asserting.
*/
public static void assertAnySliceItemContainsSubtitle(List<SliceItem> sliceItems,
String subtitle) {
// Subtitle has no hints
assertThat(hasText(sliceItems, subtitle, null /* hints */)).isTrue();
}
/**
* Assert no slice item contains subtitle.
*
* @param sliceItems All slice items of a Slice.
* @param subtitle Subtitle for asserting.
*/
public static void assertNoSliceItemContainsSubtitle(List<SliceItem> sliceItems,
String subtitle) {
// Subtitle has no hints
assertThat(hasText(sliceItems, subtitle, null /* hints */)).isFalse();
}
private static boolean hasText(List<SliceItem> sliceItems, String text, String hints) {
boolean hasText = false;
for (SliceItem item : sliceItems) {
List<SliceItem> textItems = SliceQuery.findAll(item, FORMAT_TEXT, hints,
null /* non-hints */);
if (textItems == null) {
continue;
}
for (SliceItem textItem : textItems) {
if (TextUtils.equals(textItem.getText(), text)) {
hasText = true;
break;
}
}
}
return hasText;
}
/**
* Assert any slice item contains icon.
*
* @param sliceItems All slice items of a Slice.
* @param icon Icon for asserting.
*/
public static void assertAnySliceItemContainsIcon(List<SliceItem> sliceItems, IconCompat icon) {
boolean hasIcon = false;
for (SliceItem item : sliceItems) {
List<SliceItem> iconItems = SliceQuery.findAll(item, FORMAT_IMAGE,
(String) null /* hints */, null /* non-hints */);
if (iconItems == null) {
continue;
}
for (SliceItem iconItem : iconItems) {
if (icon.toString().equals(iconItem.getIcon().toString())) {
hasIcon = true;
break;
}
}
}
assertThat(hasIcon).isTrue();
}
private static void assertKeywords(SliceMetadata metadata, SliceData data) {
final List<String> keywords = metadata.getSliceKeywords();
final Set<String> expectedKeywords = Arrays.stream(data.getKeywords().split(","))
.map(s -> s = s.trim())
.collect(Collectors.toSet());
expectedKeywords.add(data.getTitle());
expectedKeywords.add(data.getScreenTitle().toString());
assertThat(keywords).containsExactlyElementsIn(expectedKeywords);
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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.testutils;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag
.FLAG_INCLUDE_PREF_SCREEN;
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_KEY;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import com.android.settings.core.PreferenceXmlParserUtils;
import org.xmlpull.v1.XmlPullParserException;
import java.util.ArrayList;
import java.util.List;
/**
* Util class for parsing XML
*/
public class XmlTestUtils {
/**
* Parses a preference screen's xml, collects and returns all keys used by preferences
* on the screen.
*
* @param context of the preference screen.
* @param xmlId of the Preference Xml to be parsed.
* @return List of all keys in the preference Xml
*/
public static List<String> getKeysFromPreferenceXml(Context context, int xmlId) {
final List<String> keys = new ArrayList<>();
try {
List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(context, xmlId,
FLAG_NEED_KEY | FLAG_INCLUDE_PREF_SCREEN);
for (Bundle bundle : metadata) {
final String key = bundle.getString(METADATA_KEY);
if (!TextUtils.isEmpty(key)) {
keys.add(key);
}
}
} catch (java.io.IOException | XmlPullParserException e) {
return null;
}
return keys;
}
}

View File

@@ -0,0 +1,63 @@
/*
* 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.users;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class MultiUserTopIntroPreferenceControllerTest {
private Context mContext;
private MultiUserTopIntroPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new MultiUserTopIntroPreferenceController(mContext, "top_info");
}
@Ignore
@Test
public void getAvailabilityStatus_multiUserOff_shouldReturnEnabled() {
mController.mUserCaps.mEnabled = true;
mController.mUserCaps.mUserSwitcherEnabled = false;
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Ignore
@Test
public void getAvailabilityStatus_multiUserOn_shouldReturnDisabled() {
mController.mUserCaps.mEnabled = true;
mController.mUserCaps.mUserSwitcherEnabled = true;
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER);
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.utils;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class LocalClassLoaderContextThemeWrapperTest {
private LocalClassLoaderContextThemeWrapper mContextThemeWrapper;
@Test
public void getClassLoader_shouldUseLocalClassLoader() {
final Context context = ApplicationProvider.getApplicationContext();
final Class clazz = LocalClassLoaderContextThemeWrapperTest.class;
mContextThemeWrapper = new LocalClassLoaderContextThemeWrapper(clazz, context, 0);
assertThat(mContextThemeWrapper.getClassLoader()).isSameInstanceAs(clazz.getClassLoader());
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.vpn2;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.net.ConnectivityManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public final class VpnUtilsTest {
@Test
public void testIsAlwaysOnVpnSet() {
final ConnectivityManager cm = mock(ConnectivityManager.class);
when(cm.getAlwaysOnVpnPackageForUser(0)).thenReturn("com.example.vpn");
assertThat(VpnUtils.isAlwaysOnVpnSet(cm, 0)).isTrue();
when(cm.getAlwaysOnVpnPackageForUser(0)).thenReturn(null);
assertThat(VpnUtils.isAlwaysOnVpnSet(cm, 0)).isFalse();
}
}

View File

@@ -0,0 +1,51 @@
/*
* 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.widget;
import static org.junit.Assert.assertEquals;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class DefaultIndicatorSeekBarTest {
private DefaultIndicatorSeekBar mDefaultIndicatorSeekBar;
@Before
public void setUp() {
mDefaultIndicatorSeekBar = new DefaultIndicatorSeekBar(
ApplicationProvider.getApplicationContext());
mDefaultIndicatorSeekBar.setMax(100);
}
@After
public void tearDown() {
mDefaultIndicatorSeekBar = null;
}
@Test
public void defaultProgress_setSucceeds() {
mDefaultIndicatorSeekBar.setDefaultProgress(40);
assertEquals(40, mDefaultIndicatorSeekBar.getDefaultProgress());
}
}

View File

@@ -0,0 +1,34 @@
/*
* 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.widget;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class DonutViewTest {
@Test
public void getPercentageStringSpannable_doesntCrashForMissingPercentage() {
Context context = ApplicationProvider.getApplicationContext();
DonutView.getPercentageStringSpannable(context.getResources(), "50%", "h");
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.widget;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class PreferenceCategoryControllerTest {
private Context mContext;
private PreferenceCategoryController mController;
private List<AbstractPreferenceController> mChildren;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mChildren = new ArrayList<>();
mController = new PreferenceCategoryController(mContext, "pref_key").setChildren(mChildren);
}
@Test
public void isAvailable_noChildren_false() {
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_childrenAvailable_true() {
final AbstractPreferenceController child = mock(AbstractPreferenceController.class);
when(child.isAvailable()).thenReturn(true);
mChildren.add(child);
mController.setChildren(mChildren);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_childrenUnavailable_false() {
final AbstractPreferenceController child = mock(AbstractPreferenceController.class);
when(child.isAvailable()).thenReturn(false);
mChildren.add(child);
mController.setChildren(mChildren);
assertThat(mController.isAvailable()).isFalse();
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.widget;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import android.content.Context;
import android.view.View.MeasureSpec;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class RingProgressBarTest {
private Context mContext = ApplicationProvider.getApplicationContext();
private RingProgressBar mProgressBar;
@Before
public void setUp() {
mProgressBar = new RingProgressBar(mContext);
}
@Test
public void testMeasurePortrait() {
mProgressBar.measure(
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(200, MeasureSpec.EXACTLY));
assertEquals(100, mProgressBar.getMeasuredHeight());
assertEquals(100, mProgressBar.getMeasuredWidth());
}
@Test
public void testMeasureLandscape() {
mProgressBar.measure(
MeasureSpec.makeMeasureSpec(200, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY));
assertEquals(100, mProgressBar.getMeasuredHeight());
assertEquals(100, mProgressBar.getMeasuredWidth());
}
@Test
public void testDefaultAttributes() {
assertFalse(mProgressBar.isIndeterminate());
assertEquals(0, mProgressBar.getProgress());
assertEquals(10000, mProgressBar.getMax());
}
}

View File

@@ -0,0 +1,105 @@
/*
* 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.widget;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcelable;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.viewpager.widget.PagerAdapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Locale;
@RunWith(AndroidJUnit4.class)
public class RtlCompatibleViewPagerTest {
private Locale mLocaleEn;
private Locale mLocaleHe;
private RtlCompatibleViewPager mViewPager;
@Before
public void setUp() {
mViewPager = new RtlCompatibleViewPager(ApplicationProvider.getApplicationContext());
mViewPager.setAdapter(new ViewPagerAdapter());
mLocaleEn = new Locale("en");
mLocaleHe = new Locale("he");
}
@Test
public void testGetCurrentItem_shouldMaintainIndexDuringLocaleChange() {
testRtlCompatibleInner(0);
testRtlCompatibleInner(1);
}
private void testRtlCompatibleInner(int currentItem) {
// Set up the environment
Locale.setDefault(mLocaleEn);
mViewPager.setCurrentItem(currentItem);
assertThat(TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()))
.isEqualTo(View.LAYOUT_DIRECTION_LTR);
assertThat(mViewPager.getCurrentItem()).isEqualTo(currentItem);
// Simulate to change the language to RTL
Parcelable savedInstance = mViewPager.onSaveInstanceState();
Locale.setDefault(mLocaleHe);
mViewPager.onRestoreInstanceState(savedInstance);
assertThat(TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()))
.isEqualTo(View.LAYOUT_DIRECTION_RTL);
assertThat(mViewPager.getCurrentItem()).isEqualTo(currentItem);
}
/**
* Test viewpager adapter, uses 2 view to test it
*/
private static final class ViewPagerAdapter extends PagerAdapter {
private static final int ITEM_COUNT = 2;
private ViewPagerAdapter() {
}
@Override
public int getCount() {
return ITEM_COUNT;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
return null;
}
@Override
public CharSequence getPageTitle(int position) {
return null;
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.wifi;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.net.wifi.WifiConfiguration;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.wifitrackerlib.WifiEntry;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class WifiUtilsTest {
@Test
public void testSSID() {
assertThat(WifiUtils.isSSIDTooLong("123")).isFalse();
assertThat(WifiUtils.isSSIDTooLong("☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎")).isTrue();
assertThat(WifiUtils.isSSIDTooShort("123")).isFalse();
assertThat(WifiUtils.isSSIDTooShort("")).isTrue();
}
@Test
public void testPassword() {
final String longPassword = "123456789012345678901234567890"
+ "1234567890123456789012345678901234567890";
assertThat(WifiUtils.isHotspotWpa2PasswordValid("123")).isFalse();
assertThat(WifiUtils.isHotspotWpa2PasswordValid("12345678")).isTrue();
assertThat(WifiUtils.isHotspotWpa2PasswordValid("1234567890")).isTrue();
assertThat(WifiUtils.isHotspotWpa2PasswordValid(longPassword)).isFalse();
assertThat(WifiUtils.isHotspotWpa2PasswordValid("")).isFalse();
assertThat(WifiUtils.isHotspotWpa2PasswordValid("€¥£")).isFalse();
}
@Test
public void getWifiConfigByWifiEntry_shouldReturnCorrectConfig() {
final String testSSID = "WifiUtilsTest";
final WifiEntry wifiEntry = mock(WifiEntry.class);
when(wifiEntry.getSsid()).thenReturn(testSSID);
final WifiConfiguration config = WifiUtils.getWifiConfig(wifiEntry, null /* scanResult */);
assertThat(config).isNotNull();
assertThat(config.SSID).isEqualTo("\"" + testSSID + "\"");
}
@Test(expected = IllegalArgumentException.class)
public void getWifiConfigWithNullInput_ThrowIllegalArgumentException() {
WifiConfiguration config = WifiUtils.getWifiConfig(null /* wifiEntry */,
null /* scanResult */);
}
}

Some files were not shown because too many files have changed in this diff Show More