Merge "Merge sc-dev-plus-aosp-without-vendor@7634622" into stage-aosp-master
This commit is contained in:
73
tests/unit/src/com/android/settings/LinkifyUtilsTest.java
Normal file
73
tests/unit/src/com/android/settings/LinkifyUtilsTest.java
Normal 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();
|
||||
}
|
||||
}
|
||||
25
tests/unit/src/com/android/settings/TestUtils.java
Normal file
25
tests/unit/src/com/android/settings/TestUtils.java
Normal 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;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.android.settings.UserCredentialsSettings.Credential;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Process;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
/**
|
||||
* User credentials settings fragment tests
|
||||
*
|
||||
* To run the test, use command:
|
||||
* adb shell am instrument -e class com.android.settings.UserCredentialsTest
|
||||
* -w com.android.settings.tests.unit/androidx.test.runner.AndroidJUnitRunner
|
||||
*
|
||||
*/
|
||||
public class UserCredentialsTest extends InstrumentationTestCase {
|
||||
private static final String TAG = "UserCredentialsTests";
|
||||
|
||||
@SmallTest
|
||||
public void testCredentialIsParcelable() {
|
||||
final String alias = "credential-test-alias";
|
||||
Credential c = new Credential(alias, Process.SYSTEM_UID);
|
||||
|
||||
c.storedTypes.add(Credential.Type.CA_CERTIFICATE);
|
||||
c.storedTypes.add(Credential.Type.USER_KEY);
|
||||
|
||||
Parcel p = Parcel.obtain();
|
||||
c.writeToParcel(p, /* flags */ 0);
|
||||
p.setDataPosition(0);
|
||||
|
||||
Credential r = Credential.CREATOR.createFromParcel(p);
|
||||
assertEquals(c.alias, r.alias);
|
||||
assertEquals(c.uid, r.uid);
|
||||
assertEquals(c.storedTypes, r.storedTypes);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class UtilsTest extends AndroidTestCase {
|
||||
private static final int TEST_PRIMARY_USER_ID = 10;
|
||||
private static final int TEST_MANAGED_PROFILE_ID = 11;
|
||||
|
||||
@Mock private UserManager mUserManager;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
// // this is necessary for mockito to work
|
||||
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
|
||||
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mUserManager.getUserHandle()).thenReturn(TEST_PRIMARY_USER_ID);
|
||||
UserInfo primaryUser = new UserInfo(TEST_PRIMARY_USER_ID, null,
|
||||
UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_PRIMARY);
|
||||
when(mUserManager.getUserInfo(TEST_PRIMARY_USER_ID)).thenReturn(primaryUser);
|
||||
UserInfo managedProfile = new UserInfo(TEST_MANAGED_PROFILE_ID, null,
|
||||
UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
|
||||
when(mUserManager.getUserInfo(eq(TEST_MANAGED_PROFILE_ID))).thenReturn(managedProfile);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testGetManagedProfile() {
|
||||
UserHandle[] userHandles = new UserHandle[] {
|
||||
new UserHandle(TEST_PRIMARY_USER_ID),
|
||||
new UserHandle(TEST_MANAGED_PROFILE_ID)
|
||||
};
|
||||
when(mUserManager.getUserProfiles())
|
||||
.thenReturn(new ArrayList<UserHandle>(Arrays.asList(userHandles)));
|
||||
assertEquals(TEST_MANAGED_PROFILE_ID,
|
||||
Utils.getManagedProfile(mUserManager).getIdentifier());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testGetManagedProfile_notPresent() {
|
||||
UserHandle[] userHandles = new UserHandle[] {
|
||||
new UserHandle(TEST_PRIMARY_USER_ID)
|
||||
};
|
||||
when(mUserManager.getUserProfiles())
|
||||
.thenReturn(new ArrayList<UserHandle>(Arrays.asList(userHandles)));
|
||||
assertNull(Utils.getManagedProfile(mUserManager));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ReduceBrightColorsIntensityPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private Resources mResources;
|
||||
private ReduceBrightColorsIntensityPreferenceController mPreferenceController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mResources = spy(mContext.getResources());
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
mPreferenceController = new ReduceBrightColorsIntensityPreferenceController(mContext,
|
||||
"rbc_intensity");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_configuredRbcAvailable_enabledRbc_shouldReturnTrue() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
|
||||
doReturn(true).when(mResources).getBoolean(
|
||||
R.bool.config_reduceBrightColorsAvailable);
|
||||
assertThat(mPreferenceController.isAvailable()).isTrue();
|
||||
}
|
||||
@Test
|
||||
public void isAvailable_configuredRbcAvailable_disabledRbc_shouldReturnTrue() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 0);
|
||||
doReturn(true).when(mResources).getBoolean(
|
||||
R.bool.config_reduceBrightColorsAvailable);
|
||||
assertThat(mPreferenceController.isAvailable()).isTrue();
|
||||
}
|
||||
@Test
|
||||
public void isAvailable_configuredRbcUnavailable_enabledRbc_shouldReturnFalse() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
|
||||
doReturn(false).when(mResources).getBoolean(
|
||||
R.bool.config_reduceBrightColorsAvailable);
|
||||
assertThat(mPreferenceController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_changesTemperature() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
|
||||
mPreferenceController.onPreferenceChange(/* preference= */ null, 20);
|
||||
assertThat(
|
||||
Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0))
|
||||
.isEqualTo(80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rangeOfSlider_staysWithinValidRange() {
|
||||
when(mResources.getInteger(
|
||||
R.integer.config_reduceBrightColorsStrengthMax)).thenReturn(90);
|
||||
when(mResources.getInteger(
|
||||
R.integer.config_reduceBrightColorsStrengthMin)).thenReturn(15);
|
||||
assertThat(mPreferenceController.getMax()).isEqualTo(85);
|
||||
assertThat(mPreferenceController.getMin()).isEqualTo(10);
|
||||
assertThat(mPreferenceController.getMax() - mPreferenceController.getMin())
|
||||
.isEqualTo(75);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ReduceBrightColorsPreferenceControllerTest {
|
||||
private static final String PREF_KEY = "rbc_preference";
|
||||
|
||||
private Context mContext;
|
||||
private Resources mResources;;
|
||||
private ReduceBrightColorsPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mResources = spy(mContext.getResources());
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
mController = new ReduceBrightColorsPreferenceController(mContext,
|
||||
PREF_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_returnSummary() {
|
||||
assertThat(mController.getSummary().toString().contains(
|
||||
resourceString("reduce_bright_colors_preference_summary"))).isTrue();
|
||||
}
|
||||
|
||||
@Ignore("ColorDisplayManager runs in a different thread which results in a race condition")
|
||||
@Test
|
||||
public void isChecked_reduceBrightColorsIsActivated_returnTrue() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Ignore("ColorDisplayManager runs in a different thread which results in a race condition")
|
||||
@Test
|
||||
public void isChecked_reduceBrightColorsIsNotActivated_returnFalse() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 0);
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_configuredRbcAvailable_shouldReturnTrue() {
|
||||
doReturn(true).when(mResources).getBoolean(
|
||||
R.bool.config_reduceBrightColorsAvailable);
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
@Test
|
||||
public void isAvailable_configuredRbcUnAvailable_shouldReturnFalse() {
|
||||
doReturn(false).when(mResources).getBoolean(
|
||||
R.bool.config_reduceBrightColorsAvailable);
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
private int resourceId(String type, String name) {
|
||||
return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
|
||||
}
|
||||
|
||||
private String resourceString(String name) {
|
||||
return mContext.getResources().getString(resourceId("string", name));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.Settings.AccessibilitySettingsActivity;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ToggleFeaturePreferenceFragmentTest {
|
||||
private static final String SUMMARY_TEXT = "Here's some summary text";
|
||||
|
||||
@Rule
|
||||
public final ActivityTestRule<AccessibilitySettingsActivity> mActivityRule =
|
||||
new ActivityTestRule<>(AccessibilitySettingsActivity.class, true);
|
||||
|
||||
private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
|
||||
@BeforeClass
|
||||
public static void oneTimeSetup() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mInstrumentation.runOnMainSync(() -> {
|
||||
MyToggleFeaturePreferenceFragment fragment = new MyToggleFeaturePreferenceFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(AccessibilitySettings.EXTRA_SUMMARY, SUMMARY_TEXT);
|
||||
fragment.setArguments(args);
|
||||
new SubSettingLauncher(mActivityRule.getActivity())
|
||||
.setDestination(MyToggleFeaturePreferenceFragment.class.getName())
|
||||
.setArguments(args)
|
||||
.setSourceMetricsCategory(
|
||||
InstrumentedPreferenceFragment.METRICS_CATEGORY_UNKNOWN)
|
||||
.launch();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSummaryTestDisplayed() {
|
||||
onView(withText(SUMMARY_TEXT)).check(matches(isDisplayed()));
|
||||
}
|
||||
|
||||
public static class MyToggleFeaturePreferenceFragment extends ToggleFeaturePreferenceFragment {
|
||||
@Override
|
||||
protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
int getUserShortcutTypes() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.accounts.AccountManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject;
|
||||
import android.support.test.uiautomator.UiObjectNotFoundException;
|
||||
import android.support.test.uiautomator.UiScrollable;
|
||||
import android.support.test.uiautomator.UiSelector;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class AccountsSettingsTest {
|
||||
|
||||
private static final String ACCOUNTS = "Accounts";
|
||||
private static final String ACCOUNT_TYPE = "com.settingstest.account-prefs";
|
||||
private static final String PREF_TITLE = "Test preference for external account";
|
||||
|
||||
private UiDevice mDevice;
|
||||
private Context mContext;
|
||||
private String mTargetPackage;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
mTargetPackage = mContext.getPackageName();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExternalAccountInfoExists() throws UiObjectNotFoundException {
|
||||
// add a test account
|
||||
final String testAccountName = "Test Account";
|
||||
final Account account = new Account(testAccountName, ACCOUNT_TYPE);
|
||||
final AccountManager accountManager = AccountManager.get(mContext);
|
||||
final boolean accountAdded =
|
||||
accountManager.addAccountExplicitly(account, null /* password */, null /* userdata */);
|
||||
assertThat(accountAdded).isTrue();
|
||||
|
||||
// launch Accounts Settings and select the test account
|
||||
launchAccountsSettings();
|
||||
mDevice.findObject(new UiSelector().text(testAccountName)).click();
|
||||
final UiObject testPreference = mDevice.findObject(new UiSelector().text(PREF_TITLE));
|
||||
// remove test account
|
||||
accountManager.removeAccountExplicitly(account);
|
||||
|
||||
assertThat(testPreference.exists()).isTrue();
|
||||
}
|
||||
|
||||
private void launchAccountsSettings() throws UiObjectNotFoundException {
|
||||
// launch settings
|
||||
Intent settingsIntent = new Intent(Intent.ACTION_MAIN)
|
||||
.addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
.setPackage(mTargetPackage)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mContext.startActivity(settingsIntent);
|
||||
// selects Accounts
|
||||
final UiScrollable settings = new UiScrollable(
|
||||
new UiSelector().packageName(mTargetPackage).scrollable(true));
|
||||
final String titleAccounts = ACCOUNTS;
|
||||
settings.scrollTextIntoView(titleAccounts);
|
||||
mDevice.findObject(new UiSelector().text(titleAccounts)).click();
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 android.accounts.AbstractAccountAuthenticator;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountAuthenticatorResponse;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.NetworkErrorException;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class Authenticator extends AbstractAccountAuthenticator {
|
||||
|
||||
public Authenticator(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle editProperties(AccountAuthenticatorResponse r, String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle addAccount(AccountAuthenticatorResponse r, String s, String s2, String[] strings,
|
||||
Bundle bundle) throws NetworkErrorException {
|
||||
final Bundle result = new Bundle();
|
||||
result.putString(AccountManager.KEY_ACCOUNT_NAME, "Test Account");
|
||||
result.putString(AccountManager.KEY_ACCOUNT_TYPE, s);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle confirmCredentials(AccountAuthenticatorResponse r, Account account, Bundle bundle)
|
||||
throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getAuthToken(AccountAuthenticatorResponse r, Account account, String s,
|
||||
Bundle bundle) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthTokenLabel(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle updateCredentials(AccountAuthenticatorResponse r, Account account, String s,
|
||||
Bundle bundle) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle hasFeatures(AccountAuthenticatorResponse r, Account account, String[] strings)
|
||||
throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* 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.
|
||||
@@ -14,23 +14,24 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.applications;
|
||||
package com.android.settings.accounts;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.provider.Settings;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@LargeTest
|
||||
public class DrawOverlaySettingsTest extends AppOpsSettingsTest {
|
||||
public class RemoveUserFragmentTest {
|
||||
|
||||
public DrawOverlaySettingsTest() {
|
||||
super(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, AppOpsManager.OP_SYSTEM_ALERT_WINDOW);
|
||||
@Test
|
||||
public void testClassModifier_shouldBePublic() {
|
||||
final int modifiers = RemoveUserFragment.class.getModifiers();
|
||||
|
||||
assertThat(Modifier.isPublic(modifiers)).isTrue();
|
||||
}
|
||||
|
||||
// Test cases are in the superclass.
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_DEFAULT;
|
||||
import static android.app.AppOpsManager.MODE_ERRORED;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.BySelector;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An abstract parent for testing settings activities that manage an AppOps permission.
|
||||
*/
|
||||
abstract public class AppOpsSettingsTest {
|
||||
private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
|
||||
private static final long START_ACTIVITY_TIMEOUT = 5000;
|
||||
|
||||
private Context mContext;
|
||||
private UiDevice mUiDevice;
|
||||
private PackageManager mPackageManager;
|
||||
private AppOpsManager mAppOpsManager;
|
||||
private List<UserInfo> mProfiles;
|
||||
private String mPackageName;
|
||||
|
||||
// These depend on which app op's settings UI is being tested.
|
||||
private final String mActivityAction;
|
||||
private final int mAppOpCode;
|
||||
|
||||
protected AppOpsSettingsTest(String activityAction, int appOpCode) {
|
||||
mActivityAction = activityAction;
|
||||
mAppOpCode = appOpCode;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
mPackageName = InstrumentationRegistry.getContext().getPackageName();
|
||||
mPackageManager = mContext.getPackageManager();
|
||||
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
|
||||
mProfiles = mContext.getSystemService(UserManager.class).getProfiles(UserHandle.myUserId());
|
||||
resetAppOpModeForAllProfiles();
|
||||
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
mUiDevice.wakeUp();
|
||||
mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
|
||||
}
|
||||
|
||||
private void resetAppOpModeForAllProfiles() throws Exception {
|
||||
for (UserInfo user : mProfiles) {
|
||||
final int uid = mPackageManager.getPackageUidAsUser(mPackageName, user.id);
|
||||
mAppOpsManager.setMode(mAppOpCode, uid, mPackageName, MODE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an intent for showing the permission settings for all apps.
|
||||
*/
|
||||
private Intent createManageAllAppsIntent() {
|
||||
final Intent intent = new Intent(mActivityAction);
|
||||
intent.addFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
|
||||
return intent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an intent for showing the permission setting for a single app.
|
||||
*/
|
||||
private Intent createManageSingleAppIntent(String packageName) {
|
||||
final Intent intent = createManageAllAppsIntent();
|
||||
intent.setData(Uri.parse("package:" + packageName));
|
||||
return intent;
|
||||
}
|
||||
|
||||
private String getApplicationLabel(String packageName) throws Exception {
|
||||
final ApplicationInfo info = mPackageManager.getApplicationInfo(packageName, 0);
|
||||
return mPackageManager.getApplicationLabel(info).toString();
|
||||
}
|
||||
|
||||
private UiObject2 findAndVerifySwitchState(boolean checked) {
|
||||
final BySelector switchSelector = By.clazz(Switch.class).res("android:id/switch_widget");
|
||||
final UiObject2 switchPref = mUiDevice.wait(Until.findObject(switchSelector),
|
||||
START_ACTIVITY_TIMEOUT);
|
||||
assertNotNull("Switch not shown", switchPref);
|
||||
assertTrue("Switch in invalid state", switchPref.isChecked() == checked);
|
||||
return switchPref;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppList() throws Exception {
|
||||
final String testAppLabel = getApplicationLabel(mPackageName);
|
||||
|
||||
mContext.startActivity(createManageAllAppsIntent());
|
||||
final BySelector preferenceListSelector =
|
||||
By.clazz(RecyclerView.class).res("com.android.settings:id/apps_list");
|
||||
final UiObject2 preferenceList = mUiDevice.wait(Until.findObject(preferenceListSelector),
|
||||
START_ACTIVITY_TIMEOUT);
|
||||
assertNotNull("App list not shown", preferenceList);
|
||||
|
||||
final BySelector appLabelTextViewSelector = By.clazz(TextView.class)
|
||||
.res("android:id/title")
|
||||
.text(testAppLabel);
|
||||
List<UiObject2> listOfMatchingTextViews;
|
||||
do {
|
||||
listOfMatchingTextViews = preferenceList.findObjects(appLabelTextViewSelector);
|
||||
// assuming the number of profiles will be sufficiently small so that all the entries
|
||||
// for the same package will fit in one screen at some time during the scroll.
|
||||
} while (listOfMatchingTextViews.size() != mProfiles.size() &&
|
||||
preferenceList.scroll(Direction.DOWN, 0.2f));
|
||||
assertEquals("Test app not listed for each profile", mProfiles.size(),
|
||||
listOfMatchingTextViews.size());
|
||||
|
||||
for (UiObject2 matchingObject : listOfMatchingTextViews) {
|
||||
matchingObject.click();
|
||||
findAndVerifySwitchState(true);
|
||||
mUiDevice.pressBack();
|
||||
}
|
||||
}
|
||||
|
||||
private void testAppDetailScreenForAppOp(int appOpMode, int userId) throws Exception {
|
||||
final String testAppLabel = getApplicationLabel(mPackageName);
|
||||
final BySelector appDetailTitleSelector = By.clazz(TextView.class)
|
||||
.res("com.android.settings:id/app_detail_title")
|
||||
.text(testAppLabel);
|
||||
|
||||
mAppOpsManager.setMode(mAppOpCode,
|
||||
mPackageManager.getPackageUidAsUser(mPackageName, userId), mPackageName, appOpMode);
|
||||
mContext.startActivityAsUser(createManageSingleAppIntent(mPackageName),
|
||||
UserHandle.of(userId));
|
||||
mUiDevice.wait(Until.findObject(appDetailTitleSelector), START_ACTIVITY_TIMEOUT);
|
||||
findAndVerifySwitchState(appOpMode == MODE_ALLOWED || appOpMode == MODE_DEFAULT);
|
||||
mUiDevice.pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleApp() throws Exception {
|
||||
// App op MODE_DEFAULT is already tested in #testAppList
|
||||
for (UserInfo user : mProfiles) {
|
||||
testAppDetailScreenForAppOp(MODE_ALLOWED, user.id);
|
||||
testAppDetailScreenForAppOp(MODE_ERRORED, user.id);
|
||||
}
|
||||
}
|
||||
|
||||
private void testSwitchToggle(int fromAppOp, int toAppOp) throws Exception {
|
||||
final int packageUid = mPackageManager.getPackageUid(mPackageName, 0);
|
||||
final boolean initialState = (fromAppOp == MODE_ALLOWED || fromAppOp == MODE_DEFAULT);
|
||||
|
||||
mAppOpsManager.setMode(mAppOpCode, packageUid, mPackageName, fromAppOp);
|
||||
mContext.startActivity(createManageSingleAppIntent(mPackageName));
|
||||
final UiObject2 switchPref = findAndVerifySwitchState(initialState);
|
||||
switchPref.click();
|
||||
Thread.sleep(1000);
|
||||
assertEquals("Toggling switch did not change app op", toAppOp,
|
||||
mAppOpsManager.checkOpNoThrow(mAppOpCode, packageUid,
|
||||
mPackageName));
|
||||
mUiDevice.pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIfSwitchTogglesAppOp() throws Exception {
|
||||
testSwitchToggle(MODE_ALLOWED, MODE_ERRORED);
|
||||
testSwitchToggle(MODE_ERRORED, MODE_ALLOWED);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
mUiDevice.pressHome();
|
||||
resetAppOpModeForAllProfiles();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 static org.mockito.Mockito.doReturn;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AppStateAlarmsAndRemindersBridgeTest {
|
||||
private static final String TEST_PACKAGE_1 = "com.example.test.1";
|
||||
private static final String TEST_PACKAGE_2 = "com.example.test.2";
|
||||
private static final int UID_1 = 12345;
|
||||
private static final int UID_2 = 7654321;
|
||||
|
||||
@Mock
|
||||
private AlarmManager mAlarmManager;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void initMocks() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeVisible_permissionRequestedIsTrue_isTrue() {
|
||||
assertThat(new AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState(
|
||||
true /* permissionRequested */,
|
||||
true /* permissionGranted */)
|
||||
.shouldBeVisible()).isTrue();
|
||||
assertThat(new AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState(
|
||||
true /* permissionRequested */,
|
||||
false /* permissionGranted */)
|
||||
.shouldBeVisible()).isTrue();
|
||||
assertThat(new AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState(
|
||||
false /* permissionRequested */,
|
||||
true /* permissionGranted */)
|
||||
.shouldBeVisible()).isFalse();
|
||||
assertThat(new AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState(
|
||||
false /* permissionRequested */,
|
||||
false /* permissionGranted */)
|
||||
.shouldBeVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAllowed_permissionGrantedIsTrue_isTrue() {
|
||||
assertThat(new AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState(
|
||||
true /* permissionRequested */,
|
||||
true /* permissionGranted */)
|
||||
.isAllowed()).isTrue();
|
||||
assertThat(new AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState(
|
||||
true /* permissionRequested */,
|
||||
false /* permissionGranted */)
|
||||
.isAllowed()).isFalse();
|
||||
assertThat(new AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState(
|
||||
false /* permissionRequested */,
|
||||
true /* permissionGranted */)
|
||||
.isAllowed()).isTrue();
|
||||
assertThat(new AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState(
|
||||
false /* permissionRequested */,
|
||||
false /* permissionGranted */)
|
||||
.isAllowed()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPermissionState() {
|
||||
AppStateAlarmsAndRemindersBridge bridge = new AppStateAlarmsAndRemindersBridge(mContext,
|
||||
null, null);
|
||||
bridge.mAlarmManager = mAlarmManager;
|
||||
bridge.mRequesterPackages = new String[]{TEST_PACKAGE_1, "some.other.package"};
|
||||
|
||||
doReturn(false).when(mAlarmManager).hasScheduleExactAlarm(TEST_PACKAGE_1,
|
||||
UserHandle.getUserId(UID_1));
|
||||
doReturn(true).when(mAlarmManager).hasScheduleExactAlarm(TEST_PACKAGE_2,
|
||||
UserHandle.getUserId(UID_2));
|
||||
|
||||
AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState state1 =
|
||||
bridge.createPermissionState(TEST_PACKAGE_1, UID_1);
|
||||
assertThat(state1.shouldBeVisible()).isTrue();
|
||||
assertThat(state1.isAllowed()).isFalse();
|
||||
|
||||
AppStateAlarmsAndRemindersBridge.AlarmsAndRemindersState state2 =
|
||||
bridge.createPermissionState(TEST_PACKAGE_2, UID_2);
|
||||
assertThat(state2.shouldBeVisible()).isFalse();
|
||||
assertThat(state2.isAllowed()).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION;
|
||||
|
||||
import static com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.apphibernation.AppHibernationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
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;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class HibernatedAppsPreferenceControllerTest {
|
||||
|
||||
public static final String HIBERNATED_PACKAGE_NAME = "hibernated_package";
|
||||
public static final String AUTO_REVOKED_PACKAGE_NAME = "auto_revoked_package";
|
||||
public static final String PERMISSION = "permission";
|
||||
@Mock
|
||||
PackageManager mPackageManager;
|
||||
@Mock
|
||||
AppHibernationManager mAppHibernationManager;
|
||||
@Mock
|
||||
IUsageStatsManager mIUsageStatsManager;
|
||||
PreferenceScreen mPreferenceScreen;
|
||||
private static final String KEY = "key";
|
||||
private Context mContext;
|
||||
private HibernatedAppsPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
MockitoAnnotations.initMocks(this);
|
||||
DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
|
||||
"true", false);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mContext.getSystemService(AppHibernationManager.class))
|
||||
.thenReturn(mAppHibernationManager);
|
||||
when(mContext.getSystemService(UsageStatsManager.class)).thenReturn(
|
||||
new UsageStatsManager(mContext, mIUsageStatsManager));
|
||||
|
||||
PreferenceManager manager = new PreferenceManager(mContext);
|
||||
mPreferenceScreen = manager.createPreferenceScreen(mContext);
|
||||
Preference preference = mock(Preference.class);
|
||||
when(preference.getKey()).thenReturn(KEY);
|
||||
mPreferenceScreen.addPreference(preference);
|
||||
|
||||
mController = new HibernatedAppsPreferenceController(mContext, KEY,
|
||||
command -> command.run(), command -> command.run());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_featureDisabled_shouldNotReturnAvailable() {
|
||||
DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
|
||||
"false", true);
|
||||
|
||||
assertThat((mController).getAvailabilityStatus()).isNotEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_getsRightCountForHibernatedPackage() {
|
||||
final PackageInfo hibernatedPkg = getHibernatedPackage();
|
||||
when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(
|
||||
Arrays.asList(hibernatedPkg, new PackageInfo()));
|
||||
when(mContext.getResources()).thenReturn(mock(Resources.class));
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onResume();
|
||||
|
||||
verify(mContext.getResources()).getQuantityString(anyInt(), eq(1), eq(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_getsRightCountForUnusedAutoRevokedPackage() {
|
||||
final PackageInfo autoRevokedPkg = getAutoRevokedPackage();
|
||||
when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(
|
||||
Arrays.asList(autoRevokedPkg, new PackageInfo()));
|
||||
when(mContext.getResources()).thenReturn(mock(Resources.class));
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onResume();
|
||||
|
||||
verify(mContext.getResources()).getQuantityString(anyInt(), eq(1), eq(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_getsRightCountForUsedAutoRevokedPackage() {
|
||||
final PackageInfo usedAutoRevokedPkg = getAutoRevokedPackage();
|
||||
setAutoRevokedPackageUsageStats();
|
||||
when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(
|
||||
Arrays.asList(usedAutoRevokedPkg, new PackageInfo()));
|
||||
when(mContext.getResources()).thenReturn(mock(Resources.class));
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onResume();
|
||||
|
||||
verify(mContext.getResources()).getQuantityString(anyInt(), eq(0), eq(0));
|
||||
}
|
||||
|
||||
private PackageInfo getHibernatedPackage() {
|
||||
final PackageInfo pi = new PackageInfo();
|
||||
pi.packageName = HIBERNATED_PACKAGE_NAME;
|
||||
pi.requestedPermissions = new String[] {PERMISSION};
|
||||
when(mAppHibernationManager.getHibernatingPackagesForUser())
|
||||
.thenReturn(Arrays.asList(pi.packageName));
|
||||
when(mPackageManager.getPermissionFlags(
|
||||
pi.requestedPermissions[0], pi.packageName, mContext.getUser()))
|
||||
.thenReturn(PackageManager.FLAG_PERMISSION_AUTO_REVOKED);
|
||||
return pi;
|
||||
}
|
||||
|
||||
private PackageInfo getAutoRevokedPackage() {
|
||||
final PackageInfo pi = new PackageInfo();
|
||||
pi.packageName = AUTO_REVOKED_PACKAGE_NAME;
|
||||
pi.requestedPermissions = new String[] {PERMISSION};
|
||||
when(mPackageManager.getPermissionFlags(
|
||||
pi.requestedPermissions[0], pi.packageName, mContext.getUser()))
|
||||
.thenReturn(PackageManager.FLAG_PERMISSION_AUTO_REVOKED);
|
||||
return pi;
|
||||
}
|
||||
|
||||
private void setAutoRevokedPackageUsageStats() {
|
||||
final UsageStats us = new UsageStats();
|
||||
us.mPackageName = AUTO_REVOKED_PACKAGE_NAME;
|
||||
us.mLastTimeVisible = System.currentTimeMillis();
|
||||
try {
|
||||
when(mIUsageStatsManager.queryUsageStats(
|
||||
anyInt(), anyLong(), anyLong(), anyString(), anyInt()))
|
||||
.thenReturn(new ParceledListSlice(Arrays.asList(us)));
|
||||
} catch (RemoteException e) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.appinfo;
|
||||
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_DEFAULT;
|
||||
import static android.app.AppOpsManager.MODE_IGNORED;
|
||||
import static android.app.AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED;
|
||||
import static android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION;
|
||||
|
||||
import static com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED;
|
||||
import static com.android.settings.Utils.PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
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;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class HibernationSwitchPreferenceControllerTest {
|
||||
private static final int PACKAGE_UID = 1;
|
||||
private static final String INVALID_PACKAGE_NAME = "invalid_package";
|
||||
private static final String KEY = "key";
|
||||
private static final String VALID_PACKAGE_NAME = "package";
|
||||
private static final String EXEMPTED_PACKAGE_NAME = "exempted_package";
|
||||
private static final String UNEXEMPTED_PACKAGE_NAME = "unexempted_package";
|
||||
@Mock
|
||||
private AppOpsManager mAppOpsManager;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private SwitchPreference mPreference;
|
||||
|
||||
private HibernationSwitchPreferenceController mController;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws PackageManager.NameNotFoundException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
|
||||
when(mPackageManager.getPackageUid(eq(VALID_PACKAGE_NAME), anyInt()))
|
||||
.thenReturn(PACKAGE_UID);
|
||||
when(mPackageManager.getPackageUid(eq(INVALID_PACKAGE_NAME), anyInt()))
|
||||
.thenThrow(new PackageManager.NameNotFoundException());
|
||||
when(mPackageManager.getTargetSdkVersion(eq(EXEMPTED_PACKAGE_NAME)))
|
||||
.thenReturn(android.os.Build.VERSION_CODES.Q);
|
||||
when(mPackageManager.getTargetSdkVersion(eq(UNEXEMPTED_PACKAGE_NAME)))
|
||||
.thenReturn(android.os.Build.VERSION_CODES.S);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
|
||||
"true", true /* makeDefault */);
|
||||
mController = new HibernationSwitchPreferenceController(mContext, KEY);
|
||||
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_featureNotEnabled_shouldNotReturnAvailable() {
|
||||
mController.setPackage(VALID_PACKAGE_NAME);
|
||||
DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
|
||||
"false", true /* makeDefault */);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isNotEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_invalidPackage_shouldReturnNotAvailable() {
|
||||
mController.setPackage(INVALID_PACKAGE_NAME);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isNotEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_validPackage_shouldReturnAvailable() {
|
||||
mController.setPackage(VALID_PACKAGE_NAME);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_exemptedByDefaultPackage_shouldNotCheck() {
|
||||
when(mAppOpsManager.unsafeCheckOpNoThrow(
|
||||
eq(OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED), anyInt(), eq(EXEMPTED_PACKAGE_NAME)))
|
||||
.thenReturn(MODE_DEFAULT);
|
||||
mController.setPackage(EXEMPTED_PACKAGE_NAME);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_exemptedPackageOverrideByUser_shouldCheck() {
|
||||
when(mAppOpsManager.unsafeCheckOpNoThrow(
|
||||
eq(OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED), anyInt(), eq(EXEMPTED_PACKAGE_NAME)))
|
||||
.thenReturn(MODE_ALLOWED);
|
||||
mController.setPackage(EXEMPTED_PACKAGE_NAME);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_unexemptedPackageOverrideByUser_shouldNotCheck() {
|
||||
when(mAppOpsManager.unsafeCheckOpNoThrow(
|
||||
eq(OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED), anyInt(), eq(UNEXEMPTED_PACKAGE_NAME)))
|
||||
.thenReturn(MODE_IGNORED);
|
||||
mController.setPackage(UNEXEMPTED_PACKAGE_NAME);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_exemptedByDefaultPackageOverriddenByPreSFlag_shouldCheck() {
|
||||
DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS,
|
||||
"true", true /* makeDefault */);
|
||||
when(mAppOpsManager.unsafeCheckOpNoThrow(
|
||||
eq(OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED), anyInt(), eq(EXEMPTED_PACKAGE_NAME)))
|
||||
.thenReturn(MODE_DEFAULT);
|
||||
mController.setPackage(EXEMPTED_PACKAGE_NAME);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* 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.
|
||||
@@ -14,24 +14,32 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.applications;
|
||||
package com.android.settings.applications.assist;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.provider.Settings;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@LargeTest
|
||||
public class ExternalSourcesSettingsTest extends AppOpsSettingsTest {
|
||||
public class AssistSettingObserverTest {
|
||||
|
||||
public ExternalSourcesSettingsTest() {
|
||||
super(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
|
||||
AppOpsManager.OP_REQUEST_INSTALL_PACKAGES);
|
||||
@Test
|
||||
public void callConstructor_shouldNotCrash() {
|
||||
new AssistSettingObserver() {
|
||||
@Override
|
||||
protected List<Uri> getSettingUris() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingChange() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Test cases are in the superclass.
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.autofill;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Looper;
|
||||
import android.os.UserHandle;
|
||||
import android.service.autofill.AutofillServiceInfo;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class PasswordsPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private PreferenceScreen mScreen;
|
||||
private PreferenceCategory mPasswordsPreferenceCategory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare(); // needed to create the preference screen
|
||||
}
|
||||
mScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
|
||||
mPasswordsPreferenceCategory = new PreferenceCategory(mContext);
|
||||
mPasswordsPreferenceCategory.setKey("passwords");
|
||||
mScreen.addPreference(mPasswordsPreferenceCategory);
|
||||
}
|
||||
|
||||
@Test
|
||||
// Tests that getAvailabilityStatus() does not throw an exception if it's called before the
|
||||
// Controller is initialized (this can happen during indexing).
|
||||
public void getAvailabilityStatus_withoutInit_returnsUnavailable() {
|
||||
PasswordsPreferenceController controller =
|
||||
new PasswordsPreferenceController(mContext, mPasswordsPreferenceCategory.getKey());
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_noServices_returnsUnavailable() {
|
||||
PasswordsPreferenceController controller =
|
||||
createControllerWithServices(Collections.emptyList());
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_noPasswords_returnsUnavailable() {
|
||||
AutofillServiceInfo service = new AutofillServiceInfo.TestDataBuilder().build();
|
||||
PasswordsPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(service));
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_withPasswords_returnsAvailable() {
|
||||
PasswordsPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(createServiceWithPasswords()));
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_noServices_noPreferencesAdded() {
|
||||
PasswordsPreferenceController controller =
|
||||
createControllerWithServices(Collections.emptyList());
|
||||
controller.displayPreference(mScreen);
|
||||
assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_noPasswords_noPreferencesAdded() {
|
||||
AutofillServiceInfo service = new AutofillServiceInfo.TestDataBuilder().build();
|
||||
PasswordsPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(service));
|
||||
controller.displayPreference(mScreen);
|
||||
assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void displayPreference_withPasswords_addsPreference() {
|
||||
AutofillServiceInfo service = createServiceWithPasswords();
|
||||
service.getServiceInfo().packageName = "";
|
||||
service.getServiceInfo().name = "";
|
||||
PasswordsPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(service));
|
||||
doReturn(false).when(mContext).bindServiceAsUser(any(), any(), anyInt(), any());
|
||||
|
||||
controller.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||
Preference pref = mPasswordsPreferenceCategory.getPreference(0);
|
||||
assertThat(pref.getIcon()).isNotNull();
|
||||
pref.performClick();
|
||||
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||
UserHandle user = mContext.getUser();
|
||||
verify(mContext).startActivityAsUser(intentCaptor.capture(), eq(user));
|
||||
assertThat(intentCaptor.getValue().getComponent())
|
||||
.isEqualTo(
|
||||
new ComponentName(
|
||||
service.getServiceInfo().packageName,
|
||||
service.getPasswordsActivity()));
|
||||
}
|
||||
|
||||
private PasswordsPreferenceController createControllerWithServices(
|
||||
List<AutofillServiceInfo> availableServices) {
|
||||
PasswordsPreferenceController controller =
|
||||
new PasswordsPreferenceController(mContext, mPasswordsPreferenceCategory.getKey());
|
||||
controller.init(() -> mock(Lifecycle.class), availableServices);
|
||||
return controller;
|
||||
}
|
||||
|
||||
private AutofillServiceInfo createServiceWithPasswords() {
|
||||
return new AutofillServiceInfo.TestDataBuilder()
|
||||
.setPasswordsActivity("com.android.test.Passwords")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -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.applications.manageapplications;
|
||||
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_ALARMS_AND_REMINDERS;
|
||||
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_MEDIA_MANAGEMENT;
|
||||
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_ALARMS_AND_REMINDERS;
|
||||
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_MEDIA_MANAGEMENT_APPS;
|
||||
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_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_ALARMS_AND_REMINDERS))
|
||||
.isEqualTo(FILTER_ALARMS_AND_REMINDERS);
|
||||
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_MEDIA_MANAGEMENT_APPS))
|
||||
.isEqualTo(FILTER_APPS_MEDIA_MANAGEMENT);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
||||
import com.android.settingslib.applications.ApplicationsState.CompoundFilter;
|
||||
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ManageApplicationsUnitTest {
|
||||
@Test
|
||||
public void getCompositeFilter_filtersVolumeForAudio() {
|
||||
AppFilter filter =
|
||||
ManageApplications.getCompositeFilter(
|
||||
ManageApplications.LIST_TYPE_STORAGE,
|
||||
ManageApplications.STORAGE_TYPE_MUSIC,
|
||||
"uuid");
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
info.volumeUuid = "uuid";
|
||||
info.category = ApplicationInfo.CATEGORY_AUDIO;
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
appEntry.info = info;
|
||||
|
||||
assertThat(filter.filterApp(appEntry)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCompositeFilter_filtersVolumeForVideo() {
|
||||
AppFilter filter =
|
||||
ManageApplications.getCompositeFilter(
|
||||
ManageApplications.LIST_TYPE_MOVIES,
|
||||
ManageApplications.STORAGE_TYPE_DEFAULT,
|
||||
"uuid");
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
info.volumeUuid = "uuid";
|
||||
info.category = ApplicationInfo.CATEGORY_VIDEO;
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
appEntry.info = info;
|
||||
|
||||
assertThat(filter.filterApp(appEntry)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCompositeFilter_filtersVolumeForGames() {
|
||||
ApplicationsState.AppFilter filter =
|
||||
ManageApplications.getCompositeFilter(
|
||||
ManageApplications.LIST_TYPE_GAMES,
|
||||
ManageApplications.STORAGE_TYPE_DEFAULT,
|
||||
"uuid");
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
info.volumeUuid = "uuid";
|
||||
info.category = ApplicationInfo.CATEGORY_GAME;
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
appEntry.info = info;
|
||||
|
||||
assertThat(filter.filterApp(appEntry)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCompositeFilter_isEmptyNormally() {
|
||||
ApplicationsState.AppFilter filter =
|
||||
ManageApplications.getCompositeFilter(
|
||||
ManageApplications.LIST_TYPE_MAIN,
|
||||
ManageApplications.STORAGE_TYPE_DEFAULT,
|
||||
"uuid");
|
||||
assertThat(filter).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCompositeFilter_worksWithInstantApps() throws Exception {
|
||||
Field field = AppUtils.class.getDeclaredField("sInstantAppDataProvider");
|
||||
field.setAccessible(true);
|
||||
field.set(AppUtils.class, (InstantAppDataProvider) (i -> true));
|
||||
|
||||
AppFilter filter =
|
||||
ManageApplications.getCompositeFilter(
|
||||
ManageApplications.LIST_TYPE_STORAGE,
|
||||
ManageApplications.STORAGE_TYPE_MUSIC,
|
||||
"uuid");
|
||||
AppFilter composedFilter = new CompoundFilter(ApplicationsState.FILTER_INSTANT, filter);
|
||||
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
info.volumeUuid = "uuid";
|
||||
info.category = ApplicationInfo.CATEGORY_AUDIO;
|
||||
info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
appEntry.info = info;
|
||||
|
||||
assertThat(composedFilter.filterApp(appEntry)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCompositeFilter_worksForLegacyPrivateSettings() throws Exception {
|
||||
ApplicationsState.AppFilter filter =
|
||||
ManageApplications.getCompositeFilter(
|
||||
ManageApplications.LIST_TYPE_STORAGE,
|
||||
ManageApplications.STORAGE_TYPE_LEGACY,
|
||||
"uuid");
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
info.volumeUuid = "uuid";
|
||||
info.category = ApplicationInfo.CATEGORY_GAME;
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
appEntry.info = info;
|
||||
|
||||
assertThat(filter.filterApp(appEntry)).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.specialaccess.notificationaccess;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ServiceInfo;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AlertingTypeFilterPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private AlertingTypeFilterPreferenceController mController;
|
||||
@Mock
|
||||
NotificationBackend mNm;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
ServiceInfo mSi = new ServiceInfo();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
mController = new AlertingTypeFilterPreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setServiceInfo(mSi);
|
||||
mController.setUserId(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getType() {
|
||||
assertThat(mController.getType()).isEqualTo(FLAG_FILTER_TYPE_ALERTING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.specialaccess.notificationaccess;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ApprovalPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
@Mock
|
||||
private NotificationAccessDetails mFragment;
|
||||
private ApprovalPreferenceController mController;
|
||||
@Mock
|
||||
NotificationManager mNm;
|
||||
@Mock
|
||||
PackageManager mPm;
|
||||
PackageInfo mPkgInfo;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
|
||||
mPkgInfo = new PackageInfo();
|
||||
mPkgInfo.applicationInfo = mock(ApplicationInfo.class);
|
||||
when(mPkgInfo.applicationInfo.loadLabel(mPm)).thenReturn("LABEL");
|
||||
|
||||
mController = new ApprovalPreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setParent(mFragment);
|
||||
mController.setPkgInfo(mPkgInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_checked() {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
SwitchPreference pref = new SwitchPreference(mContext);
|
||||
|
||||
mController.updateState(pref);
|
||||
assertThat(pref.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enable() {
|
||||
mController.enable(mCn);
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(
|
||||
mContext,
|
||||
MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW,
|
||||
"a");
|
||||
|
||||
verify(mNm).setNotificationListenerAccessGranted(mCn, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disable() {
|
||||
mController.disable(mCn);
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(
|
||||
mContext,
|
||||
MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW,
|
||||
"a");
|
||||
|
||||
verify(mNm).setNotificationListenerAccessGranted(mCn, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.specialaccess.notificationaccess;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.service.notification.NotificationListenerFilter;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class BridgedAppsLinkPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private BridgedAppsLinkPreferenceController mController;
|
||||
@Mock
|
||||
NotificationBackend mNm;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
mController = new BridgedAppsLinkPreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setUserId(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_notGranted() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(false);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.CUR_DEVELOPMENT + 1);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_lowTargetSdk_noCustomizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.S);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_lowTargetSdk_customizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.S);
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter();
|
||||
nlf.setTypes(FLAG_FILTER_TYPE_CONVERSATIONS);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_highTargetSdk_noCustomizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.CUR_DEVELOPMENT + 1);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.specialaccess.notificationaccess;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.VersionedPackage;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Looper;
|
||||
import android.service.notification.NotificationListenerFilter;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.preference.CheckBoxPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class BridgedAppsPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private BridgedAppsPreferenceController mController;
|
||||
@Mock
|
||||
NotificationBackend mNm;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
PreferenceScreen mScreen;
|
||||
@Mock
|
||||
ApplicationsState mAppState;
|
||||
private ApplicationsState.AppEntry mAppEntry;
|
||||
private ApplicationsState.AppEntry mAppEntry2;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
mScreen = preferenceManager.createPreferenceScreen(mContext);
|
||||
|
||||
ApplicationInfo ai = new ApplicationInfo();
|
||||
ai.packageName = "pkg";
|
||||
ai.uid = 12300;
|
||||
ai.sourceDir = "";
|
||||
ApplicationInfo ai2 = new ApplicationInfo();
|
||||
ai2.packageName = "another";
|
||||
ai2.uid = 18800;
|
||||
ai2.sourceDir = "";
|
||||
mAppEntry = new ApplicationsState.AppEntry(mContext, ai, 0);
|
||||
mAppEntry2 = new ApplicationsState.AppEntry(mContext, ai2, 1);
|
||||
|
||||
mAppEntry.info = ai;
|
||||
mAppEntry.label = "hi";
|
||||
Drawable icon = mock(Drawable.class);
|
||||
mAppEntry.icon = icon;
|
||||
|
||||
mController = new BridgedAppsPreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setUserId(0);
|
||||
mController.setAppState(mAppState);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebuildComplete_AddsToScreen() {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
ArrayList<ApplicationsState.AppEntry> entries = new ArrayList<>();
|
||||
entries.add(mAppEntry);
|
||||
entries.add(mAppEntry2);
|
||||
|
||||
mController.onRebuildComplete(entries);
|
||||
|
||||
assertThat(mScreen.getPreferenceCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebuildComplete_doesNotReaddToScreen() {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
CheckBoxPreference p = mock(CheckBoxPreference.class);
|
||||
when(p.getKey()).thenReturn("pkg|12300");
|
||||
mScreen.addPreference(p);
|
||||
|
||||
ArrayList<ApplicationsState.AppEntry> entries = new ArrayList<>();
|
||||
entries.add(mAppEntry);
|
||||
entries.add(mAppEntry2);
|
||||
|
||||
mController.onRebuildComplete(entries);
|
||||
|
||||
assertThat(mScreen.getPreferenceCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebuildComplete_removesExtras() {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
Preference p = mock(Preference.class);
|
||||
when(p.getKey()).thenReturn("pkg|123");
|
||||
mScreen.addPreference(p);
|
||||
|
||||
ArrayList<ApplicationsState.AppEntry> entries = new ArrayList<>();
|
||||
entries.add(mAppEntry);
|
||||
entries.add(mAppEntry2);
|
||||
|
||||
mController.onRebuildComplete(entries);
|
||||
|
||||
assertThat((Preference) mScreen.findPreference("pkg|123")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebuildComplete_buildsSetting() {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
ArrayList<ApplicationsState.AppEntry> entries = new ArrayList<>();
|
||||
entries.add(mAppEntry);
|
||||
|
||||
mController.onRebuildComplete(entries);
|
||||
|
||||
CheckBoxPreference actual = mScreen.findPreference("pkg|12300");
|
||||
|
||||
assertThat(actual.isChecked()).isTrue();
|
||||
assertThat(actual.getTitle()).isEqualTo("hi");
|
||||
assertThat(actual.getIcon()).isEqualTo(mAppEntry.icon);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_false() {
|
||||
VersionedPackage vp = new VersionedPackage("pkg", 10567);
|
||||
ArraySet<VersionedPackage> vps = new ArraySet<>();
|
||||
vps.add(vp);
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
|
||||
| FLAG_FILTER_TYPE_CONVERSATIONS, vps);
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
pref.setKey("pkg|567");
|
||||
|
||||
mController.onPreferenceChange(pref, false);
|
||||
|
||||
ArgumentCaptor<NotificationListenerFilter> captor =
|
||||
ArgumentCaptor.forClass(NotificationListenerFilter.class);
|
||||
verify(mNm).setListenerFilter(eq(mCn), eq(0), captor.capture());
|
||||
assertThat(captor.getValue().getDisallowedPackages()).contains(
|
||||
new VersionedPackage("pkg", 567));
|
||||
assertThat(captor.getValue().getDisallowedPackages()).contains(
|
||||
new VersionedPackage("pkg", 10567));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_true() {
|
||||
VersionedPackage vp = new VersionedPackage("pkg", 567);
|
||||
VersionedPackage vp2 = new VersionedPackage("pkg", 10567);
|
||||
ArraySet<VersionedPackage> vps = new ArraySet<>();
|
||||
vps.add(vp);
|
||||
vps.add(vp2);
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
|
||||
| FLAG_FILTER_TYPE_CONVERSATIONS, vps);
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
pref.setKey("pkg|567");
|
||||
|
||||
mController.onPreferenceChange(pref, true);
|
||||
|
||||
ArgumentCaptor<NotificationListenerFilter> captor =
|
||||
ArgumentCaptor.forClass(NotificationListenerFilter.class);
|
||||
verify(mNm).setListenerFilter(eq(mCn), eq(0), captor.capture());
|
||||
assertThat(captor.getValue().getDisallowedPackages().size()).isEqualTo(1);
|
||||
assertThat(captor.getValue().getDisallowedPackages()).contains(
|
||||
new VersionedPackage("pkg", 10567));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.specialaccess.notificationaccess;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ServiceInfo;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ConversationTypeFilterPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private ConversationTypeFilterPreferenceController mController;
|
||||
@Mock
|
||||
NotificationBackend mNm;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
ServiceInfo mSi = new ServiceInfo();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
mController = new ConversationTypeFilterPreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setServiceInfo(mSi);
|
||||
mController.setUserId(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getType() {
|
||||
assertThat(mController.getType()).isEqualTo(FLAG_FILTER_TYPE_CONVERSATIONS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.specialaccess.notificationaccess;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ServiceInfo;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class OngoingTypeFilterPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private OngoingTypeFilterPreferenceController mController;
|
||||
@Mock
|
||||
NotificationBackend mNm;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
ServiceInfo mSi = new ServiceInfo();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
mController = new OngoingTypeFilterPreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setServiceInfo(mSi);
|
||||
mController.setUserId(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getType() {
|
||||
assertThat(mController.getType()).isEqualTo(FLAG_FILTER_TYPE_ONGOING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.specialaccess.notificationaccess;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.service.notification.NotificationListenerFilter;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class PreUpgradePreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private PreUpgradePreferenceController mController;
|
||||
@Mock
|
||||
NotificationBackend mNm;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
mController = new PreUpgradePreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setUserId(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_notGranted() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(false);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.S);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_lowTargetSdk_noCustomizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.S);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_lowTargetSdk_customizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.S);
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter();
|
||||
nlf.setTypes(FLAG_FILTER_TYPE_CONVERSATIONS);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_highTargetSdk_noCustomizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.CUR_DEVELOPMENT + 1);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.specialaccess.notificationaccess;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ServiceInfo;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SilentTypeFilterPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private SilentTypeFilterPreferenceController mController;
|
||||
@Mock
|
||||
NotificationBackend mNm;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
ServiceInfo mSi = new ServiceInfo();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
mController = new SilentTypeFilterPreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setServiceInfo(mSi);
|
||||
mController.setUserId(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getType() {
|
||||
assertThat(mController.getType()).isEqualTo(FLAG_FILTER_TYPE_SILENT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.specialaccess.notificationaccess;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
|
||||
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.NotificationListenerFilter;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.preference.CheckBoxPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TypeFilterPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private TypeFilterPreferenceController mController;
|
||||
@Mock
|
||||
NotificationBackend mNm;
|
||||
ComponentName mCn = new ComponentName("a", "b");
|
||||
ServiceInfo mSi = new ServiceInfo();
|
||||
|
||||
private static class TestTypeFilterPreferenceController extends TypeFilterPreferenceController {
|
||||
|
||||
public TestTypeFilterPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getType() {
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
mController = new TestTypeFilterPreferenceController(mContext, "key");
|
||||
mController.setCn(mCn);
|
||||
mController.setNm(mNm);
|
||||
mController.setServiceInfo(mSi);
|
||||
mController.setUserId(0);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.CUR_DEVELOPMENT + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_notGranted() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(false);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.CUR_DEVELOPMENT + 1);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_lowTargetSdk_noCustomizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.S);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_lowTargetSdk_customizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.S);
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter();
|
||||
nlf.setTypes(FLAG_FILTER_TYPE_CONVERSATIONS);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailable_highTargetSdk_noCustomizations() {
|
||||
when(mNm.isNotificationListenerAccessGranted(any())).thenReturn(true);
|
||||
mController.setTargetSdk(Build.VERSION_CODES.CUR_DEVELOPMENT + 1);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_enabled_noMetaData() {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
|
||||
mController.updateState(pref);
|
||||
assertThat(pref.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_enabled_metaData_notTheDisableFilter() {
|
||||
mSi.metaData = new Bundle();
|
||||
mSi.metaData.putCharSequence("test", "value");
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
|
||||
mController.updateState(pref);
|
||||
assertThat(pref.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_enabled_metaData_disableFilter_notThisField() {
|
||||
mSi.metaData = new Bundle();
|
||||
mSi.metaData.putCharSequence(NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES,
|
||||
"1|alerting");
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
|
||||
mController.updateState(pref);
|
||||
assertThat(pref.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_enabled_metaData_disableFilter_thisField_stateIsChecked() {
|
||||
mSi.metaData = new Bundle();
|
||||
mSi.metaData.putCharSequence(NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES,
|
||||
"conversations|2|32");
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(
|
||||
new NotificationListenerFilter(32, new ArraySet<>()));
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
|
||||
mController.updateState(pref);
|
||||
assertThat(pref.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_disabled() {
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(false);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
|
||||
mController.updateState(pref);
|
||||
assertThat(pref.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_disabled_metaData_disableFilter_thisField_stateIsNotChecked() {
|
||||
mSi.metaData = new Bundle();
|
||||
mSi.metaData.putCharSequence(NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES,
|
||||
"1|2|32");
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
NotificationListenerFilter before = new NotificationListenerFilter(4, new ArraySet<>());
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(before);
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
|
||||
mController.updateState(pref);
|
||||
assertThat(pref.isChecked()).isFalse();
|
||||
assertThat(pref.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_checked() {
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter(mController.getType(),
|
||||
new ArraySet<>());
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
mController.updateState(pref);
|
||||
|
||||
assertThat(pref.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_unchecked() {
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter(mController.getType() - 1,
|
||||
new ArraySet<>());
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
mController.updateState(pref);
|
||||
|
||||
assertThat(pref.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_true() {
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
|
||||
| FLAG_FILTER_TYPE_CONVERSATIONS, new ArraySet<>());
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
|
||||
mController.onPreferenceChange(pref, true);
|
||||
|
||||
ArgumentCaptor<NotificationListenerFilter> captor =
|
||||
ArgumentCaptor.forClass(NotificationListenerFilter.class);
|
||||
verify(mNm).setListenerFilter(eq(mCn), eq(0), captor.capture());
|
||||
assertThat(captor.getValue().getTypes()).isEqualTo(FLAG_FILTER_TYPE_CONVERSATIONS
|
||||
| FLAG_FILTER_TYPE_ONGOING | mController.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_false() {
|
||||
NotificationListenerFilter nlf = new NotificationListenerFilter(FLAG_FILTER_TYPE_ONGOING
|
||||
| FLAG_FILTER_TYPE_CONVERSATIONS | mController.getType(), new ArraySet<>());
|
||||
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
|
||||
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
|
||||
|
||||
CheckBoxPreference pref = new CheckBoxPreference(mContext);
|
||||
|
||||
mController.onPreferenceChange(pref, false);
|
||||
|
||||
ArgumentCaptor<NotificationListenerFilter> captor =
|
||||
ArgumentCaptor.forClass(NotificationListenerFilter.class);
|
||||
verify(mNm).setListenerFilter(eq(mCn), eq(0), captor.capture());
|
||||
assertThat(captor.getValue().getTypes()).isEqualTo(FLAG_FILTER_TYPE_CONVERSATIONS
|
||||
| FLAG_FILTER_TYPE_ONGOING);
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.backup;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class BackupIntentTest {
|
||||
private static final String INTENT_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
|
||||
private static final String BACKUP_SETTINGS_ACTIVITY =
|
||||
"com.android.settings.Settings$PrivacyDashboardActivity";
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mContext = instrumentation.getTargetContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivacySettingsIntentResolvesToOnlyOneActivity(){
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
Intent intent = new Intent(INTENT_PRIVACY_SETTINGS);
|
||||
List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
|
||||
assertThat(activities).isNotNull();
|
||||
assertThat(activities.size()).isEqualTo(1);
|
||||
assertThat(activities.get(0).activityInfo.getComponentName().getClassName()).
|
||||
isEqualTo(BACKUP_SETTINGS_ACTIVITY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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;
|
||||
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
|
||||
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_MODALITY;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_CONSENT_DENIED;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_CONSENT_GRANTED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.biometrics.face.FaceEnrollParentalConsent;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollParentalConsent;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ParentalConsentHelperTest {
|
||||
|
||||
private static final int REQUEST_CODE = 12;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMocks = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
private Activity mRootActivity;
|
||||
@Mock
|
||||
private Intent mRootActivityIntent;
|
||||
@Captor
|
||||
ArgumentCaptor<Intent> mLastStarted;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(mRootActivity.getIntent()).thenAnswer(invocation -> mRootActivityIntent);
|
||||
when(mRootActivityIntent.getBundleExtra(any())).thenAnswer(invocation -> null);
|
||||
when(mRootActivityIntent.getStringExtra(any())).thenAnswer(invocation -> null);
|
||||
when(mRootActivityIntent.getBooleanExtra(any(), anyBoolean()))
|
||||
.thenAnswer(invocation -> invocation.getArguments()[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_and_fingerprint_all_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, true /* grantFace */,
|
||||
true /* requireFingerprint */, true /* grantFace */,
|
||||
90 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_nothing_to_consent() {
|
||||
testLaunchNext(
|
||||
false /* requireFace */, false /* grantFace */,
|
||||
false /* requireFingerprint */, false /* grantFace */,
|
||||
80 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_and_fingerprint_no_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, false /* grantFace */,
|
||||
true /* requireFingerprint */, false /* grantFace */,
|
||||
70 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_and_fingerprint_only_face_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, true /* grantFace */,
|
||||
true /* requireFingerprint */, false /* grantFace */,
|
||||
60 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_and_fingerprint_only_fingerprint_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, false /* grantFace */,
|
||||
true /* requireFingerprint */, true /* grantFace */,
|
||||
50 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_with_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, true /* grantFace */,
|
||||
false /* requireFingerprint */, false /* grantFace */,
|
||||
40 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_without_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, false /* grantFace */,
|
||||
false /* requireFingerprint */, false /* grantFace */,
|
||||
30 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_fingerprint_with_consent() {
|
||||
testLaunchNext(
|
||||
false /* requireFace */, false /* grantFace */,
|
||||
true /* requireFingerprint */, true /* grantFace */,
|
||||
20 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_fingerprint_without_consent() {
|
||||
testLaunchNext(
|
||||
false /* requireFace */, false /* grantFace */,
|
||||
true /* requireFingerprint */, false /* grantFace */,
|
||||
10 /* gkpw */);
|
||||
}
|
||||
|
||||
private void testLaunchNext(
|
||||
boolean requireFace, boolean grantFace,
|
||||
boolean requireFingerprint, boolean grantFingerprint,
|
||||
long gkpw) {
|
||||
final List<Pair<String, Boolean>> expectedLaunches = new ArrayList<>();
|
||||
if (requireFace) {
|
||||
expectedLaunches.add(new Pair(FaceEnrollParentalConsent.class.getName(), grantFace));
|
||||
}
|
||||
if (requireFingerprint) {
|
||||
expectedLaunches.add(
|
||||
new Pair(FingerprintEnrollParentalConsent.class.getName(), grantFingerprint));
|
||||
}
|
||||
|
||||
// initial consent status
|
||||
final ParentalConsentHelper helper =
|
||||
new ParentalConsentHelper(requireFace, requireFingerprint, gkpw);
|
||||
assertThat(ParentalConsentHelper.hasFaceConsent(helper.getConsentResult()))
|
||||
.isFalse();
|
||||
assertThat(ParentalConsentHelper.hasFingerprintConsent(helper.getConsentResult()))
|
||||
.isFalse();
|
||||
|
||||
// check expected launches
|
||||
for (int i = 0; i <= expectedLaunches.size(); i++) {
|
||||
final Pair<String, Boolean> expected = i > 0 ? expectedLaunches.get(i - 1) : null;
|
||||
final boolean launchedNext = i == 0
|
||||
? helper.launchNext(mRootActivity, REQUEST_CODE)
|
||||
: helper.launchNext(mRootActivity, REQUEST_CODE,
|
||||
expected.second ? RESULT_CONSENT_GRANTED : RESULT_CONSENT_DENIED,
|
||||
getResultIntent(getStartedModality(expected.first)));
|
||||
assertThat(launchedNext).isEqualTo(i < expectedLaunches.size());
|
||||
}
|
||||
verify(mRootActivity, times(expectedLaunches.size()))
|
||||
.startActivityForResult(mLastStarted.capture(), eq(REQUEST_CODE));
|
||||
assertThat(mLastStarted.getAllValues()
|
||||
.stream().map(i -> i.getComponent().getClassName()).collect(Collectors.toList()))
|
||||
.containsExactlyElementsIn(
|
||||
expectedLaunches.stream().map(i -> i.first).collect(Collectors.toList()))
|
||||
.inOrder();
|
||||
if (!expectedLaunches.isEmpty()) {
|
||||
assertThat(mLastStarted.getAllValues()
|
||||
.stream().map(BiometricUtils::getGatekeeperPasswordHandle).distinct()
|
||||
.collect(Collectors.toList()))
|
||||
.containsExactly(gkpw);
|
||||
}
|
||||
|
||||
// final consent status
|
||||
assertThat(ParentalConsentHelper.hasFaceConsent(helper.getConsentResult()))
|
||||
.isEqualTo(requireFace && grantFace);
|
||||
assertThat(ParentalConsentHelper.hasFingerprintConsent(helper.getConsentResult()))
|
||||
.isEqualTo(requireFingerprint && grantFingerprint);
|
||||
}
|
||||
|
||||
private static Intent getResultIntent(@BiometricAuthenticator.Modality int modality) {
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_KEY_MODALITY, modality);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@BiometricAuthenticator.Modality
|
||||
private static int getStartedModality(String name) {
|
||||
if (name.equals(FaceEnrollParentalConsent.class.getName())) {
|
||||
return TYPE_FACE;
|
||||
}
|
||||
if (name.equals(FingerprintEnrollParentalConsent.class.getName())) {
|
||||
return TYPE_FINGERPRINT;
|
||||
}
|
||||
return TYPE_NONE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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;
|
||||
|
||||
import static junit.framework.TestCase.assertNotNull;
|
||||
import static junit.framework.TestCase.assertNull;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
|
||||
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ParentalControlsUtilsTest {
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private DevicePolicyManager mDpm;
|
||||
private ComponentName mSupervisionComponentName = new ComponentName("pkg", "cls");
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mContext.getContentResolver()).thenReturn(mock(ContentResolver.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that sets the appropriate mocks and testing behavior before returning the actual
|
||||
* EnforcedAdmin from ParentalControlsUtils.
|
||||
*/
|
||||
@Nullable
|
||||
private RestrictedLockUtils.EnforcedAdmin getEnforcedAdminForCombination(
|
||||
@Nullable ComponentName supervisionComponentName,
|
||||
@BiometricAuthenticator.Modality int modality, int keyguardDisabledFlags) {
|
||||
when(mDpm.getProfileOwnerOrDeviceOwnerSupervisionComponent(any(UserHandle.class)))
|
||||
.thenReturn(supervisionComponentName);
|
||||
when(mDpm.getKeyguardDisabledFeatures(eq(supervisionComponentName)))
|
||||
.thenReturn(keyguardDisabledFlags);
|
||||
|
||||
return ParentalControlsUtils.parentConsentRequiredInternal(mDpm, modality,
|
||||
new UserHandle(UserHandle.myUserId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnforcedAdmin_whenDpmDisablesBiometricsAndSupervisionComponentExists() {
|
||||
int[][] tests = {
|
||||
{TYPE_FINGERPRINT, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT},
|
||||
{TYPE_FACE, DevicePolicyManager.KEYGUARD_DISABLE_FACE},
|
||||
{TYPE_IRIS, DevicePolicyManager.KEYGUARD_DISABLE_IRIS},
|
||||
};
|
||||
|
||||
for (int i = 0; i < tests.length; i++) {
|
||||
RestrictedLockUtils.EnforcedAdmin admin = getEnforcedAdminForCombination(
|
||||
mSupervisionComponentName, tests[i][0] /* modality */,
|
||||
tests[i][1] /* keyguardDisableFlags */);
|
||||
assertNotNull(admin);
|
||||
assertEquals(UserManager.DISALLOW_BIOMETRIC, admin.enforcedRestriction);
|
||||
assertEquals(mSupervisionComponentName, admin.component);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoEnforcedAdmin_whenNoSupervisionComponent() {
|
||||
// Even if DPM flag exists, returns null EnforcedAdmin when no supervision component exists
|
||||
RestrictedLockUtils.EnforcedAdmin admin = getEnforcedAdminForCombination(
|
||||
null /* supervisionComponentName */, TYPE_FINGERPRINT,
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
|
||||
assertNull(admin);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.fingerprint;
|
||||
|
||||
import static androidx.test.InstrumentationRegistry.getTargetContext;
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.intent.Intents.intended;
|
||||
import static androidx.test.espresso.intent.Intents.intending;
|
||||
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Instrumentation.ActivityResult;
|
||||
import android.content.ComponentName;
|
||||
|
||||
import androidx.test.espresso.intent.rule.IntentsTestRule;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.google.android.setupcompat.PartnerCustomizationLayout;
|
||||
import com.google.android.setupcompat.template.FooterBarMixin;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class FingerprintEnrollFinishTest {
|
||||
|
||||
@Rule
|
||||
public IntentsTestRule<FingerprintEnrollFinish> mActivityRule =
|
||||
new IntentsTestRule<>(FingerprintEnrollFinish.class);
|
||||
|
||||
@Test
|
||||
public void clickAddAnother_shouldLaunchEnrolling() {
|
||||
final ComponentName enrollingComponent = new ComponentName(
|
||||
getTargetContext(),
|
||||
FingerprintEnrollEnrolling.class);
|
||||
|
||||
intending(hasComponent(enrollingComponent))
|
||||
.respondWith(new ActivityResult(Activity.RESULT_CANCELED, null));
|
||||
|
||||
PartnerCustomizationLayout layout =
|
||||
mActivityRule.getActivity().findViewById(R.id.setup_wizard_layout);
|
||||
layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick();
|
||||
|
||||
intended(hasComponent(enrollingComponent));
|
||||
assertFalse(mActivityRule.getActivity().isFinishing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickAddAnother_shouldPropagateResults() {
|
||||
final ComponentName enrollingComponent = new ComponentName(
|
||||
getTargetContext(),
|
||||
FingerprintEnrollEnrolling.class);
|
||||
|
||||
intending(hasComponent(enrollingComponent))
|
||||
.respondWith(new ActivityResult(Activity.RESULT_OK, null));
|
||||
|
||||
PartnerCustomizationLayout layout =
|
||||
mActivityRule.getActivity().findViewById(R.id.setup_wizard_layout);
|
||||
layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick();
|
||||
|
||||
intended(hasComponent(enrollingComponent));
|
||||
assertTrue(mActivityRule.getActivity().isFinishing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickNext_shouldFinish() {
|
||||
onView(withId(R.id.next_button)).perform(click());
|
||||
assertTrue(mActivityRule.getActivity().isFinishing());
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.fingerprint;
|
||||
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.test.ActivityUnitTestCase;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.google.android.setupcompat.PartnerCustomizationLayout;
|
||||
import com.google.android.setupcompat.template.FooterBarMixin;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FingerprintEnrollIntroductionTest
|
||||
extends ActivityUnitTestCase<FingerprintEnrollIntroduction> {
|
||||
|
||||
private TestContext mContext;
|
||||
|
||||
@Mock
|
||||
private FingerprintManager mFingerprintManager;
|
||||
|
||||
private FingerprintEnrollIntroduction mActivity;
|
||||
|
||||
public FingerprintEnrollIntroductionTest() {
|
||||
super(FingerprintEnrollIntroduction.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = new TestContext(getInstrumentation().getTargetContext());
|
||||
setActivityContext(mContext);
|
||||
|
||||
getInstrumentation().runOnMainSync(() -> {
|
||||
final Intent intent = new Intent();
|
||||
mActivity = startActivity(intent,
|
||||
null /* savedInstanceState */, null /* lastNonConfigurationInstance */);
|
||||
});
|
||||
}
|
||||
|
||||
public void testMaxFingerprint_shouldShowErrorMessage() {
|
||||
final int max = mContext.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
|
||||
doReturn(generateFingerprintList(max)).when(mFingerprintManager)
|
||||
.getEnrolledFingerprints(anyInt());
|
||||
|
||||
getInstrumentation().runOnMainSync(() -> {
|
||||
getInstrumentation().callActivityOnCreate(mActivity, null);
|
||||
getInstrumentation().callActivityOnResume(mActivity);
|
||||
});
|
||||
|
||||
final TextView errorTextView = (TextView) mActivity.findViewById(R.id.error_text);
|
||||
assertNotNull(errorTextView.getText().toString());
|
||||
|
||||
PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout);
|
||||
final Button nextButton = layout.getMixin(FooterBarMixin.class).getPrimaryButtonView();
|
||||
assertEquals(View.GONE, nextButton.getVisibility());
|
||||
}
|
||||
|
||||
private List<Fingerprint> generateFingerprintList(int num) {
|
||||
ArrayList<Fingerprint> list = new ArrayList<>();
|
||||
for (int i = 0; i < num; i++) {
|
||||
list.add(new Fingerprint("Fingerprint " + i, 0, i, 0));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public class TestContext extends ContextWrapper {
|
||||
|
||||
public TestContext(Context base) {
|
||||
super(base);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSystemService(String name) {
|
||||
if (Context.FINGERPRINT_SERVICE.equals(name)) {
|
||||
return mFingerprintManager;
|
||||
}
|
||||
return super.getSystemService(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.bluetooth;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.text.InputFilter;
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
||||
public class Utf8ByteLengthFilterTest extends AndroidTestCase {
|
||||
|
||||
@SmallTest
|
||||
public void testFilter() {
|
||||
// Define the variables
|
||||
CharSequence source;
|
||||
SpannableStringBuilder dest;
|
||||
// Constructor to create a LengthFilter
|
||||
InputFilter lengthFilter = new Utf8ByteLengthFilter(10);
|
||||
InputFilter[] filters = {lengthFilter};
|
||||
|
||||
// filter() implicitly invoked. If the total length > filter length, the filter will
|
||||
// cut off the source CharSequence from beginning to fit the filter length.
|
||||
source = "abc";
|
||||
dest = new SpannableStringBuilder("abcdefgh");
|
||||
dest.setFilters(filters);
|
||||
|
||||
dest.insert(1, source);
|
||||
String expectedString1 = "aabbcdefgh";
|
||||
assertEquals(expectedString1, dest.toString());
|
||||
|
||||
dest.replace(5, 8, source);
|
||||
String expectedString2 = "aabbcabcgh";
|
||||
assertEquals(expectedString2, dest.toString());
|
||||
|
||||
dest.insert(2, source);
|
||||
assertEquals(expectedString2, dest.toString());
|
||||
|
||||
dest.delete(1, 3);
|
||||
String expectedString3 = "abcabcgh";
|
||||
assertEquals(expectedString3, dest.toString());
|
||||
|
||||
dest.append("12345");
|
||||
String expectedString4 = "abcabcgh12";
|
||||
assertEquals(expectedString4, dest.toString());
|
||||
|
||||
source = "\u60a8\u597d"; // 2 Chinese chars == 6 bytes in UTF-8
|
||||
dest.replace(8, 10, source);
|
||||
assertEquals(expectedString3, dest.toString());
|
||||
|
||||
dest.replace(0, 1, source);
|
||||
String expectedString5 = "\u60a8bcabcgh";
|
||||
assertEquals(expectedString5, dest.toString());
|
||||
|
||||
dest.replace(0, 4, source);
|
||||
String expectedString6 = "\u60a8\u597dbcgh";
|
||||
assertEquals(expectedString6, dest.toString());
|
||||
|
||||
source = "\u00a3\u00a5"; // 2 Latin-1 chars == 4 bytes in UTF-8
|
||||
dest.delete(2, 6);
|
||||
dest.insert(0, source);
|
||||
String expectedString7 = "\u00a3\u00a5\u60a8\u597d";
|
||||
assertEquals(expectedString7, dest.toString());
|
||||
|
||||
dest.replace(2, 3, source);
|
||||
String expectedString8 = "\u00a3\u00a5\u00a3\u597d";
|
||||
assertEquals(expectedString8, dest.toString());
|
||||
|
||||
dest.replace(3, 4, source);
|
||||
String expectedString9 = "\u00a3\u00a5\u00a3\u00a3\u00a5";
|
||||
assertEquals(expectedString9, dest.toString());
|
||||
|
||||
// filter() explicitly invoked
|
||||
dest = new SpannableStringBuilder("abcdefgh");
|
||||
CharSequence beforeFilterSource = "TestLengthFilter";
|
||||
String expectedAfterFilter = "TestLength";
|
||||
CharSequence actualAfterFilter = lengthFilter.filter(beforeFilterSource, 0,
|
||||
beforeFilterSource.length(), dest, 0, dest.length());
|
||||
assertEquals(expectedAfterFilter, actualAfterFilter);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.development.featureflags.FeatureFlagsDashboard;
|
||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class LifecycleEventHandlingTest {
|
||||
|
||||
private static final long TIMEOUT = 2000;
|
||||
|
||||
private Context mContext;
|
||||
private String mTargetPackage;
|
||||
private UiDevice mDevice;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
mDevice.wakeUp();
|
||||
mDevice.executeShellCommand("wm dismiss-keyguard");
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
mTargetPackage = mContext.getPackageName();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Presubmit
|
||||
@Ignore("b/133334887")
|
||||
public void launchDashboard_shouldSeeFooter() {
|
||||
new SubSettingLauncher(mContext)
|
||||
.setDestination(FeatureFlagsDashboard.class.getName())
|
||||
.setSourceMetricsCategory(Instrumentable.METRICS_CATEGORY_UNKNOWN)
|
||||
.addFlags(FLAG_ACTIVITY_NEW_TASK)
|
||||
.launch();
|
||||
|
||||
final String footerText = "Experimental";
|
||||
// Scroll to bottom
|
||||
final UiObject2 view = mDevice.wait(
|
||||
Until.findObject(By.res(mTargetPackage, "main_content")),
|
||||
TIMEOUT);
|
||||
view.scroll(Direction.DOWN, 100f);
|
||||
|
||||
assertThat(mDevice.wait(Until.findObject(By.text(footerText)), TIMEOUT))
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 junit.framework.Assert.fail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.MediumTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.search.SearchIndexableData;
|
||||
import com.android.settingslib.search.SearchIndexableResources;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
public class PreferenceControllerContractTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Presubmit
|
||||
public void controllersInSearchShouldImplementPreferenceControllerMixin() {
|
||||
Looper.prepare(); // Required by AutofillLoggingLevelPreferenceController
|
||||
final Set<String> errorClasses = new ArraySet<>();
|
||||
|
||||
final SearchIndexableResources resources =
|
||||
FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
|
||||
.getSearchIndexableResources();
|
||||
for (SearchIndexableData bundle : resources.getProviderValues()) {
|
||||
|
||||
final BaseSearchIndexProvider provider =
|
||||
(BaseSearchIndexProvider) bundle.getSearchIndexProvider();
|
||||
if (provider == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final List<AbstractPreferenceController> controllers =
|
||||
provider.getPreferenceControllers(mContext);
|
||||
if (controllers == null) {
|
||||
continue;
|
||||
}
|
||||
for (AbstractPreferenceController controller : controllers) {
|
||||
if (!(controller instanceof PreferenceControllerMixin)
|
||||
&& !(controller instanceof BasePreferenceController)) {
|
||||
errorClasses.add(controller.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!errorClasses.isEmpty()) {
|
||||
final StringBuilder errorMessage = new StringBuilder()
|
||||
.append("Each preference must implement PreferenceControllerMixin ")
|
||||
.append("or extend BasePreferenceController, ")
|
||||
.append("the following classes don't:\n");
|
||||
for (String c : errorClasses) {
|
||||
errorMessage.append(c).append("\n");
|
||||
}
|
||||
fail(errorMessage.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 android.content.pm.PackageManager.GET_ACTIVITIES;
|
||||
import static android.content.pm.PackageManager.GET_META_DATA;
|
||||
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
|
||||
|
||||
import static com.android.settings.SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.core.gateway.SettingsGateway;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SettingsGatewayTest {
|
||||
|
||||
private static final String TAG = "SettingsGatewayTest";
|
||||
|
||||
private Context mContext;
|
||||
private PackageManager mPackageManager;
|
||||
private String mPackageName;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
mPackageManager = mContext.getPackageManager();
|
||||
mPackageName = mContext.getPackageName();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Presubmit
|
||||
public void allRestrictedActivityMustBeDefinedInManifest() {
|
||||
for (String className : SettingsGateway.SETTINGS_FOR_RESTRICTED) {
|
||||
final Intent intent = new Intent();
|
||||
intent.setComponent(new ComponentName(mPackageName, className));
|
||||
List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent,
|
||||
MATCH_DISABLED_COMPONENTS);
|
||||
Log.d(TAG, mPackageName + "/" + className + "; resolveInfo size: "
|
||||
+ resolveInfos.size());
|
||||
assertFalse(className + " is not-defined in manifest", resolveInfos.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Presubmit
|
||||
public void publicFragmentMustAppearInSettingsGateway()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final List<String> whitelistedFragment = new ArrayList<>();
|
||||
final StringBuilder error = new StringBuilder();
|
||||
|
||||
for (String fragment : SettingsGateway.ENTRY_FRAGMENTS) {
|
||||
whitelistedFragment.add(fragment);
|
||||
}
|
||||
final PackageInfo pi = mPackageManager.getPackageInfo(mPackageName,
|
||||
GET_META_DATA | MATCH_DISABLED_COMPONENTS | GET_ACTIVITIES);
|
||||
final List<ActivityInfo> activities = Arrays.asList(pi.activities);
|
||||
|
||||
for (ActivityInfo activity : activities) {
|
||||
final Bundle metaData = activity.metaData;
|
||||
if (metaData == null || !metaData.containsKey(META_DATA_KEY_FRAGMENT_CLASS)) {
|
||||
continue;
|
||||
}
|
||||
final String fragmentName = metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
|
||||
|
||||
assertThat(fragmentName).isNotNull();
|
||||
if (!whitelistedFragment.contains(fragmentName)) {
|
||||
error.append("SettingsGateway.ENTRY_FRAGMENTS must contain " + fragmentName
|
||||
+ " because this fragment is used in manifest for " + activity.name)
|
||||
.append("\n");
|
||||
}
|
||||
}
|
||||
final String message = error.toString();
|
||||
if (!TextUtils.isEmpty(message)) {
|
||||
fail(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 junit.framework.Assert.fail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.MediumTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.search.Indexable;
|
||||
import com.android.settingslib.search.SearchIndexableData;
|
||||
import com.android.settingslib.search.SearchIndexableRaw;
|
||||
import com.android.settingslib.search.SearchIndexableResources;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
public class UniquePreferenceTest {
|
||||
|
||||
private static final String TAG = "UniquePreferenceTest";
|
||||
private static final List<String> IGNORE_PREF_TYPES = Arrays.asList(
|
||||
"com.android.settingslib.widget.FooterPreference");
|
||||
|
||||
private static final List<String> WHITELISTED_DUPLICATE_KEYS = Arrays.asList(
|
||||
"owner_info_settings", // Lock screen message in security - multiple xml files
|
||||
// contain this because security page is constructed by
|
||||
// combining small xml chunks. Eventually the page
|
||||
// should be formed as one single xml and this entry
|
||||
// should be removed.
|
||||
|
||||
"dashboard_tile_placeholder", // This is the placeholder pref for injecting dynamic
|
||||
// tiles.
|
||||
// Dup keys from About Phone v2 experiment.
|
||||
"ims_reg_state",
|
||||
"bt_address",
|
||||
"device_model",
|
||||
"firmware_version",
|
||||
"regulatory_info",
|
||||
"manual",
|
||||
"legal_container",
|
||||
"device_feedback",
|
||||
"fcc_equipment_id",
|
||||
"sim_status",
|
||||
"build_number",
|
||||
"phone_number",
|
||||
"imei_info",
|
||||
"wifi_ip_address",
|
||||
"wifi_mac_address",
|
||||
"safety_info",
|
||||
// Dupe keys from data usage v2.
|
||||
"data_usage_screen",
|
||||
"cellular_data_usage",
|
||||
"data_usage_wifi_screen",
|
||||
"status_header",
|
||||
"billing_preference",
|
||||
"data_usage_cellular_screen",
|
||||
"wifi_data_usage",
|
||||
"data_usage_enable"
|
||||
);
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* All preferences should have their unique key. It's especially important for many parts of
|
||||
* Settings to work properly: we assume pref keys are unique in displaying, search ranking,\
|
||||
* search result suppression, and many other areas.
|
||||
* <p/>
|
||||
* So in this test we are checking preferences participating in search.
|
||||
* <p/>
|
||||
* Note: Preference is not limited to just <Preference/> object. Everything in preference xml
|
||||
* should have a key.
|
||||
*/
|
||||
@Test
|
||||
@Presubmit
|
||||
public void allPreferencesShouldHaveUniqueKey()
|
||||
throws IOException, XmlPullParserException, Resources.NotFoundException {
|
||||
final Set<String> uniqueKeys = new HashSet<>();
|
||||
final Set<String> nullKeyClasses = new HashSet<>();
|
||||
final Set<String> duplicatedKeys = new HashSet<>();
|
||||
final SearchIndexableResources resources =
|
||||
FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
|
||||
.getSearchIndexableResources();
|
||||
for (SearchIndexableData SearchIndexableData : resources.getProviderValues()) {
|
||||
verifyPreferenceKeys(uniqueKeys, duplicatedKeys, nullKeyClasses, SearchIndexableData);
|
||||
}
|
||||
|
||||
if (!nullKeyClasses.isEmpty()) {
|
||||
final StringBuilder nullKeyErrors = new StringBuilder()
|
||||
.append("Each preference/SearchIndexableData must have a key, ")
|
||||
.append("the following classes have null keys:\n");
|
||||
for (String c : nullKeyClasses) {
|
||||
nullKeyErrors.append(c).append("\n");
|
||||
}
|
||||
fail(nullKeyErrors.toString());
|
||||
}
|
||||
|
||||
if (!duplicatedKeys.isEmpty()) {
|
||||
final StringBuilder dupeKeysError = new StringBuilder(
|
||||
"The following keys are not unique\n");
|
||||
for (String c : duplicatedKeys) {
|
||||
dupeKeysError.append(c).append("\n");
|
||||
}
|
||||
fail(dupeKeysError.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyPreferenceKeys(Set<String> uniqueKeys, Set<String> duplicatedKeys,
|
||||
Set<String> nullKeyClasses, SearchIndexableData searchIndexableData)
|
||||
throws IOException, XmlPullParserException, Resources.NotFoundException {
|
||||
|
||||
final String className = searchIndexableData.getTargetClass().getName();
|
||||
final Indexable.SearchIndexProvider provider =
|
||||
searchIndexableData.getSearchIndexProvider();
|
||||
final List<SearchIndexableRaw> rawsToIndex = provider.getRawDataToIndex(mContext, true);
|
||||
final List<SearchIndexableResource> resourcesToIndex =
|
||||
provider.getXmlResourcesToIndex(mContext, true);
|
||||
verifyResources(className, resourcesToIndex, uniqueKeys, duplicatedKeys, nullKeyClasses);
|
||||
verifyRaws(className, rawsToIndex, uniqueKeys, duplicatedKeys, nullKeyClasses);
|
||||
}
|
||||
|
||||
private void verifyResources(String className, List<SearchIndexableResource> resourcesToIndex,
|
||||
Set<String> uniqueKeys, Set<String> duplicatedKeys, Set<String> nullKeyClasses)
|
||||
throws IOException, XmlPullParserException, Resources.NotFoundException {
|
||||
if (resourcesToIndex == null) {
|
||||
Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
for (SearchIndexableResource sir : resourcesToIndex) {
|
||||
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
|
||||
sir.xmlResId,
|
||||
MetadataFlag.FLAG_INCLUDE_PREF_SCREEN
|
||||
| MetadataFlag.FLAG_NEED_KEY
|
||||
| MetadataFlag.FLAG_NEED_PREF_TYPE);
|
||||
|
||||
for (Bundle bundle : metadata) {
|
||||
final String type = bundle.getString(PreferenceXmlParserUtils.METADATA_PREF_TYPE);
|
||||
if (IGNORE_PREF_TYPES.contains(type)) {
|
||||
continue;
|
||||
}
|
||||
final String key = bundle.getString(PreferenceXmlParserUtils.METADATA_KEY);
|
||||
if (TextUtils.isEmpty(key)) {
|
||||
Log.e(TAG, "Every preference must have an key; found null key"
|
||||
+ " in " + className);
|
||||
nullKeyClasses.add(className);
|
||||
continue;
|
||||
}
|
||||
if (uniqueKeys.contains(key) && !WHITELISTED_DUPLICATE_KEYS.contains(key)) {
|
||||
Log.e(TAG, "Every preference key must unique; found "
|
||||
+ " in " + className
|
||||
+ " / " + key);
|
||||
duplicatedKeys.add(key);
|
||||
}
|
||||
uniqueKeys.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyRaws(String className, List<SearchIndexableRaw> rawsToIndex,
|
||||
Set<String> uniqueKeys, Set<String> duplicatedKeys, Set<String> nullKeyClasses) {
|
||||
if (rawsToIndex == null) {
|
||||
Log.d(TAG, className + "is not providing SearchIndexableRaw, skipping");
|
||||
return;
|
||||
}
|
||||
for (SearchIndexableRaw raw : rawsToIndex) {
|
||||
if (TextUtils.isEmpty(raw.key)) {
|
||||
Log.e(TAG, "Every SearchIndexableRaw must have an key; found null key"
|
||||
+ " in " + className);
|
||||
nullKeyClasses.add(className);
|
||||
continue;
|
||||
}
|
||||
if (uniqueKeys.contains(raw.key) && !WHITELISTED_DUPLICATE_KEYS.contains(raw.key)) {
|
||||
Log.e(TAG, "Every SearchIndexableRaw key must unique; found " + raw.key
|
||||
+ " in " + className);
|
||||
duplicatedKeys.add(raw.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 junit.framework.Assert.fail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.os.UserManager;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.MediumTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.search.Indexable;
|
||||
import com.android.settingslib.search.SearchIndexableData;
|
||||
import com.android.settingslib.search.SearchIndexableResources;
|
||||
|
||||
import com.google.android.collect.Sets;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
public class UserRestrictionTest {
|
||||
|
||||
private static final String TAG = "UserRestrictionTest";
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private static final Set<String> USER_RESTRICTIONS = Sets.newHashSet(
|
||||
UserManager.DISALLOW_CONFIG_DATE_TIME,
|
||||
UserManager.DISALLOW_CONFIG_CREDENTIALS,
|
||||
UserManager.DISALLOW_NETWORK_RESET,
|
||||
UserManager.DISALLOW_FACTORY_RESET,
|
||||
UserManager.DISALLOW_CONFIG_TETHERING,
|
||||
UserManager.DISALLOW_CONFIG_VPN,
|
||||
UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
|
||||
UserManager.DISALLOW_AIRPLANE_MODE,
|
||||
UserManager.DISALLOW_CONFIG_BRIGHTNESS,
|
||||
UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT
|
||||
);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verity that userRestriction attributes are entered and parsed successfully.
|
||||
*/
|
||||
@Test
|
||||
public void userRestrictionAttributeShouldBeValid()
|
||||
throws IOException, XmlPullParserException, Resources.NotFoundException {
|
||||
final SearchIndexableResources resources =
|
||||
FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
|
||||
.getSearchIndexableResources();
|
||||
for (SearchIndexableData bundle : resources.getProviderValues()) {
|
||||
verifyUserRestriction(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyUserRestriction(SearchIndexableData searchIndexableData)
|
||||
throws IOException, XmlPullParserException, Resources.NotFoundException {
|
||||
|
||||
final Indexable.SearchIndexProvider provider =
|
||||
searchIndexableData.getSearchIndexProvider();
|
||||
final List<SearchIndexableResource> resourcesToIndex =
|
||||
provider.getXmlResourcesToIndex(mContext, true);
|
||||
|
||||
final String className = searchIndexableData.getTargetClass().getName();
|
||||
|
||||
if (resourcesToIndex == null) {
|
||||
Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
for (SearchIndexableResource sir : resourcesToIndex) {
|
||||
if (sir.xmlResId <= 0) {
|
||||
Log.d(TAG, className + " doesn't have a valid xml to index.");
|
||||
continue;
|
||||
}
|
||||
final XmlResourceParser parser = mContext.getResources().getXml(sir.xmlResId);
|
||||
|
||||
int type;
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& type != XmlPullParser.START_TAG) {
|
||||
// Parse next until start tag is found
|
||||
}
|
||||
final int outerDepth = parser.getDepth();
|
||||
|
||||
do {
|
||||
if (type != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
final String nodeName = parser.getName();
|
||||
if (!nodeName.endsWith("Preference")) {
|
||||
continue;
|
||||
}
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
final String userRestriction = getDataUserRestrictions(mContext, attrs);
|
||||
if (userRestriction != null) {
|
||||
if(!isValidRestriction(userRestriction)) {
|
||||
fail("userRestriction in " + className + " not valid.");
|
||||
}
|
||||
}
|
||||
} while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth));
|
||||
}
|
||||
}
|
||||
|
||||
boolean isValidRestriction(String userRestriction) {
|
||||
return USER_RESTRICTIONS.contains(userRestriction);
|
||||
}
|
||||
|
||||
private String getDataUserRestrictions(Context context, AttributeSet attrs) {
|
||||
return getData(context, attrs,
|
||||
com.android.settingslib.R.styleable.RestrictedPreference,
|
||||
com.android.settingslib.R.styleable.RestrictedPreference_userRestriction);
|
||||
}
|
||||
|
||||
private String getData(Context context, AttributeSet set, int[] attrs, int resId) {
|
||||
final TypedArray ta = context.obtainStyledAttributes(set, attrs);
|
||||
String data = ta.getString(resId);
|
||||
ta.recycle();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.res.Resources;
|
||||
import android.view.View;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
|
||||
/***
|
||||
* Matches on the first view with id if there are multiple views using the same Id.
|
||||
*/
|
||||
public class FirstIdViewMatcher {
|
||||
|
||||
public static Matcher<View> withFirstId(final int id) {
|
||||
return new TypeSafeMatcher<View>() {
|
||||
Resources resources = null;
|
||||
private boolean mMatched;
|
||||
|
||||
public void describeTo(Description description) {
|
||||
String idDescription = Integer.toString(id);
|
||||
if (resources != null) {
|
||||
try {
|
||||
idDescription = resources.getResourceName(id);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
// No big deal, will just use the int value.
|
||||
idDescription = String.format("%s (resource name not found)", id);
|
||||
}
|
||||
}
|
||||
description.appendText("with first id: " + idDescription);
|
||||
}
|
||||
|
||||
public boolean matchesSafely(View view) {
|
||||
this.resources = view.getResources();
|
||||
if (mMatched) {
|
||||
return false;
|
||||
} else {
|
||||
mMatched = id == view.getId();
|
||||
return mMatched;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.espresso.matcher.ViewMatchers.Visibility;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class PreferenceThemeTest {
|
||||
|
||||
private Instrumentation mInstrumentation;
|
||||
private Context mTargetContext;
|
||||
private String mTargetPackage;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mTargetContext = mInstrumentation.getTargetContext();
|
||||
mTargetPackage = mTargetContext.getPackageName();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startSetupWizardLockScreen_preferenceIconSpaceNotReserved() {
|
||||
launchSetupWizardLockScreen();
|
||||
// Icons should not be shown, and the frame should not occupy extra space.
|
||||
onView(allOf(withId(R.id.icon_frame), withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
.check(doesNotExist());
|
||||
onView(withId(R.id.icon_container)).check(doesNotExist());
|
||||
}
|
||||
|
||||
private void launchSetupWizardLockScreen() {
|
||||
final Intent settingsIntent = new Intent("com.android.settings.SETUP_LOCK_SCREEN")
|
||||
.addCategory(Intent.CATEGORY_DEFAULT)
|
||||
.setPackage(mTargetPackage)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
InstrumentationRegistry.getInstrumentation().startActivitySync(settingsIntent);
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 android.app.Instrumentation;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.MediumTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
public class UiBlockerControllerTest {
|
||||
private static final long TIMEOUT = 600;
|
||||
private static final String KEY_1 = "key1";
|
||||
private static final String KEY_2 = "key2";
|
||||
|
||||
private Instrumentation mInstrumentation;
|
||||
private UiBlockerController mSyncableController;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
|
||||
mSyncableController = new UiBlockerController(Arrays.asList(KEY_1, KEY_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void start_isSyncedReturnFalseUntilAllWorkDone() throws InterruptedException {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
mSyncableController.start(() -> latch.countDown());
|
||||
|
||||
// Return false at first
|
||||
assertThat(mSyncableController.isBlockerFinished()).isFalse();
|
||||
|
||||
// Return false if only one job is done
|
||||
mSyncableController.countDown(KEY_1);
|
||||
assertThat(mSyncableController.isBlockerFinished()).isFalse();
|
||||
|
||||
// Return true if all jobs done
|
||||
mSyncableController.countDown(KEY_2);
|
||||
assertThat(latch.await(TIMEOUT, TimeUnit.MILLISECONDS)).isTrue();
|
||||
assertThat(mSyncableController.isBlockerFinished()).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.profileselector;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ProfileSelectStorageFragmentTest {
|
||||
|
||||
private ProfileSelectStorageFragment mFragment;
|
||||
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
|
||||
mFragment = new ProfileSelectStorageFragment();
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void test_initializeOptionsMenuInvalidatesExistingMenu() {
|
||||
final Activity activity = mock(Activity.class);
|
||||
|
||||
mFragment.initializeOptionsMenu(activity);
|
||||
|
||||
verify(activity).invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
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;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AppPrefLoaderTest {
|
||||
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
private AppPrefLoader mLoader;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final ArraySet<String> pkgs = new ArraySet<>(2);
|
||||
pkgs.add("pkg0");
|
||||
pkgs.add("pkg1");
|
||||
mLoader = new AppPrefLoader(
|
||||
ApplicationProvider.getApplicationContext(), pkgs, mPackageManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadInBackground_packageNotFound_shouldReturnEmptySet()
|
||||
throws NameNotFoundException {
|
||||
when(mPackageManager.getApplicationInfo(anyString(), anyInt()))
|
||||
.thenThrow(new NameNotFoundException());
|
||||
|
||||
assertThat(mLoader.loadInBackground()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadInBackground_shouldReturnPreference() throws NameNotFoundException {
|
||||
ApplicationInfo info = mock(ApplicationInfo.class);
|
||||
when(mPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn(info);
|
||||
final Drawable drawable = mock(Drawable.class);
|
||||
final String label = "Label1";
|
||||
when(info.loadIcon(mPackageManager)).thenReturn(drawable);
|
||||
when(info.loadLabel(mPackageManager)).thenReturn(label);
|
||||
|
||||
Preference preference = mLoader.loadInBackground().valueAt(0);
|
||||
assertThat(preference.getTitle()).isEqualTo(label);
|
||||
assertThat(preference.getIcon()).isEqualTo(drawable);
|
||||
assertThat(preference.isSelectable()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -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.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
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;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class CellDataPreferenceTest {
|
||||
|
||||
@Mock
|
||||
private SubscriptionInfo mSubInfo;
|
||||
|
||||
private Context mContext;
|
||||
private CellDataPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
mPreference = new CellDataPreference(mContext, null) {
|
||||
@Override
|
||||
SubscriptionInfo getActiveSubscriptionInfo(int subId) {
|
||||
return mSubInfo;
|
||||
}
|
||||
};
|
||||
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
final View view = inflater.inflate(mPreference.getLayoutResource(),
|
||||
new LinearLayout(mContext), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateEnabled_noActiveSub_shouldDisable() {
|
||||
mSubInfo = null;
|
||||
|
||||
mPreference.mOnSubscriptionsChangeListener.onChanged();
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateEnabled_hasActiveSub_shouldEnable() {
|
||||
mPreference.mOnSubscriptionsChangeListener.onChanged();
|
||||
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.net.NetworkPolicy;
|
||||
import android.net.NetworkTemplate;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.net.DataUsageController.DataUsageInfo;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DataUsageInfoControllerTest {
|
||||
|
||||
private static final int NEGATIVE = -1;
|
||||
private static final int ZERO = 0;
|
||||
private static final int POSITIVE_SMALL = 1;
|
||||
private static final int POSITIVE_LARGE = 5;
|
||||
|
||||
private DataUsageInfoController mInfoController;
|
||||
private DataUsageInfo info;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mInfoController = new DataUsageInfoController();
|
||||
info = new DataUsageInfo();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummaryLimit_LowUsageLowWarning_LimitUsed() {
|
||||
info.warningLevel = POSITIVE_SMALL;
|
||||
info.limitLevel = POSITIVE_LARGE;
|
||||
info.usageLevel = POSITIVE_SMALL;
|
||||
|
||||
assertThat(mInfoController.getSummaryLimit(info)).isEqualTo(info.limitLevel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummaryLimit_LowUsageEqualWarning_LimitUsed() {
|
||||
info.warningLevel = POSITIVE_LARGE;
|
||||
info.limitLevel = POSITIVE_LARGE;
|
||||
info.usageLevel = POSITIVE_SMALL;
|
||||
|
||||
assertThat(mInfoController.getSummaryLimit(info)).isEqualTo(info.limitLevel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummaryLimit_NoLimitNoUsage_WarningUsed() {
|
||||
info.warningLevel = POSITIVE_LARGE;
|
||||
info.limitLevel = ZERO;
|
||||
info.usageLevel = ZERO;
|
||||
|
||||
assertThat(mInfoController.getSummaryLimit(info)).isEqualTo(info.warningLevel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummaryLimit_NoLimitLowUsage_WarningUsed() {
|
||||
info.warningLevel = POSITIVE_LARGE;
|
||||
info.limitLevel = ZERO;
|
||||
info.usageLevel = POSITIVE_SMALL;
|
||||
|
||||
assertThat(mInfoController.getSummaryLimit(info)).isEqualTo(info.warningLevel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummaryLimit_LowWarningNoLimit_UsageUsed() {
|
||||
info.warningLevel = POSITIVE_SMALL;
|
||||
info.limitLevel = ZERO;
|
||||
info.usageLevel = POSITIVE_LARGE;
|
||||
|
||||
assertThat(mInfoController.getSummaryLimit(info)).isEqualTo(info.usageLevel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummaryLimit_LowWarningLowLimit_UsageUsed() {
|
||||
info.warningLevel = POSITIVE_SMALL;
|
||||
info.limitLevel = POSITIVE_SMALL;
|
||||
info.usageLevel = POSITIVE_LARGE;
|
||||
|
||||
assertThat(mInfoController.getSummaryLimit(info)).isEqualTo(info.usageLevel);
|
||||
}
|
||||
|
||||
private NetworkPolicy getDefaultNetworkPolicy() {
|
||||
NetworkTemplate template = NetworkTemplate.buildTemplateWifi(
|
||||
NetworkTemplate.WIFI_NETWORKID_ALL, null /* subscriberId */);
|
||||
int cycleDay = -1;
|
||||
String cycleTimezone = "UTC";
|
||||
long warningBytes = -1;
|
||||
long limitBytes = -1;
|
||||
return new NetworkPolicy(template, cycleDay, cycleTimezone, warningBytes, limitBytes, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDataLimit_NullArguments_NoError() {
|
||||
mInfoController.updateDataLimit(null, null);
|
||||
mInfoController.updateDataLimit(info, null);
|
||||
mInfoController.updateDataLimit(null, getDefaultNetworkPolicy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDataLimit_NegativeWarning_UpdatedToZero() {
|
||||
NetworkPolicy policy = getDefaultNetworkPolicy();
|
||||
policy.warningBytes = NEGATIVE;
|
||||
|
||||
mInfoController.updateDataLimit(info, policy);
|
||||
|
||||
assertThat(info.warningLevel).isEqualTo(ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDataLimit_WarningZero_UpdatedToZero() {
|
||||
NetworkPolicy policy = getDefaultNetworkPolicy();
|
||||
policy.warningBytes = ZERO;
|
||||
|
||||
mInfoController.updateDataLimit(info, policy);
|
||||
|
||||
assertThat(info.warningLevel).isEqualTo(ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDataLimit_WarningPositive_UpdatedToWarning() {
|
||||
NetworkPolicy policy = getDefaultNetworkPolicy();
|
||||
policy.warningBytes = POSITIVE_SMALL;
|
||||
|
||||
mInfoController.updateDataLimit(info, policy);
|
||||
|
||||
assertThat(info.warningLevel).isEqualTo(policy.warningBytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDataLimit_LimitNegative_UpdatedToZero() {
|
||||
NetworkPolicy policy = getDefaultNetworkPolicy();
|
||||
policy.limitBytes = NEGATIVE;
|
||||
|
||||
mInfoController.updateDataLimit(info, policy);
|
||||
|
||||
assertThat(info.limitLevel).isEqualTo(ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDataLimit_LimitZero_UpdatedToZero() {
|
||||
NetworkPolicy policy = getDefaultNetworkPolicy();
|
||||
policy.limitBytes = ZERO;
|
||||
|
||||
mInfoController.updateDataLimit(info, policy);
|
||||
|
||||
assertThat(info.limitLevel).isEqualTo(ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDataLimit_LimitPositive_UpdatedToLimit() {
|
||||
NetworkPolicy policy = getDefaultNetworkPolicy();
|
||||
policy.limitBytes = POSITIVE_SMALL;
|
||||
|
||||
mInfoController.updateDataLimit(info, policy);
|
||||
|
||||
assertThat(info.limitLevel).isEqualTo(policy.limitBytes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,573 @@
|
||||
/*
|
||||
* 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.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.MeasureSpec;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DataUsageSummaryPreferenceTest {
|
||||
|
||||
private static final long CYCLE_DURATION_MILLIS = 1000000000L;
|
||||
private static final long UPDATE_LAG_MILLIS = 10000000L;
|
||||
private static final String FAKE_CARRIER = "z-mobile";
|
||||
|
||||
private Context mContext;
|
||||
private Resources mResources;
|
||||
private PreferenceViewHolder mHolder;
|
||||
private DataUsageSummaryPreference mSummaryPreference;
|
||||
|
||||
private long mCycleEnd;
|
||||
private long mUpdateTime;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mResources = spy(mContext.getResources());
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
mSummaryPreference = spy(new DataUsageSummaryPreference(mContext, null /* attrs */));
|
||||
LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class);
|
||||
View view = inflater.inflate(
|
||||
mSummaryPreference.getLayoutResource(),
|
||||
null /* root */, false /* attachToRoot */);
|
||||
|
||||
mHolder = spy(PreferenceViewHolder.createInstanceForTests(view));
|
||||
assertThat(mSummaryPreference.getDataUsed(mHolder)).isNotNull();
|
||||
|
||||
final long now = System.currentTimeMillis();
|
||||
mCycleEnd = now + CYCLE_DURATION_MILLIS;
|
||||
mUpdateTime = now - UPDATE_LAG_MILLIS;
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void testSetUsageInfo_withLaunchIntent_launchButtonShown() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getLaunchButton(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withoutLaunchIntent_launchButtonNotShown() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
null /* launchIntent */);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getLaunchButton(mHolder).getVisibility())
|
||||
.isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withDataPlans_carrierInfoShown() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withNoDataPlans_carrierInfoNotShown() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getVisibility())
|
||||
.isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierUpdateTime_shouldFormatDaysCorrectly() {
|
||||
int baseUnit = 2;
|
||||
int smudge = 6;
|
||||
final long updateTime = System.currentTimeMillis()
|
||||
- TimeUnit.DAYS.toMillis(baseUnit) - TimeUnit.HOURS.toMillis(smudge);
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getText().toString())
|
||||
.isEqualTo("Updated by " + FAKE_CARRIER + " " + baseUnit + " days ago");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierUpdateTime_shouldFormatHoursCorrectly() {
|
||||
int baseUnit = 2;
|
||||
int smudge = 6;
|
||||
final long updateTime = System.currentTimeMillis()
|
||||
- TimeUnit.HOURS.toMillis(baseUnit) - TimeUnit.MINUTES.toMillis(smudge);
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getText().toString())
|
||||
.isEqualTo("Updated by " + FAKE_CARRIER + " " + baseUnit + " hr ago");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierUpdateTime_shouldFormatMinutesCorrectly() {
|
||||
int baseUnit = 2;
|
||||
int smudge = 6;
|
||||
final long updateTime = System.currentTimeMillis()
|
||||
- TimeUnit.MINUTES.toMillis(baseUnit) - TimeUnit.SECONDS.toMillis(smudge);
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getText().toString())
|
||||
.isEqualTo("Updated by " + FAKE_CARRIER + " " + baseUnit + " min ago");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierUpdateTime_shouldFormatLessThanMinuteCorrectly() {
|
||||
final long updateTime = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(45);
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getText().toString())
|
||||
.isEqualTo("Updated by " + FAKE_CARRIER + " just now");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierUpdateTimeWithNoCarrier_shouldSayJustNow() {
|
||||
final long updateTime = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(45);
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, null /* carrier */,
|
||||
1 /* numPlans */, new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getText().toString())
|
||||
.isEqualTo("Updated just now");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierUpdateTimeWithNoCarrier_shouldFormatTime() {
|
||||
final long updateTime = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2);
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, null /* carrier */,
|
||||
1 /* numPlans */, new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getText().toString())
|
||||
.isEqualTo("Updated 2 min ago");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setUsageInfo_withRecentCarrierUpdate_doesNotSetCarrierInfoWarningColorAndFont() {
|
||||
final long updateTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1);
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
TextView carrierInfo = mSummaryPreference.getCarrierInfo(mHolder);
|
||||
assertThat(carrierInfo.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(carrierInfo.getCurrentTextColor()).isEqualTo(
|
||||
Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorSecondary));
|
||||
assertThat(carrierInfo.getTypeface()).isEqualTo(Typeface.SANS_SERIF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withStaleCarrierUpdate_setsCarrierInfoWarningColorAndFont() {
|
||||
final long updateTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(7);
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
TextView carrierInfo = mSummaryPreference.getCarrierInfo(mHolder);
|
||||
assertThat(carrierInfo.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(carrierInfo.getCurrentTextColor()).isEqualTo(
|
||||
Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorError));
|
||||
assertThat(carrierInfo.getTypeface()).isEqualTo(
|
||||
DataUsageSummaryPreference.SANS_SERIF_MEDIUM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withNoDataPlans_usageTitleNotShown() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getUsageTitle(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withMultipleDataPlans_usageTitleShown() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 2 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getUsageTitle(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_cycleRemainingTimeIsLessOneDay() {
|
||||
// just under one day
|
||||
final long cycleEnd = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(23);
|
||||
mSummaryPreference.setUsageInfo(cycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCycleTime(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getCycleTime(mHolder).getText()).isEqualTo(
|
||||
ResourcesUtils.getResourcesString(
|
||||
mContext, "billing_cycle_less_than_one_day_left"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_cycleRemainingTimeNegativeDaysLeft_shouldDisplayNoneLeft() {
|
||||
final long cycleEnd = System.currentTimeMillis() - 1L;
|
||||
mSummaryPreference.setUsageInfo(cycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCycleTime(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getCycleTime(mHolder).getText()).isEqualTo(
|
||||
ResourcesUtils.getResourcesString(mContext, "billing_cycle_none_left"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_cycleRemainingTimeDaysLeft_shouldUsePlurals() {
|
||||
final int daysLeft = 3;
|
||||
final long cycleEnd = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(daysLeft)
|
||||
+ TimeUnit.HOURS.toMillis(1);
|
||||
mSummaryPreference.setUsageInfo(cycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
new Intent());
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getCycleTime(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getCycleTime(mHolder).getText())
|
||||
.isEqualTo(daysLeft + " days left");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLimitInfo_withLimitInfo_dataLimitsShown() {
|
||||
final String limitText = "test limit text";
|
||||
mSummaryPreference.setLimitInfo(limitText);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getDataLimits(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getDataLimits(mHolder).getText()).isEqualTo(limitText);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLimitInfo_withNullLimitInfo_dataLimitsNotShown() {
|
||||
mSummaryPreference.setLimitInfo(null);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getDataLimits(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLimitInfo_withEmptyLimitInfo_dataLimitsNotShown() {
|
||||
final String emptyLimitText = "";
|
||||
mSummaryPreference.setLimitInfo(emptyLimitText);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getDataLimits(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetChartEnabledFalse_hidesLabelBar() {
|
||||
setValidLabels();
|
||||
mSummaryPreference.setChartEnabled(false);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getLabelBar(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mSummaryPreference.getProgressBar(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetEmptyLabels_hidesLabelBar() {
|
||||
mSummaryPreference.setLabels("", "");
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getLabelBar(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mSummaryPreference.getProgressBar(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLabelBar_isVisible_whenLabelsSet() {
|
||||
setValidLabels();
|
||||
//mChartEnabled defaults to true
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getLabelBar(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getProgressBar(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetProgress_updatesProgressBar() {
|
||||
setValidLabels();
|
||||
mSummaryPreference.setProgress(.5f);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getProgressBar(mHolder).getProgress()).isEqualTo(50);
|
||||
}
|
||||
|
||||
private void setValidLabels() {
|
||||
mSummaryPreference.setLabels("0.0 GB", "5.0 GB");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageAndRemainingInfo_withUsageInfo_dataUsageAndRemainingShown() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
mSummaryPreference.setUsageNumbers(
|
||||
BillingCycleSettings.MIB_IN_BYTES,
|
||||
10 * BillingCycleSettings.MIB_IN_BYTES,
|
||||
true /* hasMobileData */);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getDataUsed(mHolder).getText().toString())
|
||||
.isEqualTo("1.00 MB used");
|
||||
assertThat(mSummaryPreference.getDataRemaining(mHolder).getText().toString())
|
||||
.isEqualTo("9.00 MB left");
|
||||
assertThat(mSummaryPreference.getDataRemaining(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
final int colorId = Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorAccent);
|
||||
assertThat(mSummaryPreference.getDataRemaining(mHolder).getCurrentTextColor())
|
||||
.isEqualTo(colorId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withDataOverusage() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
mSummaryPreference.setUsageNumbers(
|
||||
11 * BillingCycleSettings.MIB_IN_BYTES,
|
||||
10 * BillingCycleSettings.MIB_IN_BYTES,
|
||||
true /* hasMobileData */);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getDataUsed(mHolder).getText().toString())
|
||||
.isEqualTo("11.00 MB used");
|
||||
assertThat(mSummaryPreference.getDataRemaining(mHolder).getText().toString())
|
||||
.isEqualTo("1.00 MB over");
|
||||
final int colorId = Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorError);
|
||||
assertThat(mSummaryPreference.getDataRemaining(mHolder).getCurrentTextColor())
|
||||
.isEqualTo(colorId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withUsageInfo_dataUsageShown() {
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
new Intent());
|
||||
mSummaryPreference.setUsageNumbers(
|
||||
BillingCycleSettings.MIB_IN_BYTES, -1L, true /* hasMobileData */);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getDataUsed(mHolder).getText().toString())
|
||||
.isEqualTo("1.00 MB used");
|
||||
assertThat(mSummaryPreference.getDataRemaining(mHolder).getText()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetAppIntent_toMdpApp_intentCorrect() {
|
||||
final Intent intent = new Intent(SubscriptionManager.ACTION_MANAGE_SUBSCRIPTION_PLANS);
|
||||
intent.setPackage("test-owner.example.com");
|
||||
intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 42);
|
||||
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
intent);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getLaunchButton(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getLaunchButton(mHolder).getText())
|
||||
.isEqualTo(ResourcesUtils.getResourcesString(mContext, "launch_mdp_app_text"));
|
||||
|
||||
doNothing().when(mContext).startActivity(any(Intent.class));
|
||||
mSummaryPreference.getLaunchButton(mHolder).callOnClick();
|
||||
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(
|
||||
Intent.class);
|
||||
verify(mContext).startActivity(intentCaptor.capture());
|
||||
final Intent startedIntent = intentCaptor.getValue();
|
||||
|
||||
assertThat(startedIntent.getAction())
|
||||
.isEqualTo(SubscriptionManager.ACTION_MANAGE_SUBSCRIPTION_PLANS);
|
||||
assertThat(startedIntent.getPackage()).isEqualTo("test-owner.example.com");
|
||||
assertThat(startedIntent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, -1))
|
||||
.isEqualTo(42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUsageInfo_withOverflowStrings_dataRemainingNotShown() {
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
View view = inflater.inflate(mSummaryPreference.getLayoutResource(), null /* root */,
|
||||
false /* attachToRoot */);
|
||||
|
||||
mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, FAKE_CARRIER, 1 /* numPlans */,
|
||||
new Intent());
|
||||
mSummaryPreference.setUsageNumbers(
|
||||
BillingCycleSettings.MIB_IN_BYTES,
|
||||
10 * BillingCycleSettings.MIB_IN_BYTES,
|
||||
true /* hasMobileData */);
|
||||
|
||||
int data_used_formatted_id = ResourcesUtils.getResourcesId(
|
||||
mContext, "string", "data_used_formatted");
|
||||
int data_remaining_id = ResourcesUtils.getResourcesId(
|
||||
mContext, "string", "data_remaining");
|
||||
CharSequence data_used_formatted_cs = "^1 ^2 used with long trailing text";
|
||||
CharSequence data_remaining_cs = "^1 left";
|
||||
doReturn(data_used_formatted_cs).when(mResources).getText(data_used_formatted_id);
|
||||
doReturn(data_remaining_cs).when(mResources).getText(data_remaining_id);
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
|
||||
TextView dataUsed = mSummaryPreference.getDataUsed(mHolder);
|
||||
TextView dataRemaining = mSummaryPreference.getDataRemaining(mHolder);
|
||||
int width = MeasureSpec.makeMeasureSpec(500, MeasureSpec.EXACTLY);
|
||||
dataUsed.measure(width, MeasureSpec.UNSPECIFIED);
|
||||
dataRemaining.measure(width, MeasureSpec.UNSPECIFIED);
|
||||
|
||||
assertThat(dataRemaining.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
|
||||
MeasurableLinearLayout layout = mSummaryPreference.getLayout(mHolder);
|
||||
layout.measure(
|
||||
MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
|
||||
|
||||
assertThat(dataUsed.getText().toString()).isEqualTo("1.00 MB used with long trailing text");
|
||||
// TODO(b/175389659): re-enable this line once cuttlefish device specs are verified.
|
||||
// assertThat(dataRemaining.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetWifiMode_withUsageInfo_dataUsageShown() {
|
||||
final int daysLeft = 3;
|
||||
final long cycleEnd = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(daysLeft)
|
||||
+ TimeUnit.HOURS.toMillis(1);
|
||||
mSummaryPreference.setUsageInfo(cycleEnd, mUpdateTime, FAKE_CARRIER, 0 /* numPlans */,
|
||||
new Intent());
|
||||
mSummaryPreference.setUsageNumbers(1000000L, -1L, true);
|
||||
final String cycleText = "The quick fox";
|
||||
mSummaryPreference.setWifiMode(true /* isWifiMode */, cycleText, false /* isSingleWifi */);
|
||||
doReturn(200L).when(mSummaryPreference).getHistoricalUsageLevel();
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
assertThat(mSummaryPreference.getUsageTitle(mHolder).getText().toString())
|
||||
.isEqualTo(ResourcesUtils.getResourcesString(mContext, "data_usage_wifi_title"));
|
||||
assertThat(mSummaryPreference.getUsageTitle(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getCycleTime(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getCycleTime(mHolder).getText()).isEqualTo(cycleText);
|
||||
assertThat(mSummaryPreference.getCarrierInfo(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mSummaryPreference.getDataLimits(mHolder).getVisibility()).isEqualTo(View.GONE);
|
||||
assertThat(mSummaryPreference.getLaunchButton(mHolder).getVisibility())
|
||||
.isEqualTo(View.VISIBLE);
|
||||
assertThat(mSummaryPreference.getLaunchButton(mHolder).getText())
|
||||
.isEqualTo(ResourcesUtils.getResourcesString(mContext, "launch_wifi_text"));
|
||||
|
||||
doNothing().when(mContext).startActivity(any(Intent.class));
|
||||
mSummaryPreference.getLaunchButton(mHolder).callOnClick();
|
||||
|
||||
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(
|
||||
Intent.class);
|
||||
verify(mContext).startActivity(intentCaptor.capture());
|
||||
final Intent startedIntent = intentCaptor.getValue();
|
||||
|
||||
final Bundle expect = new Bundle(1);
|
||||
expect.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE,
|
||||
NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
|
||||
null /* subscriberId */));
|
||||
final Bundle actual = startedIntent
|
||||
.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||
assertThat((NetworkTemplate) actual.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE))
|
||||
.isEqualTo(NetworkTemplate.buildTemplateWifi(
|
||||
NetworkTemplate.WIFI_NETWORKID_ALL, null /* subscriberId */));
|
||||
|
||||
assertThat(startedIntent.getIntExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, 0))
|
||||
.isEqualTo(ResourcesUtils.getResourcesId(mContext, "string", "wifi_data_usage"));
|
||||
}
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void testSetWifiMode_noUsageInfo_shouldDisableLaunchButton() {
|
||||
mSummaryPreference.setWifiMode(true /* isWifiMode */, "Test cycle text",
|
||||
false /* isSingleWifi */);
|
||||
doReturn(0L).when(mSummaryPreference).getHistoricalUsageLevel();
|
||||
|
||||
mSummaryPreference.onBindViewHolder(mHolder);
|
||||
|
||||
assertThat(mSummaryPreference.getLaunchButton(mHolder).isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchWifiDataUsage_shouldSetWifiNetworkTypeInIntentExtra() {
|
||||
doNothing().when(mContext).startActivity(any(Intent.class));
|
||||
mSummaryPreference.launchWifiDataUsage(mContext);
|
||||
|
||||
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(
|
||||
Intent.class);
|
||||
verify(mContext).startActivity(intentCaptor.capture());
|
||||
final Intent launchIntent = intentCaptor.getValue();
|
||||
final Bundle args =
|
||||
launchIntent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||
|
||||
assertThat(args.getInt(DataUsageList.EXTRA_NETWORK_TYPE))
|
||||
.isEqualTo(ConnectivityManager.TYPE_WIFI);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.model;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class TimeZoneDataTest {
|
||||
|
||||
private TimeZoneData mTimeZoneData;
|
||||
@Before
|
||||
public void setUp() {
|
||||
mTimeZoneData = TimeZoneData.getInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupCountryTimeZones_shouldReturnAtLeastOneTimeZoneInEveryRegion() {
|
||||
Set<String> regionIds = mTimeZoneData.getRegionIds();
|
||||
for (String regionId : regionIds) {
|
||||
FilteredCountryTimeZones countryTimeZones =
|
||||
mTimeZoneData.lookupCountryTimeZones(regionId);
|
||||
assertThat(countryTimeZones).isNotNull();
|
||||
assertThat(countryTimeZones.getPreferredTimeZoneIds().size()).isGreaterThan(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupCountryCodesForZoneId_shouldNotReturnHiddenZone() {
|
||||
/*
|
||||
Simferopol is filtered out for two reasons:
|
||||
1) because we specifically exclude it with the picker attribute, and
|
||||
2) because it's the same as Moscow after Oct 2014.
|
||||
*/
|
||||
assertThat(mTimeZoneData.lookupCountryCodesForZoneId("Europe/Simferopol")).isEmpty();
|
||||
assertThat(mTimeZoneData.lookupCountryCodesForZoneId("Europe/London")).isNotEmpty();
|
||||
assertThat(mTimeZoneData.lookupCountryCodesForZoneId("America/Los_Angeles")).isNotEmpty();
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 android.content.Context;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class BluetoothMaxConnectedAudioDevicesPreferenceControllerInstrumentationTest {
|
||||
|
||||
private Context mTargetContext;
|
||||
private String[] mListValues;
|
||||
private String[] mListEntries;
|
||||
private String mDefaultMaxConnectedAudioDevices;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mTargetContext = InstrumentationRegistry.getTargetContext();
|
||||
// Get XML values without mock
|
||||
mListValues = mTargetContext.getResources()
|
||||
.getStringArray(R.array.bluetooth_max_connected_audio_devices_values);
|
||||
mListEntries = mTargetContext.getResources()
|
||||
.getStringArray(R.array.bluetooth_max_connected_audio_devices);
|
||||
mDefaultMaxConnectedAudioDevices = String.valueOf(mTargetContext.getResources()
|
||||
.getInteger(
|
||||
com.android.internal.R.integer
|
||||
.config_bluetooth_max_connected_audio_devices));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyResource() {
|
||||
// Verify normal list entries and default preference entries have the same size
|
||||
Assert.assertEquals(mListEntries.length, mListValues.length);
|
||||
Assert.assertThat(Arrays.asList(mListValues),
|
||||
CoreMatchers.hasItem(mDefaultMaxConnectedAudioDevices));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin.SECURE_OVERLAY_SETTINGS;
|
||||
|
||||
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.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() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
SECURE_OVERLAY_SETTINGS, 1);
|
||||
|
||||
assertThat(OverlaySettingsPreferenceController.isOverlaySettingsEnabled(mContext)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isOverlaySettingsEnabled_sharePreferenceSetFalse_shouldReturnFalse() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
SECURE_OVERLAY_SETTINGS, 0);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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_shouldReturnAVAILABLE() {
|
||||
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.android.settings.development.transcode.TranscodeDisableCachePreferenceController.TRANSCODE_DISABLE_CACHE_SYS_PROP_KEY;
|
||||
|
||||
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 TranscodeDisableCachePreferenceControllerTest {
|
||||
|
||||
private TranscodeDisableCachePreferenceController mUnderTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
mUnderTest = new TranscodeDisableCachePreferenceController(context, "some_key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_whenSysPropSet_shouldReturnTrue() {
|
||||
SystemProperties.set(TRANSCODE_DISABLE_CACHE_SYS_PROP_KEY, "true");
|
||||
assertThat(mUnderTest.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_whenSysPropUnset_shouldReturnFalse() {
|
||||
SystemProperties.set(TRANSCODE_DISABLE_CACHE_SYS_PROP_KEY, "false");
|
||||
assertThat(mUnderTest.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_withTrue_shouldSetSysProp() {
|
||||
mUnderTest.setChecked(true);
|
||||
assertThat(
|
||||
SystemProperties.getBoolean(TRANSCODE_DISABLE_CACHE_SYS_PROP_KEY, false)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_withFalse_shouldUnsetSysProp() {
|
||||
mUnderTest.setChecked(false);
|
||||
assertThat(
|
||||
SystemProperties.getBoolean(TRANSCODE_DISABLE_CACHE_SYS_PROP_KEY, true)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_shouldReturnAVAILABLE() {
|
||||
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.android.settings.development.transcode.TranscodeNotificationPreferenceController.TRANSCODE_NOTIFICATION_SYS_PROP_KEY;
|
||||
|
||||
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 TranscodeNotificationPreferenceControllerTest {
|
||||
private TranscodeNotificationPreferenceController mUnderTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
mUnderTest = new TranscodeNotificationPreferenceController(context, "notification_key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_whenSysPropSet_shouldReturnTrue() {
|
||||
SystemProperties.set(TRANSCODE_NOTIFICATION_SYS_PROP_KEY, "true");
|
||||
assertThat(mUnderTest.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_whenSysPropUnset_shouldReturnFalse() {
|
||||
SystemProperties.set(TRANSCODE_NOTIFICATION_SYS_PROP_KEY, "false");
|
||||
assertThat(mUnderTest.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_withTrue_shouldSetSysProp() {
|
||||
mUnderTest.setChecked(true);
|
||||
assertThat(
|
||||
SystemProperties.getBoolean(TRANSCODE_NOTIFICATION_SYS_PROP_KEY, false)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_withFalse_shouldUnsetSysProp() {
|
||||
mUnderTest.setChecked(false);
|
||||
assertThat(
|
||||
SystemProperties.getBoolean(TRANSCODE_NOTIFICATION_SYS_PROP_KEY, true)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_shouldReturnAVAILABLE() {
|
||||
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
}
|
||||
@@ -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_shouldReturnAVAILABLE() {
|
||||
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
import static com.android.settings.deviceinfo.DeviceNamePreferenceController.RES_SHOW_DEVICE_NAME_BOOL;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.net.wifi.SoftApConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.widget.ValidatedEditTextPreference;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DeviceNamePreferenceControllerTest {
|
||||
private static final String TESTING_STRING = "Testing";
|
||||
private static final String TEST_PREFERENCE_KEY = "test_key";
|
||||
|
||||
@Mock
|
||||
private WifiManager mWifiManager;
|
||||
private PreferenceScreen mScreen;
|
||||
private ValidatedEditTextPreference mPreference;
|
||||
private DeviceNamePreferenceController mController;
|
||||
private Context mContext;
|
||||
private Resources mResources;
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager);
|
||||
mResources = spy(mContext.getResources());
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
mScreen = preferenceManager.createPreferenceScreen(mContext);
|
||||
mPreference = new ValidatedEditTextPreference(mContext);
|
||||
mPreference.setKey(TEST_PREFERENCE_KEY);
|
||||
mScreen.addPreference(mPreference);
|
||||
|
||||
final SoftApConfiguration configuration =
|
||||
new SoftApConfiguration.Builder().setSsid("test-ap").build();
|
||||
when(mWifiManager.getSoftApConfiguration()).thenReturn(configuration);
|
||||
|
||||
mController = new DeviceNamePreferenceController(mContext, TEST_PREFERENCE_KEY);
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
Settings.Global.putString(
|
||||
mContext.getContentResolver(), Settings.Global.DEVICE_NAME, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailibilityStatus_availableByDefault() {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_unsupportedWhenSet() {
|
||||
doReturn(false).when(mResources).getBoolean(RES_SHOW_DEVICE_NAME_BOOL);
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructor_defaultDeviceNameIsModelName() {
|
||||
assertThat(mController.getSummary()).isEqualTo(Build.MODEL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructor_deviceNameLoadedIfSet() {
|
||||
Settings.Global.putString(
|
||||
mContext.getContentResolver(), Settings.Global.DEVICE_NAME, "Test");
|
||||
mController = new DeviceNamePreferenceController(mContext, "test_key");
|
||||
assertThat(mController.getSummary()).isEqualTo("Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isTextValid_nameUnder33Characters_isValid() {
|
||||
assertThat(mController.isTextValid("12345678901234567890123456789012")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isTextValid_nameTooLong_isInvalid() {
|
||||
assertThat(mController.isTextValid("123456789012345678901234567890123")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDeviceName_preferenceUpdatedWhenDeviceNameUpdated() {
|
||||
acceptDeviceName(true);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.onPreferenceChange(mPreference, TESTING_STRING);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(TESTING_STRING);
|
||||
}
|
||||
|
||||
// TODO(b/175389659): Determine why this test case fails for virtual but not local devices.
|
||||
@Ignore
|
||||
@Test
|
||||
public void setDeviceName_bluetoothNameUpdatedWhenDeviceNameUpdated() {
|
||||
acceptDeviceName(true);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.onPreferenceChange(mPreference, TESTING_STRING);
|
||||
|
||||
assertThat(mBluetoothAdapter.getName()).isEqualTo(TESTING_STRING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDeviceName_wifiTetherNameUpdatedWhenDeviceNameUpdated() {
|
||||
acceptDeviceName(true);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.onPreferenceChange(mPreference, TESTING_STRING);
|
||||
|
||||
ArgumentCaptor<SoftApConfiguration> captor =
|
||||
ArgumentCaptor.forClass(SoftApConfiguration.class);
|
||||
verify(mWifiManager).setSoftApConfiguration(captor.capture());
|
||||
assertThat(captor.getValue().getSsid()).isEqualTo(TESTING_STRING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_defaultDeviceNameIsModelNameOnPreference() {
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreference.getText()).isEqualTo(Build.MODEL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDeviceName_okInDeviceNameWarningDialog_shouldChangePreferenceText() {
|
||||
acceptDeviceName(true);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.onPreferenceChange(mPreference, TESTING_STRING);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(TESTING_STRING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDeviceName_cancelInDeviceNameWarningDialog_shouldNotChangePreferenceText() {
|
||||
acceptDeviceName(false);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.onPreferenceChange(mPreference, TESTING_STRING);
|
||||
|
||||
assertThat(mPreference.getSummary()).isNotEqualTo(TESTING_STRING);
|
||||
assertThat(mPreference.getText()).isEqualTo(mPreference.getSummary());
|
||||
}
|
||||
|
||||
private void acceptDeviceName(boolean accept) {
|
||||
mController.setHost(deviceName -> mController.updateDeviceName(accept));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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;
|
||||
|
||||
import static android.content.Context.CLIPBOARD_SERVICE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class PhoneNumberPreferenceControllerTest {
|
||||
|
||||
private Preference mPreference;
|
||||
@Mock
|
||||
private Preference mSecondPreference;
|
||||
@Mock
|
||||
private TelephonyManager mTelephonyManager;
|
||||
@Mock
|
||||
private SubscriptionInfo mSubscriptionInfo;
|
||||
@Mock
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
private PreferenceScreen mScreen;
|
||||
private PreferenceCategory mCategory;
|
||||
|
||||
private Context mContext;
|
||||
private PhoneNumberPreferenceController mController;
|
||||
private ClipboardManager mClipboardManager;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mClipboardManager = (ClipboardManager) spy(mContext.getSystemService(CLIPBOARD_SERVICE));
|
||||
doReturn(mClipboardManager).when(mContext).getSystemService(CLIPBOARD_SERVICE);
|
||||
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
|
||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
mController = spy(new PhoneNumberPreferenceController(mContext, "phone_number"));
|
||||
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
mScreen = preferenceManager.createPreferenceScreen(mContext);
|
||||
mPreference = spy(new Preference(mContext));
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
mPreference.setVisible(true);
|
||||
mScreen.addPreference(mPreference);
|
||||
final String categoryKey = "basic_info_category";
|
||||
mCategory = new PreferenceCategory(mContext);
|
||||
mCategory.setKey(categoryKey);
|
||||
mScreen.addPreference(mCategory);
|
||||
|
||||
doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
|
||||
doReturn(mSecondPreference).when(mController).createNewPreference(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_isVoiceCapable_shouldBeAVAILABLE() {
|
||||
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_isNotVoiceCapable_shouldBeUNSUPPORTED_ON_DEVICE() {
|
||||
when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_multiSim_shouldAddSecondPreference() {
|
||||
when(mTelephonyManager.getPhoneCount()).thenReturn(2);
|
||||
|
||||
final Preference sim1Preference = new Preference(mContext);
|
||||
mCategory.addItemFromInflater(sim1Preference);
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mCategory.getPreferenceCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_singleSim_shouldUpdateTitleAndPhoneNumber() {
|
||||
final String phoneNumber = "1111111111";
|
||||
doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
|
||||
when(mTelephonyManager.getPhoneCount()).thenReturn(1);
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setTitle(ResourcesUtils.getResourcesString(mContext, "status_number"));
|
||||
verify(mPreference).setSummary(phoneNumber);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_multiSim_shouldUpdateTitleAndPhoneNumberOfMultiplePreferences() {
|
||||
final String phoneNumber = "1111111111";
|
||||
doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
|
||||
when(mTelephonyManager.getPhoneCount()).thenReturn(2);
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setTitle(ResourcesUtils.getResourcesString(
|
||||
mContext, "status_number_sim_slot", 1 /* sim slot */));
|
||||
verify(mPreference).setSummary(phoneNumber);
|
||||
verify(mSecondPreference).setTitle(ResourcesUtils.getResourcesString(
|
||||
mContext, "status_number_sim_slot", 2 /* sim slot */));
|
||||
verify(mSecondPreference).setSummary(phoneNumber);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_cannotGetActiveSubscriptionInfo_shouldShowUnknown() {
|
||||
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
|
||||
|
||||
CharSequence primaryNumber = mController.getSummary();
|
||||
|
||||
assertThat(primaryNumber).isNotNull();
|
||||
assertThat(primaryNumber).isEqualTo(ResourcesUtils.getResourcesString(
|
||||
mContext, "device_info_default"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_getEmptySubscriptionInfo_shouldShowUnknown() {
|
||||
List<SubscriptionInfo> infos = new ArrayList<>();
|
||||
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(infos);
|
||||
|
||||
CharSequence primaryNumber = mController.getSummary();
|
||||
|
||||
assertThat(primaryNumber).isEqualTo(ResourcesUtils.getResourcesString(
|
||||
mContext, "device_info_default"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void copy_shouldCopyPhoneNumberToClipboard() {
|
||||
final List<SubscriptionInfo> list = new ArrayList<>();
|
||||
list.add(mSubscriptionInfo);
|
||||
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(list);
|
||||
final String phoneNumber = "1111111111";
|
||||
doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
|
||||
ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class);
|
||||
doNothing().when(mClipboardManager).setPrimaryClip(captor.capture());
|
||||
|
||||
mController.copy();
|
||||
|
||||
final CharSequence data = captor.getValue().getItemAt(0).getText();
|
||||
assertThat(phoneNumber.contentEquals(data)).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.usage.StorageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.icu.text.NumberFormat;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.text.format.Formatter;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TopLevelStoragePreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private StorageManagerVolumeProvider mStorageManagerVolumeProvider;
|
||||
|
||||
private Context mContext;
|
||||
private TopLevelStoragePreferenceController mController;
|
||||
private List<VolumeInfo> mVolumes;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
mVolumes = new ArrayList<>();
|
||||
mVolumes.add(mock(VolumeInfo.class, RETURNS_DEEP_STUBS));
|
||||
when(mStorageManagerVolumeProvider.getVolumes()).thenReturn(mVolumes);
|
||||
|
||||
mController = spy(new TopLevelStoragePreferenceController(mContext, "test_key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateSummary_shouldDisplayUsedPercentAndFreeSpace() throws Exception {
|
||||
final VolumeInfo volumeInfo = mVolumes.get(0);
|
||||
when(volumeInfo.isMountedReadable()).thenReturn(true);
|
||||
when(volumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
|
||||
when(mStorageManagerVolumeProvider
|
||||
.getTotalBytes(nullable(StorageStatsManager.class), nullable(VolumeInfo.class)))
|
||||
.thenReturn(500L);
|
||||
when(mStorageManagerVolumeProvider
|
||||
.getFreeBytes(nullable(StorageStatsManager.class), nullable(VolumeInfo.class)))
|
||||
.thenReturn(0L);
|
||||
when(mController.getStorageManagerVolumeProvider())
|
||||
.thenReturn(mStorageManagerVolumeProvider);
|
||||
final String percentage = NumberFormat.getPercentInstance().format(1);
|
||||
final String freeSpace = Formatter.formatFileSize(mContext, 0);
|
||||
final Preference preference = new Preference(mContext);
|
||||
|
||||
// Wait for asynchronous thread to finish, otherwise test will flake.
|
||||
Future thread = mController.refreshSummaryThread(preference);
|
||||
try {
|
||||
thread.get();
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
fail("Exception during automatic selection");
|
||||
}
|
||||
|
||||
|
||||
// Sleep for 5 seconds because a function is executed on the main thread from within
|
||||
// the background thread.
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
assertThat(preference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(
|
||||
mContext, "storage_summary", percentage, freeSpace));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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;
|
||||
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.storage.DiskInfo;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.os.storage.VolumeRecord;
|
||||
import android.view.Menu;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.deviceinfo.storage.StorageEntry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class VolumeOptionMenuControllerTest {
|
||||
|
||||
private static final String INTERNAL_VOLUME_ID = "1";
|
||||
private static final String EXTERNAL_VOLUME_ID = "2";
|
||||
private static final String DISK_ID = "3";
|
||||
private static final String VOLUME_RECORD_FSUUID = "volume_record_fsuuid";
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Menu mMenu;
|
||||
@Mock private PackageManager mPackageManager;
|
||||
@Mock private StorageManager mStorageManager;
|
||||
@Mock private VolumeInfo mExternalVolumeInfo;
|
||||
@Mock private VolumeInfo mInternalVolumeInfo;
|
||||
|
||||
private Context mContext;
|
||||
private VolumeOptionMenuController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager);
|
||||
|
||||
when(mInternalVolumeInfo.getId()).thenReturn(INTERNAL_VOLUME_ID);
|
||||
when(mInternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
|
||||
when(mInternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
|
||||
when(mInternalVolumeInfo.isMountedWritable()).thenReturn(true);
|
||||
when(mExternalVolumeInfo.getId()).thenReturn(EXTERNAL_VOLUME_ID);
|
||||
|
||||
final StorageEntry selectedStorageEntry = new StorageEntry(mContext, mInternalVolumeInfo);
|
||||
mController = new VolumeOptionMenuController(mContext, mock(Fragment.class),
|
||||
selectedStorageEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_unSupportedDiskInfo_formatIsVisible() {
|
||||
final StorageEntry unsupportedStorageEntry =
|
||||
new StorageEntry(new DiskInfo(DISK_ID, 0 /* flags */));
|
||||
mController.setSelectedStorageEntry(unsupportedStorageEntry);
|
||||
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mFormat, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mRename, never()).setVisible(true);
|
||||
verify(mController.mMount, never()).setVisible(true);
|
||||
verify(mController.mUnmount, never()).setVisible(true);
|
||||
verify(mController.mFormatAsPortable, never()).setVisible(true);
|
||||
verify(mController.mFormatAsInternal, never()).setVisible(true);
|
||||
verify(mController.mMigrate, never()).setVisible(true);
|
||||
verify(mController.mFree, never()).setVisible(true);
|
||||
verify(mController.mForget, never()).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_missingVolumeRecord_forgetIsVisible() {
|
||||
final StorageEntry missingStorageEntry =
|
||||
new StorageEntry(new VolumeRecord(0 /* type */, VOLUME_RECORD_FSUUID));
|
||||
mController.setSelectedStorageEntry(missingStorageEntry);
|
||||
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mForget, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mRename, never()).setVisible(true);
|
||||
verify(mController.mMount, never()).setVisible(true);
|
||||
verify(mController.mUnmount, never()).setVisible(true);
|
||||
verify(mController.mFormat, never()).setVisible(true);
|
||||
verify(mController.mFormatAsPortable, never()).setVisible(true);
|
||||
verify(mController.mFormatAsInternal, never()).setVisible(true);
|
||||
verify(mController.mMigrate, never()).setVisible(true);
|
||||
verify(mController.mFree, never()).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_unmountedStorage_mountIsVisible() {
|
||||
when(mInternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_UNMOUNTED);
|
||||
mController.setSelectedStorageEntry(new StorageEntry(mContext, mInternalVolumeInfo));
|
||||
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mMount, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mRename, never()).setVisible(true);
|
||||
verify(mController.mUnmount, never()).setVisible(true);
|
||||
verify(mController.mFormat, never()).setVisible(true);
|
||||
verify(mController.mFormatAsPortable, never()).setVisible(true);
|
||||
verify(mController.mFormatAsInternal, never()).setVisible(true);
|
||||
verify(mController.mMigrate, never()).setVisible(true);
|
||||
verify(mController.mFree, never()).setVisible(true);
|
||||
verify(mController.mForget, never()).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_privateNotDefaultInternal_someMenusAreVisible() {
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mRename, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mUnmount, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mFormatAsPortable, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mMount, never()).setVisible(true);
|
||||
verify(mController.mFormat, never()).setVisible(true);
|
||||
verify(mController.mFormatAsInternal, never()).setVisible(true);
|
||||
verify(mController.mFree, never()).setVisible(true);
|
||||
verify(mController.mForget, never()).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_privateDefaultInternal_mostMenusAreNotVisible() {
|
||||
when(mInternalVolumeInfo.getId()).thenReturn(VolumeInfo.ID_PRIVATE_INTERNAL);
|
||||
when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mInternalVolumeInfo);
|
||||
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mRename, never()).setVisible(true);
|
||||
verify(mController.mUnmount, never()).setVisible(true);
|
||||
verify(mController.mFormatAsPortable, never()).setVisible(true);
|
||||
verify(mController.mMount, never()).setVisible(true);
|
||||
verify(mController.mFormat, never()).setVisible(true);
|
||||
verify(mController.mFormatAsInternal, never()).setVisible(true);
|
||||
verify(mController.mFree, never()).setVisible(true);
|
||||
verify(mController.mForget, never()).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_publicStorage_someMenusArcVisible() {
|
||||
when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
|
||||
when(mExternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
|
||||
when(mExternalVolumeInfo.getDiskId()).thenReturn(DISK_ID);
|
||||
final DiskInfo externalDiskInfo = mock(DiskInfo.class);
|
||||
when(mStorageManager.findDiskById(DISK_ID)).thenReturn(externalDiskInfo);
|
||||
mController.setSelectedStorageEntry(new StorageEntry(mContext, mExternalVolumeInfo));
|
||||
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mRename, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mUnmount, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mFormat, atLeastOnce()).setVisible(true);
|
||||
verify(mController.mMount, never()).setVisible(true);
|
||||
verify(mController.mFormatAsPortable, never()).setVisible(true);
|
||||
verify(mController.mFormatAsInternal, never()).setVisible(true);
|
||||
verify(mController.mFree, never()).setVisible(true);
|
||||
verify(mController.mForget, never()).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_noExternalStorage_migrateNotVisible() {
|
||||
when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mInternalVolumeInfo);
|
||||
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mMigrate, atLeastOnce()).setVisible(false);
|
||||
verify(mController.mMigrate, never()).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_externalPrimaryStorageAvailable_migrateIsVisible() {
|
||||
when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
|
||||
when(mExternalVolumeInfo.isMountedWritable()).thenReturn(true);
|
||||
when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mExternalVolumeInfo);
|
||||
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mMigrate, atLeastOnce()).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrepareOptionsMenu_externalUnmounted_migrateIsVisible() {
|
||||
when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
|
||||
when(mExternalVolumeInfo.isMountedWritable()).thenReturn(false);
|
||||
when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mExternalVolumeInfo);
|
||||
|
||||
mController.onPrepareOptionsMenu(mMenu);
|
||||
|
||||
verify(mController.mMigrate, atLeastOnce()).setVisible(false);
|
||||
verify(mController.mMigrate, never()).setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.deviceinfo.legal;
|
||||
|
||||
import static com.android.settings.deviceinfo.legal.ModuleLicenseProvider.LICENSE_FILE_NAME;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ModuleInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ModuleLicenseProviderTest {
|
||||
public static final String PACKAGE_NAME = "com.android.test_package";
|
||||
@Test
|
||||
public void onCreate_returnsTrue() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
assertThat(provider.onCreate()).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void query_throwsUnsupportedOperationException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.query(null, null, null, null, null);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void insert_throwsUnsupportedOperationException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.insert(null, null);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void delete_throwsUnsupportedOperationException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.delete(null, null, null);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void update_throwsUnsupportedOperationException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.update(null, null, null, null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getType_notContentScheme_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.getType(new Uri.Builder()
|
||||
.scheme("badscheme")
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getType_invalidAuthority_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.getType(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority("notmyauthority")
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getType_emptyPath_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.getType(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getType_missingPackageName_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.getType(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getType_missingFileName_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.getType(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getType_incorrectFileName_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.getType(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath("badname.txt")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void getType_packageNotAModule_throwsIllegalArgumentException()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
ModuleLicenseProvider provider = spy(new ModuleLicenseProvider());
|
||||
Context context = mock(Context.class);
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
when(provider.getModuleContext()).thenReturn(context);
|
||||
when(context.getPackageManager()).thenReturn(packageManager);
|
||||
when(packageManager.getModuleInfo(PACKAGE_NAME, 0))
|
||||
.thenThrow(new PackageManager.NameNotFoundException());
|
||||
|
||||
provider.getType(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getType_validUri_returnsHtmlMimeType()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
ModuleLicenseProvider provider = spy(new ModuleLicenseProvider());
|
||||
Context context = mock(Context.class);
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
when(provider.getModuleContext()).thenReturn(context);
|
||||
when(context.getPackageManager()).thenReturn(packageManager);
|
||||
when(packageManager.getModuleInfo(PACKAGE_NAME, 0))
|
||||
.thenReturn(new ModuleInfo());
|
||||
|
||||
assertThat(provider.getType(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build())).isEqualTo(ModuleLicenseProvider.LICENSE_FILE_MIME_TYPE);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void openFile_notContentScheme_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.openFile(new Uri.Builder()
|
||||
.scheme("badscheme")
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build(), "r");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void openFile_invalidAuthority_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.openFile(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority("notmyauthority")
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build(), "r");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void openFile_emptyPath_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.openFile(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.build(), "r");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void openFile_missingPackageName_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.openFile(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build(), "r");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void openFile_missingFileName_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.openFile(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.build(), "r");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void openFile_incorrectFileName_throwsIllegalArgumentException() {
|
||||
ModuleLicenseProvider provider = new ModuleLicenseProvider();
|
||||
provider.openFile(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath("badname.txt")
|
||||
.build(), "r");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void openFile_packageNotAModule_throwsIllegalArgumentException()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
ModuleLicenseProvider provider = spy(new ModuleLicenseProvider());
|
||||
Context context = mock(Context.class);
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
when(provider.getModuleContext()).thenReturn(context);
|
||||
when(context.getPackageManager()).thenReturn(packageManager);
|
||||
when(packageManager.getModuleInfo(PACKAGE_NAME, 0))
|
||||
.thenThrow(new PackageManager.NameNotFoundException());
|
||||
|
||||
provider.openFile(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build(), "r");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void openFile_validUri_notReadMode_throwsIllegalArgumentException()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
ModuleLicenseProvider provider = spy(new ModuleLicenseProvider());
|
||||
Context context = mock(Context.class);
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
when(provider.getModuleContext()).thenReturn(context);
|
||||
when(context.getPackageManager()).thenReturn(packageManager);
|
||||
when(packageManager.getModuleInfo(PACKAGE_NAME, 0))
|
||||
.thenReturn(new ModuleInfo());
|
||||
|
||||
provider.openFile(new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(ModuleLicenseProvider.AUTHORITY)
|
||||
.appendPath(PACKAGE_NAME)
|
||||
.appendPath(LICENSE_FILE_NAME)
|
||||
.build(), "badmode");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCachedHtmlFileOutdated_packageNotInSharedPrefs_returnTrue()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
context.getSharedPreferences(ModuleLicenseProvider.PREFS_NAME, Context.MODE_PRIVATE)
|
||||
.edit().clear().commit();
|
||||
|
||||
assertThat(ModuleLicenseProvider.isCachedHtmlFileOutdated(context, PACKAGE_NAME)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCachedHtmlFileOutdated_versionCodeDiffersFromSharedPref_returnTrue()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
Context context = spy(ApplicationProvider.getApplicationContext());
|
||||
SharedPreferences.Editor editor = context.getSharedPreferences(
|
||||
ModuleLicenseProvider.PREFS_NAME, Context.MODE_PRIVATE)
|
||||
.edit();
|
||||
editor.clear().commit();
|
||||
editor.putLong(PACKAGE_NAME, 900L).commit();
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
doReturn(packageManager).when(context).getPackageManager();
|
||||
PackageInfo packageInfo = new PackageInfo();
|
||||
packageInfo.setLongVersionCode(1000L);
|
||||
when(packageManager.getPackageInfo(PACKAGE_NAME, PackageManager.MATCH_APEX))
|
||||
.thenReturn(packageInfo);
|
||||
|
||||
assertThat(ModuleLicenseProvider.isCachedHtmlFileOutdated(context, PACKAGE_NAME)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCachedHtmlFileOutdated_fileDoesNotExist_returnTrue()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
Context context = spy(ApplicationProvider.getApplicationContext());
|
||||
context.getSharedPreferences(ModuleLicenseProvider.PREFS_NAME, Context.MODE_PRIVATE)
|
||||
.edit().clear().commit();
|
||||
SharedPreferences.Editor editor = context.getSharedPreferences(
|
||||
ModuleLicenseProvider.PREFS_NAME, Context.MODE_PRIVATE)
|
||||
.edit();
|
||||
editor.clear().commit();
|
||||
editor.putLong(PACKAGE_NAME, 1000L).commit();
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
doReturn(packageManager).when(context).getPackageManager();
|
||||
PackageInfo packageInfo = new PackageInfo();
|
||||
packageInfo.setLongVersionCode(1000L);
|
||||
when(packageManager.getPackageInfo(PACKAGE_NAME, PackageManager.MATCH_APEX))
|
||||
.thenReturn(packageInfo);
|
||||
new File(context.getCacheDir() + "/" + PACKAGE_NAME, LICENSE_FILE_NAME).delete();
|
||||
|
||||
assertThat(ModuleLicenseProvider.isCachedHtmlFileOutdated(context, PACKAGE_NAME)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCachedHtmlFileOutdated_fileIsEmpty_returnTrue()
|
||||
throws PackageManager.NameNotFoundException, IOException {
|
||||
Context context = spy(ApplicationProvider.getApplicationContext());
|
||||
context.getSharedPreferences(ModuleLicenseProvider.PREFS_NAME, Context.MODE_PRIVATE)
|
||||
.edit().clear().commit();
|
||||
SharedPreferences.Editor editor = context.getSharedPreferences(
|
||||
ModuleLicenseProvider.PREFS_NAME, Context.MODE_PRIVATE)
|
||||
.edit();
|
||||
editor.clear().commit();
|
||||
editor.putLong(PACKAGE_NAME, 1000L).commit();
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
doReturn(packageManager).when(context).getPackageManager();
|
||||
PackageInfo packageInfo = new PackageInfo();
|
||||
packageInfo.setLongVersionCode(1000L);
|
||||
when(packageManager.getPackageInfo(PACKAGE_NAME, PackageManager.MATCH_APEX))
|
||||
.thenReturn(packageInfo);
|
||||
new File(context.getCacheDir(), PACKAGE_NAME).mkdir();
|
||||
File file = new File(context.getCacheDir() + "/" + PACKAGE_NAME, LICENSE_FILE_NAME);
|
||||
file.delete();
|
||||
file.createNewFile();
|
||||
|
||||
assertThat(ModuleLicenseProvider.isCachedHtmlFileOutdated(context, PACKAGE_NAME)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCachedHtmlFileOutdated_notOutdated_returnFalse()
|
||||
throws PackageManager.NameNotFoundException, IOException {
|
||||
Context context = spy(ApplicationProvider.getApplicationContext());
|
||||
context.getSharedPreferences(ModuleLicenseProvider.PREFS_NAME, Context.MODE_PRIVATE)
|
||||
.edit().clear().commit();
|
||||
SharedPreferences.Editor editor = context.getSharedPreferences(
|
||||
ModuleLicenseProvider.PREFS_NAME, Context.MODE_PRIVATE)
|
||||
.edit();
|
||||
editor.clear().commit();
|
||||
editor.putLong(PACKAGE_NAME, 1000L).commit();
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
doReturn(packageManager).when(context).getPackageManager();
|
||||
PackageInfo packageInfo = new PackageInfo();
|
||||
packageInfo.setLongVersionCode(1000L);
|
||||
when(packageManager.getPackageInfo(PACKAGE_NAME, PackageManager.MATCH_APEX))
|
||||
.thenReturn(packageInfo);
|
||||
new File(context.getCacheDir(), PACKAGE_NAME).mkdir();
|
||||
File file = new File(context.getCacheDir() + "/" + PACKAGE_NAME, LICENSE_FILE_NAME);
|
||||
file.delete();
|
||||
file.createNewFile();
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
|
||||
writer.write("test");
|
||||
}
|
||||
|
||||
assertThat(ModuleLicenseProvider.isCachedHtmlFileOutdated(context, PACKAGE_NAME)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUriForPackage_returnsProperlyFormattedUri() {
|
||||
assertThat(ModuleLicenseProvider.getUriForPackage(PACKAGE_NAME))
|
||||
.isEqualTo(Uri.parse(
|
||||
"content://com.android.settings.module_licenses/"
|
||||
+ "com.android.test_package/NOTICE.html"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,767 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.simstatus;
|
||||
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.CELL_DATA_NETWORK_TYPE_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.CELL_VOICE_NETWORK_TYPE_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.EID_INFO_LABEL_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.EID_INFO_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.ICCID_INFO_LABEL_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.ICCID_INFO_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.IMS_REGISTRATION_STATE_LABEL_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.IMS_REGISTRATION_STATE_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.MAX_PHONE_COUNT_SINGLE_SIM;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.NETWORK_PROVIDER_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.OPERATOR_INFO_LABEL_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.OPERATOR_INFO_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.ROAMING_INFO_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.SERVICE_STATE_VALUE_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.SIGNAL_STRENGTH_LABEL_ID;
|
||||
import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.SIGNAL_STRENGTH_VALUE_ID;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.CellSignalStrength;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.UiccCardInfo;
|
||||
import android.telephony.euicc.EuiccManager;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SimStatusDialogControllerTest {
|
||||
|
||||
@Mock
|
||||
private SimStatusDialogFragment mDialog;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
@Mock
|
||||
private SubscriptionInfo mSubscriptionInfo;
|
||||
@Mock
|
||||
private ServiceState mServiceState;
|
||||
@Mock
|
||||
private SignalStrength mSignalStrength;
|
||||
@Mock
|
||||
private CellSignalStrength mCellSignalStrengthCdma;
|
||||
@Mock
|
||||
private CellSignalStrength mCellSignalStrengthLte;
|
||||
@Mock
|
||||
private CellSignalStrength mCellSignalStrengthWcdma;
|
||||
@Mock
|
||||
private CarrierConfigManager mCarrierConfigManager;
|
||||
private PersistableBundle mPersistableBundle;
|
||||
@Mock
|
||||
private EuiccManager mEuiccManager;
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
|
||||
private SimStatusDialogController mController;
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Lifecycle mLifecycle;
|
||||
|
||||
private static final String TEST_EID_FROM_CARD = "11111111111111111111111111111111";
|
||||
private static final String TEST_EID_FROM_MANAGER = "22222222222222222222222222222222";
|
||||
|
||||
private static final int MAX_PHONE_COUNT_DUAL_SIM = 2;
|
||||
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mDialog.getContext()).thenReturn(mContext);
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
|
||||
mTelephonyManager = spy(mContext.getSystemService(TelephonyManager.class));
|
||||
mSubscriptionManager = spy(mContext.getSystemService(SubscriptionManager.class));
|
||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager)
|
||||
.getActiveSubscriptionInfoForSimSlotIndex(anyInt());
|
||||
|
||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
when(mContext.getSystemService(CarrierConfigManager.class)).thenReturn(
|
||||
mCarrierConfigManager);
|
||||
when(mContext.getSystemService(EuiccManager.class)).thenReturn(mEuiccManager);
|
||||
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
|
||||
|
||||
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
|
||||
anyInt());
|
||||
doReturn(2).when(mTelephonyManager).getCardIdForDefaultEuicc();
|
||||
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mTelephonyManager).getDataNetworkType();
|
||||
|
||||
mController = spy(new SimStatusDialogController(mDialog, mLifecycle, 0 /* phone id */));
|
||||
// CellSignalStrength setup
|
||||
doReturn(0).when(mCellSignalStrengthCdma).getDbm();
|
||||
doReturn(0).when(mCellSignalStrengthCdma).getAsuLevel();
|
||||
doReturn(0).when(mCellSignalStrengthLte).getDbm();
|
||||
doReturn(0).when(mCellSignalStrengthLte).getAsuLevel();
|
||||
doReturn(0).when(mCellSignalStrengthWcdma).getDbm();
|
||||
doReturn(0).when(mCellSignalStrengthWcdma).getAsuLevel();
|
||||
|
||||
doReturn(null).when(mSignalStrength).getCellSignalStrengths();
|
||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
|
||||
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
|
||||
doReturn(new ArrayList<UiccCardInfo>()).when(mTelephonyManager).getUiccCardsInfo();
|
||||
doReturn(new HashMap<Integer, Integer>()).when(mTelephonyManager)
|
||||
.getLogicalToPhysicalSlotMapping();
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(false);
|
||||
when(mEuiccManager.getEid()).thenReturn("");
|
||||
when(mEuiccManager.createForCardId(anyInt())).thenReturn(mEuiccManager);
|
||||
|
||||
mPersistableBundle = new PersistableBundle();
|
||||
when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mPersistableBundle);
|
||||
|
||||
mPersistableBundle.putBoolean(
|
||||
CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL, true);
|
||||
doReturn(mServiceState).when(mTelephonyManager).getServiceState();
|
||||
doReturn(mSignalStrength).when(mTelephonyManager).getSignalStrength();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateNetworkProviderWithFoobarCarrier_shouldUpdateCarrierWithFoobar() {
|
||||
final CharSequence carrierName = "foobar";
|
||||
doReturn(carrierName).when(mSubscriptionInfo).getCarrierName();
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).setText(NETWORK_PROVIDER_VALUE_ID, carrierName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_shouldUpdatePhoneNumber() {
|
||||
mController.initialize();
|
||||
|
||||
verify(mController).updatePhoneNumber();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateLatestAreaInfoWithCdmaPhone_shouldRemoveOperatorInfoSetting() {
|
||||
when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).removeSettingFromScreen(OPERATOR_INFO_LABEL_ID);
|
||||
verify(mDialog).removeSettingFromScreen(OPERATOR_INFO_VALUE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateServiceStateWithInService_shouldUpdateTextToBeCInService() {
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String inServiceText = ResourcesUtils.getResourcesString(
|
||||
mContext, "radioInfo_service_in");
|
||||
verify(mDialog).setText(SERVICE_STATE_VALUE_ID, inServiceText);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateServiceStateWithPowerOff_shouldUpdateTextAndResetSignalStrength() {
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_POWER_OFF);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String offServiceText = ResourcesUtils.getResourcesString(
|
||||
mContext, "radioInfo_service_off");
|
||||
verify(mDialog).setText(SERVICE_STATE_VALUE_ID, offServiceText);
|
||||
verify(mDialog).setText(SIGNAL_STRENGTH_VALUE_ID, "0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateVoiceDataOutOfService_shouldUpdateSettingAndResetSignalStrength() {
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
|
||||
when(mServiceState.getDataRegistrationState()).thenReturn(
|
||||
ServiceState.STATE_OUT_OF_SERVICE);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String offServiceText = ResourcesUtils.getResourcesString(
|
||||
mContext, "radioInfo_service_out");
|
||||
verify(mDialog).setText(SERVICE_STATE_VALUE_ID, offServiceText);
|
||||
verify(mDialog).setText(SIGNAL_STRENGTH_VALUE_ID, "0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateVoiceOutOfServiceDataInService_shouldUpdateTextToBeInService() {
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
|
||||
when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String inServiceText = ResourcesUtils.getResourcesString(
|
||||
mContext, "radioInfo_service_in");
|
||||
verify(mDialog).setText(SERVICE_STATE_VALUE_ID, inServiceText);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateSignalStrengthWithLte50Wcdma40_shouldUpdateSignalStrengthTo50() {
|
||||
final int lteDbm = 50;
|
||||
final int lteAsu = 50;
|
||||
final int wcdmaDbm = 40;
|
||||
final int wcdmaAsu = 40;
|
||||
setupCellSignalStrength_lteWcdma(lteDbm, lteAsu, wcdmaDbm, wcdmaAsu);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String signalStrengthString = ResourcesUtils.getResourcesString(
|
||||
mContext, "sim_signal_strength", lteDbm, lteAsu);
|
||||
verify(mDialog, times(2)).setText(SIGNAL_STRENGTH_VALUE_ID, signalStrengthString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateSignalStrengthWithLte50Cdma30_shouldUpdateSignalStrengthTo50() {
|
||||
final int lteDbm = 50;
|
||||
final int lteAsu = 50;
|
||||
final int cdmaDbm = 30;
|
||||
final int cdmaAsu = 30;
|
||||
setupCellSignalStrength_lteCdma(lteDbm, lteAsu, cdmaDbm, cdmaAsu);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String signalStrengthString = ResourcesUtils.getResourcesString(
|
||||
mContext, "sim_signal_strength", lteDbm, lteAsu);
|
||||
verify(mDialog, times(2)).setText(SIGNAL_STRENGTH_VALUE_ID, signalStrengthString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateVoiceOutOfServiceDataInService_shouldUpdateSignalStrengthTo50() {
|
||||
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
|
||||
when(mServiceState.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
|
||||
|
||||
final int lteDbm = 50;
|
||||
final int lteAsu = 50;
|
||||
setupCellSignalStrength_lteOnly(lteDbm, lteAsu);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String signalStrengthString = ResourcesUtils.getResourcesString(
|
||||
mContext, "sim_signal_strength", lteDbm, lteAsu);
|
||||
verify(mDialog, times(2)).setText(SIGNAL_STRENGTH_VALUE_ID, signalStrengthString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateVoiceNetworkTypeWithEdge_shouldUpdateSettingToEdge() {
|
||||
when(mTelephonyManager.getVoiceNetworkType()).thenReturn(
|
||||
TelephonyManager.NETWORK_TYPE_EDGE);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).setText(CELL_VOICE_NETWORK_TYPE_VALUE_ID,
|
||||
SimStatusDialogController.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_EDGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateDataNetworkTypeWithEdge_shouldUpdateSettingToEdge() {
|
||||
when(mTelephonyManager.getDataNetworkType()).thenReturn(
|
||||
TelephonyManager.NETWORK_TYPE_EDGE);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).setText(CELL_DATA_NETWORK_TYPE_VALUE_ID,
|
||||
SimStatusDialogController.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_EDGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateRoamingStatusIsRoaming_shouldSetSettingToRoaming() {
|
||||
when(mServiceState.getRoaming()).thenReturn(true);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String roamingOnString = ResourcesUtils.getResourcesString(
|
||||
mContext, "radioInfo_roaming_in");
|
||||
verify(mDialog).setText(ROAMING_INFO_VALUE_ID, roamingOnString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateRoamingStatusNotRoaming_shouldSetSettingToRoamingOff() {
|
||||
when(mServiceState.getRoaming()).thenReturn(false);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
final String roamingOffString = ResourcesUtils.getResourcesString(
|
||||
mContext, "radioInfo_roaming_not");
|
||||
verify(mDialog).setText(ROAMING_INFO_VALUE_ID, roamingOffString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_doNotShowIccid_shouldRemoveIccidSetting() {
|
||||
mPersistableBundle.putBoolean(
|
||||
CarrierConfigManager.KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL, false);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).removeSettingFromScreen(ICCID_INFO_LABEL_ID);
|
||||
verify(mDialog).removeSettingFromScreen(ICCID_INFO_VALUE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_doNotShowSignalStrength_shouldRemoveSignalStrengthSetting() {
|
||||
mPersistableBundle.putBoolean(
|
||||
CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL, false);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog, times(2)).removeSettingFromScreen(SIGNAL_STRENGTH_LABEL_ID);
|
||||
verify(mDialog, times(2)).removeSettingFromScreen(SIGNAL_STRENGTH_VALUE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_showSignalStrengthAndIccId_shouldShowSignalStrengthAndIccIdSetting() {
|
||||
// getConfigForSubId is nullable, so make sure the default behavior is correct
|
||||
when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(null);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog, times(2)).setText(eq(SIGNAL_STRENGTH_VALUE_ID), any());
|
||||
verify(mDialog).removeSettingFromScreen(ICCID_INFO_LABEL_ID);
|
||||
verify(mDialog).removeSettingFromScreen(ICCID_INFO_VALUE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_showIccid_shouldSetIccidToSetting() {
|
||||
final String iccid = "12351351231241";
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL, true);
|
||||
doReturn(iccid).when(mTelephonyManager).getSimSerialNumber();
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).setText(ICCID_INFO_VALUE_ID, iccid);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateEid_shouldNotSetEid() {
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
|
||||
|
||||
ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
|
||||
UiccCardInfo uiccCardInfo1 = new UiccCardInfo(
|
||||
false, // isEuicc
|
||||
0, // cardId
|
||||
null, // eid
|
||||
"123451234567890", // iccid
|
||||
0, // slotIndex
|
||||
true); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo1);
|
||||
UiccCardInfo uiccCardInfo2 = new UiccCardInfo(
|
||||
true, // isEuicc
|
||||
1, // cardId
|
||||
null, // eid (unavailable)
|
||||
null, // iccid
|
||||
1, // slotIndex
|
||||
false); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo2);
|
||||
when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
|
||||
|
||||
Map<Integer, Integer> slotMapping = new HashMap<>();
|
||||
slotMapping.put(0, 1);
|
||||
slotMapping.put(1, 0);
|
||||
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(true);
|
||||
when(mEuiccManager.getEid()).thenReturn(null);
|
||||
|
||||
doNothing().when(mController).requestForUpdateEid();
|
||||
mController.updateEid(mController.getEid(0));
|
||||
mController.initialize();
|
||||
|
||||
// Keep 'Not available' if neither the card nor the associated manager can provide EID.
|
||||
verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
|
||||
verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateEid_shouldSetEidFromCard() {
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
|
||||
|
||||
ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
|
||||
UiccCardInfo uiccCardInfo1 = new UiccCardInfo(
|
||||
true, // isEuicc
|
||||
0, // cardId
|
||||
TEST_EID_FROM_CARD, // eid
|
||||
null, // iccid
|
||||
0, // slotIndex
|
||||
false); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo1);
|
||||
UiccCardInfo uiccCardInfo2 = new UiccCardInfo(
|
||||
false, // isEuicc
|
||||
1, // cardId
|
||||
null, // eid
|
||||
"123451234567890", // iccid
|
||||
1, // slotIndex
|
||||
true); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo2);
|
||||
when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
|
||||
|
||||
Map<Integer, Integer> slotMapping = new HashMap<>();
|
||||
slotMapping.put(0, 0);
|
||||
slotMapping.put(1, 1);
|
||||
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(true);
|
||||
when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
|
||||
when(mEuiccManager.createForCardId(0)).thenReturn(mEuiccManager);
|
||||
|
||||
doNothing().when(mController).requestForUpdateEid();
|
||||
mController.updateEid(mController.getEid(0));
|
||||
mController.initialize();
|
||||
|
||||
// Set EID retrieved from the card.
|
||||
verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_CARD);
|
||||
verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateEid_shouldSetEidFromManager() {
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
|
||||
|
||||
ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
|
||||
UiccCardInfo uiccCardInfo1 = new UiccCardInfo(
|
||||
false, // isEuicc
|
||||
0, // cardId
|
||||
null, // eid
|
||||
"123451234567890", // iccid
|
||||
0, // slotIndex
|
||||
true); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo1);
|
||||
UiccCardInfo uiccCardInfo2 = new UiccCardInfo(
|
||||
true, // isEuicc
|
||||
1, // cardId
|
||||
null, // eid (unavailable)
|
||||
null, // iccid
|
||||
1, // slotIndex
|
||||
false); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo2);
|
||||
when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
|
||||
|
||||
Map<Integer, Integer> slotMapping = new HashMap<>();
|
||||
slotMapping.put(0, 1);
|
||||
slotMapping.put(1, 0);
|
||||
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(true);
|
||||
when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
|
||||
when(mEuiccManager.createForCardId(0)).thenThrow(
|
||||
new RuntimeException("Unexpected card ID was specified"));
|
||||
when(mEuiccManager.createForCardId(1)).thenReturn(mEuiccManager);
|
||||
|
||||
doNothing().when(mController).requestForUpdateEid();
|
||||
mController.updateEid(mController.getEid(0));
|
||||
mController.initialize();
|
||||
|
||||
// Set EID retrieved from the manager associated with the card which cannot provide EID.
|
||||
verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER);
|
||||
verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateEid_shouldRemoveEid() {
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_DUAL_SIM);
|
||||
|
||||
ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
|
||||
UiccCardInfo uiccCardInfo1 = new UiccCardInfo(
|
||||
false, // isEuicc
|
||||
0, // cardId
|
||||
null, // eid
|
||||
"123451234567890", // iccid
|
||||
0, // slotIndex
|
||||
true); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo1);
|
||||
UiccCardInfo uiccCardInfo2 = new UiccCardInfo(
|
||||
true, // isEuicc
|
||||
1, // cardId
|
||||
TEST_EID_FROM_CARD, // eid
|
||||
null, // iccid
|
||||
1, // slotIndex
|
||||
false); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo2);
|
||||
when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
|
||||
|
||||
Map<Integer, Integer> slotMapping = new HashMap<>();
|
||||
slotMapping.put(0, 0);
|
||||
slotMapping.put(1, 1);
|
||||
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(true);
|
||||
when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
|
||||
|
||||
doNothing().when(mController).requestForUpdateEid();
|
||||
mController.updateEid(mController.getEid(0));
|
||||
mController.initialize();
|
||||
|
||||
// Remove EID if the card is not eUICC.
|
||||
verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
|
||||
verify(mDialog).removeSettingFromScreen(eq(EID_INFO_LABEL_ID));
|
||||
verify(mDialog).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateEid_shouldNotSetEidInSingleSimMode() {
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
|
||||
|
||||
ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
|
||||
UiccCardInfo uiccCardInfo = new UiccCardInfo(
|
||||
true, // isEuicc
|
||||
0, // cardId
|
||||
TEST_EID_FROM_CARD, // eid (not used)
|
||||
null, // iccid
|
||||
0, // slotIndex
|
||||
false); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo);
|
||||
when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
|
||||
|
||||
Map<Integer, Integer> slotMapping = new HashMap<>();
|
||||
slotMapping.put(0, 0);
|
||||
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(true);
|
||||
when(mEuiccManager.getEid()).thenReturn(null);
|
||||
|
||||
doNothing().when(mController).requestForUpdateEid();
|
||||
mController.updateEid(mController.getEid(0));
|
||||
mController.initialize();
|
||||
|
||||
// Keep 'Not available' if the default eUICC manager cannot provide EID in Single SIM mode.
|
||||
verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
|
||||
verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateEid_shouldSetEidInSingleSimModeWithEnabledEuicc() {
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
|
||||
|
||||
ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
|
||||
UiccCardInfo uiccCardInfo = new UiccCardInfo(
|
||||
true, // isEuicc (eUICC slot is selected)
|
||||
0, // cardId
|
||||
TEST_EID_FROM_CARD, // eid (not used)
|
||||
null, // iccid
|
||||
0, // slotIndex
|
||||
false); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo);
|
||||
when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
|
||||
|
||||
Map<Integer, Integer> slotMapping = new HashMap<>();
|
||||
slotMapping.put(0, 0);
|
||||
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(true);
|
||||
when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
|
||||
when(mEuiccManager.createForCardId(anyInt())).thenThrow(
|
||||
new RuntimeException("EID shall be retrieved from the default eUICC manager"));
|
||||
|
||||
doNothing().when(mController).requestForUpdateEid();
|
||||
mController.updateEid(mController.getEid(0));
|
||||
mController.initialize();
|
||||
|
||||
// Set EID retrieved from the default eUICC manager in Single SIM mode.
|
||||
verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER);
|
||||
verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateEid_shouldSetEidInSingleSimModeWithDisabledEuicc() {
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
|
||||
|
||||
ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
|
||||
UiccCardInfo uiccCardInfo = new UiccCardInfo(
|
||||
false, // isEuicc (eUICC slot is not selected)
|
||||
0, // cardId
|
||||
null, // eid
|
||||
"123451234567890", // iccid
|
||||
0, // slotIndex
|
||||
true); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo);
|
||||
when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
|
||||
|
||||
Map<Integer, Integer> slotMapping = new HashMap<>();
|
||||
slotMapping.put(0, 0);
|
||||
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(true);
|
||||
when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER);
|
||||
when(mEuiccManager.createForCardId(anyInt())).thenThrow(
|
||||
new RuntimeException("EID shall be retrieved from the default eUICC manager"));
|
||||
|
||||
doNothing().when(mController).requestForUpdateEid();
|
||||
mController.updateEid(mController.getEid(0));
|
||||
mController.initialize();
|
||||
|
||||
// Set EID retrieved from the default eUICC manager in Single SIM mode.
|
||||
verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER);
|
||||
verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_updateEid_shouldRemoveEidInSingleSimMode() {
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM);
|
||||
|
||||
ArrayList<UiccCardInfo> uiccCardInfos = new ArrayList<>();
|
||||
UiccCardInfo uiccCardInfo = new UiccCardInfo(
|
||||
false, // isEuicc
|
||||
0, // cardId
|
||||
null, // eid
|
||||
"123451234567890", // iccid
|
||||
0, // slotIndex
|
||||
true); // isRemovable
|
||||
uiccCardInfos.add(uiccCardInfo);
|
||||
when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos);
|
||||
|
||||
Map<Integer, Integer> slotMapping = new HashMap<>();
|
||||
slotMapping.put(0, 0);
|
||||
when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping);
|
||||
|
||||
when(mEuiccManager.isEnabled()).thenReturn(false);
|
||||
when(mEuiccManager.getEid()).thenReturn(null);
|
||||
|
||||
doNothing().when(mController).requestForUpdateEid();
|
||||
mController.updateEid(mController.getEid(0));
|
||||
mController.initialize();
|
||||
|
||||
// Remove EID if the default eUICC manager indicates that eSIM is not enabled.
|
||||
verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any());
|
||||
verify(mDialog).removeSettingFromScreen(eq(EID_INFO_LABEL_ID));
|
||||
verify(mDialog).removeSettingFromScreen(eq(EID_INFO_VALUE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void initialize_imsRegistered_shouldSetImsRegistrationStateSummaryToRegisterd() {
|
||||
mPersistableBundle.putBoolean(
|
||||
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
|
||||
when(mTelephonyManager.isImsRegistered(anyInt())).thenReturn(true);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).setText(IMS_REGISTRATION_STATE_VALUE_ID,
|
||||
mContext.getString(R.string.ims_reg_status_registered));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void initialize_imsNotRegistered_shouldSetImsRegistrationStateSummaryToNotRegisterd() {
|
||||
mPersistableBundle.putBoolean(
|
||||
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
|
||||
when(mTelephonyManager.isImsRegistered(anyInt())).thenReturn(false);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).setText(IMS_REGISTRATION_STATE_VALUE_ID,
|
||||
mContext.getString(R.string.ims_reg_status_not_registered));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void initialize_showImsRegistration_shouldNotRemoveImsRegistrationStateSetting() {
|
||||
mPersistableBundle.putBoolean(
|
||||
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog, never()).removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void initialize_doNotShowImsRegistration_shouldRemoveImsRegistrationStateSetting() {
|
||||
mPersistableBundle.putBoolean(
|
||||
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
|
||||
|
||||
mController.initialize();
|
||||
|
||||
verify(mDialog).removeSettingFromScreen(IMS_REGISTRATION_STATE_LABEL_ID);
|
||||
verify(mDialog).removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_nullSignalStrength_noCrash() {
|
||||
doReturn(null).when(mTelephonyManager).getSignalStrength();
|
||||
// we should not crash when running the following line
|
||||
mController.initialize();
|
||||
}
|
||||
|
||||
private void setupCellSignalStrength_lteWcdma(int lteDbm, int lteAsu, int wcdmaDbm,
|
||||
int wcdmaAsu) {
|
||||
doReturn(lteDbm).when(mCellSignalStrengthLte).getDbm();
|
||||
doReturn(lteAsu).when(mCellSignalStrengthLte).getAsuLevel();
|
||||
doReturn(wcdmaDbm).when(mCellSignalStrengthWcdma).getDbm();
|
||||
doReturn(wcdmaAsu).when(mCellSignalStrengthWcdma).getAsuLevel();
|
||||
|
||||
List<CellSignalStrength> cellSignalStrengthList = new ArrayList<>(2);
|
||||
cellSignalStrengthList.add(mCellSignalStrengthLte);
|
||||
cellSignalStrengthList.add(mCellSignalStrengthWcdma);
|
||||
|
||||
doReturn(cellSignalStrengthList).when(mSignalStrength).getCellSignalStrengths();
|
||||
}
|
||||
|
||||
private void setupCellSignalStrength_lteCdma(int lteDbm, int lteAsu, int cdmaDbm, int cdmaAsu) {
|
||||
doReturn(lteDbm).when(mCellSignalStrengthLte).getDbm();
|
||||
doReturn(lteAsu).when(mCellSignalStrengthLte).getAsuLevel();
|
||||
doReturn(cdmaDbm).when(mCellSignalStrengthCdma).getDbm();
|
||||
doReturn(cdmaAsu).when(mCellSignalStrengthCdma).getAsuLevel();
|
||||
|
||||
List<CellSignalStrength> cellSignalStrengthList = new ArrayList<>(2);
|
||||
cellSignalStrengthList.add(mCellSignalStrengthLte);
|
||||
cellSignalStrengthList.add(mCellSignalStrengthCdma);
|
||||
|
||||
doReturn(cellSignalStrengthList).when(mSignalStrength).getCellSignalStrengths();
|
||||
}
|
||||
|
||||
private void setupCellSignalStrength_lteOnly(int lteDbm, int lteAsu) {
|
||||
doReturn(lteDbm).when(mCellSignalStrengthLte).getDbm();
|
||||
doReturn(lteAsu).when(mCellSignalStrengthLte).getAsuLevel();
|
||||
|
||||
List<CellSignalStrength> cellSignalStrengthList = new ArrayList<>(2);
|
||||
cellSignalStrengthList.add(mCellSignalStrengthLte);
|
||||
|
||||
doReturn(cellSignalStrengthList).when(mSignalStrength).getCellSignalStrengths();
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,9 @@ import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -30,20 +32,22 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.net.TrafficStats;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.applications.StorageStatsSource;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@@ -57,11 +61,11 @@ public class StorageAsyncLoaderTest {
|
||||
private static final int SECONDARY_USER_ID = 10;
|
||||
private static final String PACKAGE_NAME_1 = "com.blah.test";
|
||||
private static final String PACKAGE_NAME_2 = "com.blah.test2";
|
||||
private static final String PACKAGE_NAME_3 = "com.blah.test3";
|
||||
private static final long DEFAULT_QUOTA = 64 * TrafficStats.MB_IN_BYTES;
|
||||
|
||||
@Mock
|
||||
private StorageStatsSource mSource;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@@ -76,6 +80,7 @@ public class StorageAsyncLoaderTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mInfo = new ArrayList<>();
|
||||
mLoader = new StorageAsyncLoader(mContext, mUserManager, "id", mSource, mPackageManager);
|
||||
when(mPackageManager.getInstalledApplicationsAsUser(eq(PRIMARY_USER_ID), anyInt()))
|
||||
@@ -85,6 +90,10 @@ public class StorageAsyncLoaderTest {
|
||||
mUsers.add(info);
|
||||
when(mUserManager.getUsers()).thenReturn(mUsers);
|
||||
when(mSource.getCacheQuotaBytes(anyString(), anyInt())).thenReturn(DEFAULT_QUOTA);
|
||||
final Resources resources = spy(mContext.getResources());
|
||||
when(mContext.getResources()).thenReturn(resources);
|
||||
doReturn("content://com.android.providers.media.documents/root/videos_root")
|
||||
.when(resources).getString(R.string.config_videos_storage_category_uri);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,22 +101,22 @@ public class StorageAsyncLoaderTest {
|
||||
addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
|
||||
addPackage(PACKAGE_NAME_2, 0, 100, 1000, ApplicationInfo.CATEGORY_UNDEFINED);
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(PRIMARY_USER_ID).gamesSize).isEqualTo(0L);
|
||||
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(1111L);
|
||||
assertThat(result.get(PRIMARY_USER_ID).allAppsExceptGamesSize).isEqualTo(1111L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGamesAreFiltered() throws Exception {
|
||||
addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_GAME);
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(PRIMARY_USER_ID).gamesSize).isEqualTo(11L);
|
||||
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(0);
|
||||
assertThat(result.get(PRIMARY_USER_ID).allAppsExceptGamesSize).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -116,21 +125,21 @@ public class StorageAsyncLoaderTest {
|
||||
addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
|
||||
info.flags = ApplicationInfo.FLAG_IS_GAME;
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(PRIMARY_USER_ID).gamesSize).isEqualTo(11L);
|
||||
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(0);
|
||||
assertThat(result.get(PRIMARY_USER_ID).allAppsExceptGamesSize).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheIsNotIgnored() throws Exception {
|
||||
addPackage(PACKAGE_NAME_1, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(111L);
|
||||
assertThat(result.get(PRIMARY_USER_ID).allAppsExceptGamesSize).isEqualTo(111L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,7 +152,7 @@ public class StorageAsyncLoaderTest {
|
||||
when(mSource.getExternalStorageStats(anyString(), eq(new UserHandle(SECONDARY_USER_ID))))
|
||||
.thenReturn(new StorageStatsSource.ExternalStorageStats(10, 3, 3, 4, 0));
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(2);
|
||||
assertThat(result.get(PRIMARY_USER_ID).externalStats.totalBytes).isEqualTo(9L);
|
||||
@@ -156,21 +165,10 @@ public class StorageAsyncLoaderTest {
|
||||
addPackage(PACKAGE_NAME_1, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
|
||||
systemApp.flags = ApplicationInfo.FLAG_SYSTEM & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(111L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVideoAppsAreFiltered() throws Exception {
|
||||
addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_VIDEO);
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(PRIMARY_USER_ID).videoAppsSize).isEqualTo(11L);
|
||||
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(0);
|
||||
assertThat(result.get(PRIMARY_USER_ID).allAppsExceptGamesSize).isEqualTo(111L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -182,43 +180,32 @@ public class StorageAsyncLoaderTest {
|
||||
when(mSource.getStatsForPackage(anyString(), anyString(), any(UserHandle.class)))
|
||||
.thenThrow(new NameNotFoundException());
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
// Should not crash.
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageIsNotDoubleCounted() throws Exception {
|
||||
UserInfo info = new UserInfo();
|
||||
info.id = SECONDARY_USER_ID;
|
||||
mUsers.add(info);
|
||||
when(mSource.getExternalStorageStats(anyString(), eq(UserHandle.SYSTEM)))
|
||||
.thenReturn(new StorageStatsSource.ExternalStorageStats(9, 2, 3, 4, 0));
|
||||
when(mSource.getExternalStorageStats(anyString(), eq(new UserHandle(SECONDARY_USER_ID))))
|
||||
.thenReturn(new StorageStatsSource.ExternalStorageStats(10, 3, 3, 4, 0));
|
||||
addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_VIDEO);
|
||||
ArrayList<ApplicationInfo> secondaryUserApps = new ArrayList<>();
|
||||
ApplicationInfo appInfo = new ApplicationInfo();
|
||||
appInfo.packageName = PACKAGE_NAME_1;
|
||||
appInfo.category = ApplicationInfo.CATEGORY_VIDEO;
|
||||
secondaryUserApps.add(appInfo);
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(2);
|
||||
assertThat(result.get(PRIMARY_USER_ID).videoAppsSize).isEqualTo(11L);
|
||||
// No code size for the second user.
|
||||
assertThat(result.get(SECONDARY_USER_ID).videoAppsSize).isEqualTo(10L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheOveragesAreCountedAsFree() throws Exception {
|
||||
addPackage(PACKAGE_NAME_1, DEFAULT_QUOTA + 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
|
||||
|
||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(DEFAULT_QUOTA + 11);
|
||||
assertThat(result.get(PRIMARY_USER_ID).allAppsExceptGamesSize)
|
||||
.isEqualTo(DEFAULT_QUOTA + 11);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppsAreFiltered() throws Exception {
|
||||
addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_IMAGE);
|
||||
addPackage(PACKAGE_NAME_2, 0, 1, 10, ApplicationInfo.CATEGORY_VIDEO);
|
||||
addPackage(PACKAGE_NAME_3, 0, 1, 10, ApplicationInfo.CATEGORY_AUDIO);
|
||||
|
||||
SparseArray<StorageAsyncLoader.StorageResult> result = mLoader.loadInBackground();
|
||||
|
||||
assertThat(result.size()).isEqualTo(1);
|
||||
assertThat(result.get(PRIMARY_USER_ID).allAppsExceptGamesSize).isEqualTo(33L);
|
||||
}
|
||||
|
||||
private ApplicationInfo addPackage(String packageName, long cacheSize, long codeSize,
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.storage.DiskInfo;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.os.storage.VolumeRecord;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class StorageEntryTest {
|
||||
|
||||
private static final String VOLUME_INFO_ID = "volume_info_id";
|
||||
private static final String DISK_INFO_ID = "disk_info_id";
|
||||
private static final String VOLUME_RECORD_UUID = "volume_record_id";
|
||||
|
||||
@Mock
|
||||
private VolumeInfo mVolumeInfo;
|
||||
@Mock
|
||||
private DiskInfo mDiskInfo;
|
||||
@Mock
|
||||
private VolumeRecord mVolumeRecord;
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private StorageManager mStorageManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equals_volumesOfSameId_shouldBeTheSame() {
|
||||
final StorageEntry volumeStorage1 = new StorageEntry(mContext,
|
||||
new VolumeInfo(VOLUME_INFO_ID, 0 /* type */, null /* disk */, null /* partGuid */));
|
||||
final StorageEntry volumeStorage2 = new StorageEntry(mContext,
|
||||
new VolumeInfo(VOLUME_INFO_ID, 0 /* type */, null /* disk */, null /* partGuid */));
|
||||
final StorageEntry diskStorage1 =
|
||||
new StorageEntry(new DiskInfo(DISK_INFO_ID, 0 /* flags */));
|
||||
final StorageEntry diskStorage2 =
|
||||
new StorageEntry(new DiskInfo(DISK_INFO_ID, 0 /* flags */));
|
||||
final StorageEntry volumeRecordStorage1 = new StorageEntry(new VolumeRecord(0 /* flags */,
|
||||
VOLUME_RECORD_UUID));
|
||||
final StorageEntry volumeRecordStorage2 = new StorageEntry(new VolumeRecord(0 /* flags */,
|
||||
VOLUME_RECORD_UUID));
|
||||
|
||||
assertThat(Objects.equals(volumeStorage1, volumeStorage2)).isTrue();
|
||||
assertThat(Objects.equals(diskStorage1, diskStorage2)).isTrue();
|
||||
assertThat(Objects.equals(volumeRecordStorage1, volumeRecordStorage2)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equals_volumesOfDifferentId_shouldBeDifferent() {
|
||||
final StorageEntry volumeStorage1 = new StorageEntry(mContext,
|
||||
new VolumeInfo(VOLUME_INFO_ID, 0 /* type */, null /* disk */, null /* partGuid */));
|
||||
final StorageEntry volumeStorage2 = new StorageEntry(mContext,
|
||||
new VolumeInfo("id2", 0 /* type */, null /* disk */, null /* partGuid */));
|
||||
final StorageEntry diskStorage1 =
|
||||
new StorageEntry(new DiskInfo(DISK_INFO_ID, 0 /* flags */));
|
||||
final StorageEntry diskStorage2 =
|
||||
new StorageEntry(new DiskInfo("id2", 0 /* flags */));
|
||||
final StorageEntry volumeRecordStorage1 = new StorageEntry(new VolumeRecord(0 /* flags */,
|
||||
VOLUME_RECORD_UUID));
|
||||
final StorageEntry volumeRecordStorage2 = new StorageEntry(new VolumeRecord(0 /* flags */,
|
||||
"id2"));
|
||||
|
||||
assertThat(Objects.equals(volumeStorage1, volumeStorage2)).isFalse();
|
||||
assertThat(Objects.equals(diskStorage1, diskStorage2)).isFalse();
|
||||
assertThat(Objects.equals(volumeRecordStorage1, volumeRecordStorage2)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareTo_defaultInternalStorage_shouldBeAtTopMost() {
|
||||
final StorageEntry storage1 = mock(StorageEntry.class);
|
||||
when(storage1.isDefaultInternalStorage()).thenReturn(true);
|
||||
final StorageEntry storage2 = mock(StorageEntry.class);
|
||||
when(storage2.isDefaultInternalStorage()).thenReturn(false);
|
||||
|
||||
assertThat(storage1.compareTo(storage2) > 0).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDefaultInternalStorageEntry_shouldReturnVolumeInfoStorageOfIdPrivateInternal() {
|
||||
final VolumeInfo volumeInfo = mock(VolumeInfo.class);
|
||||
when(mStorageManager.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL)).thenReturn(volumeInfo);
|
||||
|
||||
assertThat(StorageEntry.getDefaultInternalStorageEntry(mContext))
|
||||
.isEqualTo(new StorageEntry(mContext, volumeInfo));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isVolumeInfo_shouldReturnTrueForVolumeInfo() {
|
||||
final VolumeInfo volumeInfo = mock(VolumeInfo.class);
|
||||
final StorageEntry storage = new StorageEntry(mContext, volumeInfo);
|
||||
|
||||
assertThat(storage.isVolumeInfo()).isTrue();
|
||||
assertThat(storage.isDiskInfoUnsupported()).isFalse();
|
||||
assertThat(storage.isVolumeRecordMissed()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isDiskInfoUnsupported_shouldReturnTrueForDiskInfo() {
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry storage = new StorageEntry(diskInfo);
|
||||
|
||||
assertThat(storage.isVolumeInfo()).isFalse();
|
||||
assertThat(storage.isDiskInfoUnsupported()).isTrue();
|
||||
assertThat(storage.isVolumeRecordMissed()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isVolumeRecordMissed_shouldReturnTrueForVolumeRecord() {
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry storage = new StorageEntry(volumeRecord);
|
||||
|
||||
assertThat(storage.isVolumeInfo()).isFalse();
|
||||
assertThat(storage.isDiskInfoUnsupported()).isFalse();
|
||||
assertThat(storage.isVolumeRecordMissed()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isMounted_mountedOrMountedReadOnly_shouldReturnTrue() {
|
||||
final VolumeInfo mountedVolumeInfo1 = mock(VolumeInfo.class);
|
||||
final StorageEntry mountedStorage1 = new StorageEntry(mContext, mountedVolumeInfo1);
|
||||
when(mountedVolumeInfo1.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
|
||||
final VolumeInfo mountedVolumeInfo2 = mock(VolumeInfo.class);
|
||||
when(mountedVolumeInfo2.getState()).thenReturn(VolumeInfo.STATE_MOUNTED_READ_ONLY);
|
||||
final StorageEntry mountedStorage2 = new StorageEntry(mContext, mountedVolumeInfo2);
|
||||
|
||||
assertThat(mountedStorage1.isMounted()).isTrue();
|
||||
assertThat(mountedStorage2.isMounted()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isMounted_nonVolumeInfo_shouldReturnFalse() {
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry diskStorage = new StorageEntry(diskInfo);
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry recordStorage2 = new StorageEntry(volumeRecord);
|
||||
|
||||
assertThat(diskStorage.isMounted()).isFalse();
|
||||
assertThat(recordStorage2.isMounted()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUnmountable_unmountableVolume_shouldReturnTrue() {
|
||||
final VolumeInfo unmountableVolumeInfo = mock(VolumeInfo.class);
|
||||
final StorageEntry mountedStorage = new StorageEntry(mContext, unmountableVolumeInfo);
|
||||
when(unmountableVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_UNMOUNTABLE);
|
||||
|
||||
assertThat(mountedStorage.isUnmountable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUnmountable_nonVolumeInfo_shouldReturnFalse() {
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry diskStorage = new StorageEntry(diskInfo);
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry recordStorage2 = new StorageEntry(volumeRecord);
|
||||
|
||||
assertThat(diskStorage.isUnmountable()).isFalse();
|
||||
assertThat(recordStorage2.isUnmountable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPrivate_privateVolume_shouldReturnTrue() {
|
||||
final VolumeInfo privateVolumeInfo = mock(VolumeInfo.class);
|
||||
final StorageEntry privateStorage = new StorageEntry(mContext, privateVolumeInfo);
|
||||
when(privateVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
|
||||
|
||||
assertThat(privateStorage.isPrivate()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPublic_prublicVolume_shouldReturnTrue() {
|
||||
final VolumeInfo publicVolumeInfo = mock(VolumeInfo.class);
|
||||
final StorageEntry publicStorage = new StorageEntry(mContext, publicVolumeInfo);
|
||||
when(publicVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
|
||||
|
||||
assertThat(publicStorage.isPublic()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPrivate_nonVolumeInfo_shouldReturnFalse() {
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry diskStorage = new StorageEntry(diskInfo);
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry recordStorage2 = new StorageEntry(volumeRecord);
|
||||
|
||||
assertThat(diskStorage.isPrivate()).isFalse();
|
||||
assertThat(recordStorage2.isPrivate()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDescription_shouldReturnDescription() {
|
||||
final String description = "description";
|
||||
final VolumeInfo volumeInfo = mock(VolumeInfo.class);
|
||||
when(mStorageManager.getBestVolumeDescription(volumeInfo)).thenReturn(description);
|
||||
final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry diskStorage = new StorageEntry(diskInfo);
|
||||
when(diskInfo.getDescription()).thenReturn(description);
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry recordStorage = new StorageEntry(volumeRecord);
|
||||
when(volumeRecord.getNickname()).thenReturn(description);
|
||||
|
||||
assertThat(volumeStorage.getDescription()).isEqualTo(description);
|
||||
assertThat(diskStorage.getDescription()).isEqualTo(description);
|
||||
assertThat(recordStorage.getDescription()).isEqualTo(description);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDescription_defaultInternalStorage_returnThisDevice() {
|
||||
final VolumeInfo volumeInfo = mock(VolumeInfo.class);
|
||||
when(volumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
|
||||
when(volumeInfo.getId()).thenReturn(VolumeInfo.ID_PRIVATE_INTERNAL);
|
||||
final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
|
||||
|
||||
assertThat(volumeStorage.getDescription()).isEqualTo(
|
||||
ResourcesUtils.getResourcesString(mContext, "storage_default_internal_storage"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDiskId_shouldReturnDiskId() {
|
||||
final VolumeInfo volumeInfo = mock(VolumeInfo.class);
|
||||
final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
|
||||
when(volumeInfo.getDiskId()).thenReturn(VOLUME_INFO_ID);
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry diskStorage = new StorageEntry(diskInfo);
|
||||
when(diskInfo.getId()).thenReturn(DISK_INFO_ID);
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry recordStorage = new StorageEntry(volumeRecord);
|
||||
|
||||
assertThat(volumeStorage.getDiskId()).isEqualTo(VOLUME_INFO_ID);
|
||||
assertThat(diskStorage.getDiskId()).isEqualTo(DISK_INFO_ID);
|
||||
assertThat(recordStorage.getDiskId()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFsUuid_shouldReturnFsUuid() {
|
||||
final VolumeInfo volumeInfo = mock(VolumeInfo.class);
|
||||
final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
|
||||
when(volumeInfo.getFsUuid()).thenReturn(VOLUME_INFO_ID);
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry diskStorage = new StorageEntry(diskInfo);
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry recordStorage = new StorageEntry(volumeRecord);
|
||||
when(volumeRecord.getFsUuid()).thenReturn(VOLUME_RECORD_UUID);
|
||||
|
||||
assertThat(volumeStorage.getFsUuid()).isEqualTo(VOLUME_INFO_ID);
|
||||
assertThat(diskStorage.getFsUuid()).isEqualTo(null);
|
||||
assertThat(recordStorage.getFsUuid()).isEqualTo(VOLUME_RECORD_UUID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPath_shouldReturnPath() {
|
||||
final File file = new File("fakePath");
|
||||
final VolumeInfo volumeInfo = mock(VolumeInfo.class);
|
||||
final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
|
||||
when(volumeInfo.getPath()).thenReturn(file);
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry diskStorage = new StorageEntry(diskInfo);
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry recordStorage = new StorageEntry(volumeRecord);
|
||||
|
||||
assertThat(volumeStorage.getPath()).isEqualTo(file);
|
||||
assertThat(diskStorage.getPath()).isEqualTo(null);
|
||||
assertThat(recordStorage.getPath()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getVolumeInfo_shouldVolumeInfo() {
|
||||
final VolumeInfo volumeInfo = mock(VolumeInfo.class);
|
||||
final StorageEntry volumeStorage = new StorageEntry(mContext, volumeInfo);
|
||||
final DiskInfo diskInfo = mock(DiskInfo.class);
|
||||
final StorageEntry diskStorage = new StorageEntry(diskInfo);
|
||||
final VolumeRecord volumeRecord = mock(VolumeRecord.class);
|
||||
final StorageEntry recordStorage = new StorageEntry(volumeRecord);
|
||||
|
||||
assertThat(volumeStorage.getVolumeInfo()).isEqualTo(volumeInfo);
|
||||
assertThat(diskStorage.getVolumeInfo()).isEqualTo(null);
|
||||
assertThat(recordStorage.getVolumeInfo()).isEqualTo(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.Mockito.mock;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.os.storage.StorageManager;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.widget.SettingsSpinnerPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class StorageSelectionPreferenceControllerTest {
|
||||
|
||||
private static final String PREFERENCE_KEY = "preference_key";
|
||||
|
||||
private Context mContext;
|
||||
private StorageManager mStorageManager;
|
||||
private StorageSelectionPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
mStorageManager = mContext.getSystemService(StorageManager.class);
|
||||
mController = new StorageSelectionPreferenceController(mContext, PREFERENCE_KEY);
|
||||
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
final PreferenceScreen preferenceScreen =
|
||||
preferenceManager.createPreferenceScreen(mContext);
|
||||
final SettingsSpinnerPreference spinnerPreference = new SettingsSpinnerPreference(mContext);
|
||||
spinnerPreference.setKey(PREFERENCE_KEY);
|
||||
preferenceScreen.addPreference(spinnerPreference);
|
||||
mController.displayPreference(preferenceScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setStorageEntries_fromStorageManager_correctAdapterItems() {
|
||||
final List<StorageEntry> storageEntries = mStorageManager.getVolumes().stream()
|
||||
.map(volumeInfo -> new StorageEntry(mContext, volumeInfo))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
mController.setStorageEntries(storageEntries);
|
||||
|
||||
final int adapterItemCount = mController.mStorageAdapter.getCount();
|
||||
assertThat(adapterItemCount).isEqualTo(storageEntries.size());
|
||||
for (int i = 0; i < adapterItemCount; i++) {
|
||||
assertThat(storageEntries.get(i).getDescription())
|
||||
.isEqualTo(mController.mStorageAdapter.getItem(i).getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSelectedStorageEntry_primaryStorage_correctSelectedAdapterItem() {
|
||||
final StorageEntry primaryStorageEntry =
|
||||
StorageEntry.getDefaultInternalStorageEntry(mContext);
|
||||
mController.setStorageEntries(mStorageManager.getVolumes().stream()
|
||||
.map(volumeInfo -> new StorageEntry(mContext, volumeInfo))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
mController.setSelectedStorageEntry(primaryStorageEntry);
|
||||
|
||||
assertThat((StorageEntry) mController.mSpinnerPreference.getSelectedItem())
|
||||
.isEqualTo(primaryStorageEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setStorageEntries_1StorageEntry_preferenceInvisible() {
|
||||
final List<StorageEntry> storageEntries = new ArrayList<>();
|
||||
storageEntries.add(mock(StorageEntry.class));
|
||||
|
||||
mController.setStorageEntries(storageEntries);
|
||||
|
||||
assertThat(mController.mSpinnerPreference.isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setStorageEntries_2StorageEntries_preferenceVisible() {
|
||||
final List<StorageEntry> storageEntries = new ArrayList<>();
|
||||
storageEntries.add(mock(StorageEntry.class));
|
||||
storageEntries.add(mock(StorageEntry.class));
|
||||
|
||||
mController.setStorageEntries(storageEntries);
|
||||
|
||||
assertThat(mController.mSpinnerPreference.isVisible()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.usage.StorageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.widget.UsageProgressBarPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class StorageUsageProgressBarPreferenceControllerTest {
|
||||
|
||||
private static final String FAKE_UUID = "95D9-B3A4";
|
||||
private static final long WAIT_TIMEOUT = 10_000L;
|
||||
private static final long FREE_BYTES = 123L;
|
||||
private static final long TOTAL_BYTES = 456L;
|
||||
private static final long USAGE_BYTES = TOTAL_BYTES - FREE_BYTES;
|
||||
|
||||
private Context mContext;
|
||||
private FakeStorageUsageProgressBarPreferenceController mController;
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock
|
||||
private StorageStatsManager mStorageStatsManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getSystemService(StorageStatsManager.class)).thenReturn(mStorageStatsManager);
|
||||
mController = new FakeStorageUsageProgressBarPreferenceController(mContext, "key");
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
mPreferenceScreen = preferenceManager.createPreferenceScreen(mContext);
|
||||
final UsageProgressBarPreference usageProgressBarPreference =
|
||||
new UsageProgressBarPreference(mContext);
|
||||
usageProgressBarPreference.setKey(mController.getPreferenceKey());
|
||||
mPreferenceScreen.addPreference(usageProgressBarPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSelectedStorageEntry_primaryStorage_getPrimaryStorageBytes() throws IOException {
|
||||
final StorageEntry defaultInternalStorageEntry =
|
||||
StorageEntry.getDefaultInternalStorageEntry(mContext);
|
||||
when(mStorageStatsManager.getTotalBytes(defaultInternalStorageEntry.getFsUuid()))
|
||||
.thenReturn(TOTAL_BYTES);
|
||||
when(mStorageStatsManager.getFreeBytes(defaultInternalStorageEntry.getFsUuid()))
|
||||
.thenReturn(FREE_BYTES);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
|
||||
synchronized (mController.mLock) {
|
||||
mController.setSelectedStorageEntry(defaultInternalStorageEntry);
|
||||
mController.waitUpdateState(WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
assertThat(mController.mUsedBytes).isEqualTo(USAGE_BYTES);
|
||||
assertThat(mController.mTotalBytes).isEqualTo(TOTAL_BYTES);
|
||||
}
|
||||
|
||||
private class FakeStorageUsageProgressBarPreferenceController
|
||||
extends StorageUsageProgressBarPreferenceController {
|
||||
private final Object mLock = new Object();
|
||||
|
||||
FakeStorageUsageProgressBarPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
try {
|
||||
mLock.notifyAll();
|
||||
} catch (IllegalMonitorStateException e) {
|
||||
// Catch it for displayPreference to prevent exception by object not locked by
|
||||
// thread before notify. Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
public void waitUpdateState(long timeout) {
|
||||
try {
|
||||
mLock.wait(timeout);
|
||||
} catch (InterruptedException e) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.display;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.display.ColorDisplayManager;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
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 ColorModePreferenceControllerTest {
|
||||
|
||||
private Preference mPreference;
|
||||
private ColorModePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
final Context context = spy(ApplicationProvider.getApplicationContext());
|
||||
mController = spy(new ColorModePreferenceController(context, "test"));
|
||||
mPreference = new Preference(context);
|
||||
final Resources res = spy(context.getResources());
|
||||
when(res.getIntArray(com.android.internal.R.array.config_availableColorModes)).thenReturn(
|
||||
new int[]{
|
||||
ColorDisplayManager.COLOR_MODE_NATURAL,
|
||||
ColorDisplayManager.COLOR_MODE_BOOSTED,
|
||||
ColorDisplayManager.COLOR_MODE_SATURATED,
|
||||
ColorDisplayManager.COLOR_MODE_AUTOMATIC
|
||||
});
|
||||
doReturn(res).when(context).getResources();
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void updateState_colorModeAutomatic_shouldSetSummaryToAutomatic() {
|
||||
doReturn(ColorDisplayManager.COLOR_MODE_AUTOMATIC).when(mController).getColorMode();
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo("Adaptive");
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void updateState_colorModeSaturated_shouldSetSummaryToSaturated() {
|
||||
doReturn(ColorDisplayManager.COLOR_MODE_SATURATED).when(mController).getColorMode();
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo("Saturated");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_colorModeBoosted_shouldSetSummaryToBoosted() {
|
||||
doReturn(ColorDisplayManager.COLOR_MODE_BOOSTED).when(mController).getColorMode();
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo("Boosted");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_colorModeNatural_shouldSetSummaryToNatural() {
|
||||
doReturn(ColorDisplayManager.COLOR_MODE_NATURAL).when(mController).getColorMode();
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo("Natural");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.display;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.display.ColorDisplayManager;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settingslib.widget.CandidateInfo;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ColorModePreferenceFragmentTest {
|
||||
|
||||
private ColorModePreferenceFragment mFragment;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setup() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
mFragment = spy(new ColorModePreferenceFragment());
|
||||
doNothing().when(mFragment).setColorMode(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyMetricsConstant() {
|
||||
assertThat(mFragment.getMetricsCategory())
|
||||
.isEqualTo(MetricsProto.MetricsEvent.COLOR_MODE_SETTINGS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getCandidates_all() {
|
||||
final Resources res = spy(mContext.getResources());
|
||||
when(res.getIntArray(com.android.internal.R.array.config_availableColorModes)).thenReturn(
|
||||
new int[]{
|
||||
ColorDisplayManager.COLOR_MODE_NATURAL,
|
||||
ColorDisplayManager.COLOR_MODE_BOOSTED,
|
||||
ColorDisplayManager.COLOR_MODE_SATURATED,
|
||||
ColorDisplayManager.COLOR_MODE_AUTOMATIC
|
||||
});
|
||||
doReturn(res).when(mContext).getResources();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
final List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(4);
|
||||
assertThat(candidates.get(0).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_NATURAL));
|
||||
assertThat(candidates.get(1).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED));
|
||||
assertThat(candidates.get(2).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_SATURATED));
|
||||
assertThat(candidates.get(3).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getCandidates_none() {
|
||||
final Resources res = spy(mContext.getResources());
|
||||
when(res.getIntArray(com.android.internal.R.array.config_availableColorModes)).thenReturn(
|
||||
new int[]{
|
||||
});
|
||||
doReturn(res).when(mContext).getResources();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getCandidates_withAutomatic() {
|
||||
final Resources res = spy(mContext.getResources());
|
||||
when(res.getIntArray(com.android.internal.R.array.config_availableColorModes)).thenReturn(
|
||||
new int[]{
|
||||
ColorDisplayManager.COLOR_MODE_NATURAL,
|
||||
ColorDisplayManager.COLOR_MODE_AUTOMATIC
|
||||
});
|
||||
doReturn(res).when(mContext).getResources();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(2);
|
||||
assertThat(candidates.get(0).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_NATURAL));
|
||||
assertThat(candidates.get(1).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getCandidates_withoutAutomatic() {
|
||||
final Resources res = spy(mContext.getResources());
|
||||
when(res.getIntArray(com.android.internal.R.array.config_availableColorModes)).thenReturn(
|
||||
new int[]{
|
||||
ColorDisplayManager.COLOR_MODE_NATURAL,
|
||||
ColorDisplayManager.COLOR_MODE_BOOSTED,
|
||||
ColorDisplayManager.COLOR_MODE_SATURATED
|
||||
});
|
||||
doReturn(res).when(mContext).getResources();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(3);
|
||||
assertThat(candidates.get(0).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_NATURAL));
|
||||
assertThat(candidates.get(1).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED));
|
||||
assertThat(candidates.get(2).getKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_SATURATED));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getKey_natural() {
|
||||
doReturn(ColorDisplayManager.COLOR_MODE_NATURAL).when(mFragment).getColorMode();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_NATURAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getKey_boosted() {
|
||||
doReturn(ColorDisplayManager.COLOR_MODE_BOOSTED).when(mFragment).getColorMode();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getKey_saturated() {
|
||||
doReturn(ColorDisplayManager.COLOR_MODE_SATURATED).when(mFragment).getColorMode();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_SATURATED));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getKey_automatic() {
|
||||
doReturn(ColorDisplayManager.COLOR_MODE_AUTOMATIC).when(mFragment).getColorMode();
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void setKey_natural() {
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
mFragment.setDefaultKey(
|
||||
mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_NATURAL));
|
||||
|
||||
verify(mFragment).setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void setKey_boosted() {
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
mFragment.setDefaultKey(
|
||||
mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED));
|
||||
|
||||
verify(mFragment).setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void setKey_saturated() {
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
mFragment.setDefaultKey(
|
||||
mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_SATURATED));
|
||||
|
||||
verify(mFragment).setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void setKey_automatic() {
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
mFragment.setDefaultKey(
|
||||
mFragment.getKeyForColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC));
|
||||
|
||||
verify(mFragment).setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.display;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.Settings.NightDisplaySettingsActivity;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class NightDisplaySettingsActivityTest {
|
||||
|
||||
private Context mTargetContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mTargetContext = instrumentation.getTargetContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nightDisplaySettingsIntent_resolvesCorrectly() {
|
||||
final boolean nightDisplayAvailable = mTargetContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_nightDisplayAvailable);
|
||||
final PackageManager pm = mTargetContext.getPackageManager();
|
||||
final Intent intent = new Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS);
|
||||
final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
|
||||
if (nightDisplayAvailable) {
|
||||
Assert.assertNotNull("No activity for " + Settings.ACTION_NIGHT_DISPLAY_SETTINGS, ri);
|
||||
Assert.assertEquals(mTargetContext.getPackageName(), ri.activityInfo.packageName);
|
||||
Assert.assertEquals(NightDisplaySettingsActivity.class.getName(),
|
||||
ri.activityInfo.name);
|
||||
} else {
|
||||
Assert.assertNull("Should have no activity for "
|
||||
+ Settings.ACTION_NIGHT_DISPLAY_SETTINGS, ri);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.display;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.om.IOverlayManager;
|
||||
import android.content.om.OverlayInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ThemePreferenceControllerTest {
|
||||
|
||||
private IOverlayManager mMockOverlayManager;
|
||||
private ContextWrapper mContext;
|
||||
private ThemePreferenceController mPreferenceController;
|
||||
private PackageManager mMockPackageManager;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mMockOverlayManager = mock(IOverlayManager.class);
|
||||
mMockPackageManager = mock(PackageManager.class);
|
||||
mContext = new ContextWrapper(InstrumentationRegistry.getTargetContext()) {
|
||||
@Override
|
||||
public PackageManager getPackageManager() {
|
||||
return mMockPackageManager;
|
||||
}
|
||||
};
|
||||
mPreferenceController = new ThemePreferenceController(mContext, mMockOverlayManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState() throws Exception {
|
||||
OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android", "",
|
||||
OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
|
||||
OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android", "",
|
||||
OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
|
||||
when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenAnswer(inv -> {
|
||||
ApplicationInfo info = mock(ApplicationInfo.class);
|
||||
if ("com.android.Theme1".equals(inv.getArguments()[0])) {
|
||||
when(info.loadLabel(any())).thenReturn("Theme1");
|
||||
} else {
|
||||
when(info.loadLabel(any())).thenReturn("Theme2");
|
||||
}
|
||||
return info;
|
||||
});
|
||||
when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
|
||||
new PackageInfo());
|
||||
when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
|
||||
list(info1, info2));
|
||||
ListPreference pref = mock(ListPreference.class);
|
||||
mPreferenceController.updateState(pref);
|
||||
ArgumentCaptor<String[]> arg = ArgumentCaptor.forClass(String[].class);
|
||||
verify(pref).setEntries(arg.capture());
|
||||
|
||||
|
||||
CharSequence[] entries = arg.getValue();
|
||||
assertThat(entries).asList().containsExactly("Theme1", "Theme2");
|
||||
|
||||
verify(pref).setEntryValues(arg.capture());
|
||||
CharSequence[] entryValues = arg.getValue();
|
||||
assertThat(entryValues).asList().containsExactly(
|
||||
"com.android.Theme1", "com.android.Theme2");
|
||||
|
||||
verify(pref).setValue(eq("com.android.Theme1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_withStaticOverlay() throws Exception {
|
||||
OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android", "",
|
||||
OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
|
||||
OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android", "",
|
||||
OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
|
||||
when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenAnswer(inv -> {
|
||||
ApplicationInfo info = mock(ApplicationInfo.class);
|
||||
if ("com.android.Theme1".equals(inv.getArguments()[0])) {
|
||||
when(info.loadLabel(any())).thenReturn("Theme1");
|
||||
} else {
|
||||
when(info.loadLabel(any())).thenReturn("Theme2");
|
||||
}
|
||||
return info;
|
||||
});
|
||||
PackageInfo pi = mock(PackageInfo.class);
|
||||
when(pi.isStaticOverlayPackage()).thenReturn(true);
|
||||
when(mMockPackageManager.getPackageInfo(eq("com.android.Theme1"), anyInt())).thenReturn(pi);
|
||||
when(mMockPackageManager.getPackageInfo(eq("com.android.Theme2"), anyInt())).thenReturn(
|
||||
new PackageInfo());
|
||||
when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
|
||||
list(info1, info2));
|
||||
ListPreference pref = mock(ListPreference.class);
|
||||
mPreferenceController.updateState(pref);
|
||||
ArgumentCaptor<String[]> arg = ArgumentCaptor.forClass(String[].class);
|
||||
verify(pref).setEntries(arg.capture());
|
||||
|
||||
|
||||
CharSequence[] entries = arg.getValue();
|
||||
assertThat(entries).asList().containsExactly("Theme2");
|
||||
|
||||
verify(pref).setEntryValues(arg.capture());
|
||||
CharSequence[] entryValues = arg.getValue();
|
||||
assertThat(entryValues).asList().containsExactly("com.android.Theme2");
|
||||
|
||||
verify(pref).setValue(eq("com.android.Theme2"));
|
||||
}
|
||||
|
||||
private ArrayList<OverlayInfo> list(OverlayInfo... infos) {
|
||||
ArrayList<OverlayInfo> list = new ArrayList<>();
|
||||
for (OverlayInfo info : infos) {
|
||||
list.add(info);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user