fix: 引入Settings的Module

This commit is contained in:
2024-12-10 14:57:24 +08:00
parent ad8fc8731d
commit df105485bd
6934 changed files with 896168 additions and 2 deletions

View File

@@ -0,0 +1,70 @@
/*
* 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;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.telephony.TelephonyManager;
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 org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowSettings;
@RunWith(AndroidJUnit4.class)
public final class AirplaneModeEnablerTest {
private Context mContext;
@Mock
private AirplaneModeChangedListener mAirplaneModeChangedListener;
private AirplaneModeEnabler mAirplaneModeEnabler;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application.getBaseContext();
mAirplaneModeEnabler = new AirplaneModeEnabler(mContext,
mAirplaneModeChangedListener);
}
@Test
public void onRadioPowerStateChanged_beenInvoke_invokeOnAirplaneModeChanged() {
mAirplaneModeEnabler.start();
ShadowSettings.setAirplaneMode(true);
mAirplaneModeEnabler.mPhoneStateListener.onRadioPowerStateChanged(
TelephonyManager.RADIO_POWER_OFF);
verify(mAirplaneModeChangedListener, times(1)).onAirplaneModeChanged(true);
}
private class AirplaneModeChangedListener
implements AirplaneModeEnabler.OnAirplaneModeChangedListener {
public void onAirplaneModeChanged(boolean isAirplaneModeOn) {}
}
}

View File

@@ -0,0 +1,38 @@
package com.android.settings;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class DisplaySettingsTest {
@Test
public void testPreferenceControllers_getPreferenceKeys_existInPreferenceScreen() {
final Context context = ApplicationProvider.getApplicationContext();
final DisplaySettings fragment = new DisplaySettings();
final List<String> preferenceScreenKeys = XmlTestUtils.getKeysFromPreferenceXml(context,
fragment.getPreferenceScreenResId());
final List<String> preferenceKeys = new ArrayList<>();
for (AbstractPreferenceController controller : fragment.createPreferenceControllers(context)) {
preferenceKeys.add(controller.getPreferenceKey());
}
// Nightmode is currently hidden
preferenceKeys.remove("night_mode");
assertThat(preferenceScreenKeys).containsAtLeastElementsIn(preferenceKeys);
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import android.content.Intent;
import com.android.settings.testutils.shadow.ShadowHelpUtils;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowHelpUtils.class)
public class HelpTrampolineTest {
@After
public void tearDown() {
ShadowHelpUtils.reset();
}
@Test
public void launchHelp_noExtra_shouldDoNothing() {
final Intent intent = new Intent().setClassName(
RuntimeEnvironment.application.getPackageName(), HelpTrampoline.class.getName());
Robolectric.buildActivity(HelpTrampoline.class, intent).create().get();
assertThat(ShadowHelpUtils.isGetHelpIntentCalled()).isFalse();
}
@Test
public void launchHelp_hasExtra_shouldLaunchHelp() {
final Intent intent = new Intent().setClassName(
RuntimeEnvironment.application.getPackageName(), HelpTrampoline.class.getName())
.putExtra(Intent.EXTRA_TEXT, "help_url_upgrading");
final ShadowActivity shadow = Shadows.
shadowOf(Robolectric.buildActivity(HelpTrampoline.class, intent).create().get());
final Intent launchedIntent = shadow.getNextStartedActivity();
assertThat(ShadowHelpUtils.isGetHelpIntentCalled()).isTrue();
assertThat(launchedIntent).isNotNull();
}
}

View File

@@ -0,0 +1,51 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class LegalSettingsTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final Context context = RuntimeEnvironment.application;
final List<String> niks =
LegalSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(context);
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, R.xml.about_legal);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,173 @@
/*
* 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;
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.app.admin.DevicePolicyManager;
import android.app.admin.FactoryResetProtectionPolicy;
import android.content.Context;
import android.service.persistentdata.PersistentDataBlockManager;
import android.view.LayoutInflater;
import android.widget.TextView;
import androidx.fragment.app.FragmentActivity;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
})
public class MainClearConfirmTest {
private FragmentActivity mActivity;
@Mock
private FragmentActivity mMockActivity;
@Mock
private DevicePolicyManager mDevicePolicyManager;
@Mock
private PersistentDataBlockManager mPersistentDataBlockManager;
private MainClearConfirm mMainClearConfirm;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mActivity = Robolectric.setupActivity(FragmentActivity.class);
mMainClearConfirm = spy(new MainClearConfirm());
}
@Test
public void setSubtitle_eraseEsim() {
MainClearConfirm mainClearConfirm = new MainClearConfirm();
mainClearConfirm.mEraseEsims = true;
mainClearConfirm.mContentView =
LayoutInflater.from(mActivity).inflate(R.layout.main_clear_confirm, null);
mainClearConfirm.setSubtitle();
assertThat(((TextView) mainClearConfirm.mContentView
.findViewById(R.id.sud_layout_description)).getText())
.isEqualTo(mActivity.getString(R.string.main_clear_final_desc_esim));
}
@Test
public void setSubtitle_notEraseEsim() {
MainClearConfirm mainClearConfirm = new MainClearConfirm();
mainClearConfirm.mEraseEsims = false;
mainClearConfirm.mContentView =
LayoutInflater.from(mActivity).inflate(R.layout.main_clear_confirm, null);
mainClearConfirm.setSubtitle();
assertThat(((TextView) mainClearConfirm.mContentView
.findViewById(R.id.sud_layout_description)).getText())
.isEqualTo(mActivity.getString(R.string.main_clear_final_desc));
}
@Test
public void shouldWipePersistentDataBlock_noPersistentDataBlockManager_shouldReturnFalse() {
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(null)).isFalse();
}
@Test
public void shouldWipePersistentDataBlock_deviceIsStillBeingProvisioned_shouldReturnFalse() {
doReturn(true).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
mPersistentDataBlockManager)).isFalse();
}
@Test
public void shouldWipePersistentDataBlock_oemUnlockAllowed_shouldReturnFalse() {
doReturn(false).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
doReturn(true).when(mMainClearConfirm).isOemUnlockedAllowed();
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
mPersistentDataBlockManager)).isFalse();
}
@Test
public void shouldWipePersistentDataBlock_frpPolicyNotSupported_shouldReturnFalse() {
when(mMainClearConfirm.getActivity()).thenReturn(mMockActivity);
doReturn(false).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
doReturn(false).when(mMainClearConfirm).isOemUnlockedAllowed();
when(mMockActivity.getSystemService(Context.DEVICE_POLICY_SERVICE))
.thenReturn(mDevicePolicyManager);
when(mDevicePolicyManager.isFactoryResetProtectionPolicySupported()).thenReturn(false);
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
mPersistentDataBlockManager)).isFalse();
}
@Test
public void shouldWipePersistentDataBlock_hasFactoryResetProtectionPolicy_shouldReturnFalse() {
when(mMainClearConfirm.getActivity()).thenReturn(mMockActivity);
doReturn(false).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
doReturn(false).when(mMainClearConfirm).isOemUnlockedAllowed();
ArrayList<String> accounts = new ArrayList<>();
accounts.add("test");
FactoryResetProtectionPolicy frp = new FactoryResetProtectionPolicy.Builder()
.setFactoryResetProtectionAccounts(accounts)
.setFactoryResetProtectionEnabled(true)
.build();
when(mMockActivity.getSystemService(Context.DEVICE_POLICY_SERVICE))
.thenReturn(mDevicePolicyManager);
when(mDevicePolicyManager.isFactoryResetProtectionPolicySupported()).thenReturn(true);
when(mDevicePolicyManager.getFactoryResetProtectionPolicy(null)).thenReturn(frp);
when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true);
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
mPersistentDataBlockManager)).isFalse();
}
@Test
public void shouldWipePersistentDataBlock_isNotOrganizationOwnedDevice_shouldReturnTrue() {
when(mMainClearConfirm.getActivity()).thenReturn(mMockActivity);
doReturn(false).when(mMainClearConfirm).isDeviceStillBeingProvisioned();
doReturn(false).when(mMainClearConfirm).isOemUnlockedAllowed();
when(mMockActivity.getSystemService(Context.DEVICE_POLICY_SERVICE))
.thenReturn(mDevicePolicyManager);
when(mDevicePolicyManager.isFactoryResetProtectionPolicySupported()).thenReturn(true);
when(mDevicePolicyManager.getFactoryResetProtectionPolicy(null)).thenReturn(null);
when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(false);
assertThat(mMainClearConfirm.shouldWipePersistentDataBlock(
mPersistentDataBlockManager)).isTrue();
}
}

View File

@@ -0,0 +1,477 @@
/*
* 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.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
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.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.UserManager;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
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;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowActivity;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ShadowUtils.class,
ShadowUserManager.class,
com.android.settings.testutils.shadow.ShadowFragment.class,
})
public class MainClearTest {
private static final String TEST_ACCOUNT_TYPE = "android.test.account.type";
private static final String TEST_CONFIRMATION_PACKAGE = "android.test.conf.pkg";
private static final String TEST_CONFIRMATION_CLASS = "android.test.conf.pkg.ConfActivity";
private static final String TEST_ACCOUNT_NAME = "test@example.com";
@Mock
private ScrollView mScrollView;
@Mock
private LinearLayout mLinearLayout;
@Mock
private PackageManager mPackageManager;
@Mock
private AccountManager mAccountManager;
@Mock
private FragmentActivity mMockActivity;
@Mock
private Intent mMockIntent;
private MainClear mMainClear;
private ShadowActivity mShadowActivity;
private FragmentActivity mActivity;
private ShadowUserManager mShadowUserManager;
private View mContentView;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mMainClear = spy(new MainClear() {
@Override
boolean showAnySubscriptionInfo(Context context) { return true; }
});
mActivity = Robolectric.setupActivity(FragmentActivity.class);
mShadowActivity = Shadows.shadowOf(mActivity);
UserManager userManager = mActivity.getSystemService(UserManager.class);
mShadowUserManager = Shadow.extract(userManager);
mShadowUserManager.setIsAdminUser(true);
mContentView = LayoutInflater.from(mActivity).inflate(R.layout.main_clear, null);
// Make scrollView only have one child
when(mScrollView.getChildAt(0)).thenReturn(mLinearLayout);
when(mScrollView.getChildCount()).thenReturn(1);
}
@After
public void tearDown() {
mShadowUserManager.setIsAdminUser(false);
}
@Test
public void testShowFinalConfirmation_eraseEsimVisible_eraseEsimChecked() {
final Context context = mock(Context.class);
when(mMainClear.getContext()).thenReturn(context);
mMainClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
mMainClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
mMainClear.mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
mMainClear.mEsimStorageContainer.setVisibility(View.VISIBLE);
mMainClear.mEsimStorage.setChecked(true);
mMainClear.showFinalConfirmation();
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
verify(context).startActivity(intent.capture());
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
.getBoolean(MainClear.ERASE_ESIMS_EXTRA, false))
.isTrue();
}
@Test
public void testShowFinalConfirmation_eraseEsimVisible_eraseEsimUnchecked() {
final Context context = mock(Context.class);
when(mMainClear.getContext()).thenReturn(context);
mMainClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
mMainClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
mMainClear.mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
mMainClear.mEsimStorageContainer.setVisibility(View.VISIBLE);
mMainClear.mEsimStorage.setChecked(false);
mMainClear.showFinalConfirmation();
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
verify(context).startActivity(intent.capture());
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
.getBoolean(MainClear.ERASE_ESIMS_EXTRA, false))
.isFalse();
}
@Test
public void testShowFinalConfirmation_eraseEsimGone_eraseEsimChecked() {
final Context context = mock(Context.class);
when(mMainClear.getContext()).thenReturn(context);
mMainClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
mMainClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
mMainClear.mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
mMainClear.mEsimStorageContainer.setVisibility(View.GONE);
mMainClear.mEsimStorage.setChecked(true);
mMainClear.showFinalConfirmation();
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
verify(context).startActivity(intent.capture());
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
.getBoolean(MainClear.ERASE_ESIMS_EXTRA, false))
.isTrue();
}
@Test
public void testShowFinalConfirmation_eraseEsimGone_eraseEsimUnchecked() {
final Context context = mock(Context.class);
when(mMainClear.getContext()).thenReturn(context);
mMainClear.mEsimStorage = mContentView.findViewById(R.id.erase_esim);
mMainClear.mExternalStorage = mContentView.findViewById(R.id.erase_external);
mMainClear.mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
mMainClear.mEsimStorageContainer.setVisibility(View.GONE);
mMainClear.mEsimStorage.setChecked(false);
mMainClear.showFinalConfirmation();
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
verify(context).startActivity(intent.capture());
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
.getBoolean(MainClear.ERASE_ESIMS_EXTRA, false))
.isFalse();
}
@Test
public void testShowWipeEuicc_euiccDisabled() {
prepareEuiccState(
false /* isEuiccEnabled */,
true /* isEuiccProvisioned */,
false /* isDeveloper */);
assertThat(mMainClear.showWipeEuicc()).isFalse();
}
@Test
public void testShowWipeEuicc_euiccEnabled_unprovisioned() {
prepareEuiccState(
true /* isEuiccEnabled */,
false /* isEuiccProvisioned */,
false /* isDeveloper */);
assertThat(mMainClear.showWipeEuicc()).isFalse();
}
@Test
public void testShowWipeEuicc_euiccEnabled_provisioned() {
prepareEuiccState(
true /* isEuiccEnabled */,
true /* isEuiccProvisioned */,
false /* isDeveloper */);
assertThat(mMainClear.showWipeEuicc()).isTrue();
}
@Ignore("b/313566998")
@Test
public void testShowWipeEuicc_developerMode_unprovisioned() {
prepareEuiccState(
true /* isEuiccEnabled */,
false /* isEuiccProvisioned */,
true /* isDeveloper */);
assertThat(mMainClear.showWipeEuicc()).isTrue();
}
@Test
public void testEsimRecheckBoxDefaultChecked() {
assertThat(((CheckBox) mContentView.findViewById(R.id.erase_esim)).isChecked()).isFalse();
}
@Test
public void testHasReachedBottom_NotScrollDown_returnFalse() {
initScrollView(100, 0, 200);
assertThat(mMainClear.hasReachedBottom(mScrollView)).isFalse();
}
@Test
public void testHasReachedBottom_CanNotScroll_returnTrue() {
initScrollView(100, 0, 80);
assertThat(mMainClear.hasReachedBottom(mScrollView)).isTrue();
}
@Test
public void testHasReachedBottom_ScrollToBottom_returnTrue() {
initScrollView(100, 100, 200);
assertThat(mMainClear.hasReachedBottom(mScrollView)).isTrue();
}
@Test
public void testInitiateMainClear_inDemoMode_sendsIntent() {
ShadowUtils.setIsDemoUser(true);
final ComponentName componentName =
ComponentName.unflattenFromString("com.android.retaildemo/.DeviceAdminReceiver");
ShadowUtils.setDeviceOwnerComponent(componentName);
mMainClear.mInitiateListener.onClick(mContentView);
final Intent intent = mShadowActivity.getNextStartedActivity();
assertThat(Intent.ACTION_FACTORY_RESET).isEqualTo(intent.getAction());
assertThat(componentName).isNotNull();
assertThat(componentName.getPackageName()).isEqualTo(intent.getPackage());
}
@Test
public void testOnActivityResultInternal_invalideRequest() {
int invalidRequestCode = -1;
doReturn(false).when(mMainClear).isValidRequestCode(eq(invalidRequestCode));
mMainClear.onActivityResultInternal(invalidRequestCode, Activity.RESULT_OK, null);
verify(mMainClear, times(1)).isValidRequestCode(eq(invalidRequestCode));
verify(mMainClear, times(0)).establishInitialState();
verify(mMainClear, times(0)).getAccountConfirmationIntent();
verify(mMainClear, times(0)).showFinalConfirmation();
}
@Test
public void testOnActivityResultInternal_resultCanceled() {
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
doNothing().when(mMainClear).establishInitialState();
mMainClear
.onActivityResultInternal(MainClear.KEYGUARD_REQUEST, Activity.RESULT_CANCELED,
null);
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
verify(mMainClear, times(1)).establishInitialState();
verify(mMainClear, times(0)).getAccountConfirmationIntent();
verify(mMainClear, times(0)).showFinalConfirmation();
}
@Test
public void testOnActivityResultInternal_keyguardRequestTriggeringConfirmAccount() {
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
doReturn(mMockIntent).when(mMainClear).getAccountConfirmationIntent();
doNothing().when(mMainClear).showAccountCredentialConfirmation(eq(mMockIntent));
mMainClear
.onActivityResultInternal(MainClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
verify(mMainClear, times(0)).establishInitialState();
verify(mMainClear, times(1)).getAccountConfirmationIntent();
verify(mMainClear, times(1)).showAccountCredentialConfirmation(eq(mMockIntent));
}
@Test
public void testOnActivityResultInternal_keyguardRequestTriggeringShowFinal() {
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
doReturn(null).when(mMainClear).getAccountConfirmationIntent();
doNothing().when(mMainClear).showFinalConfirmation();
mMainClear
.onActivityResultInternal(MainClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
verify(mMainClear, times(0)).establishInitialState();
verify(mMainClear, times(1)).getAccountConfirmationIntent();
verify(mMainClear, times(1)).showFinalConfirmation();
}
@Test
public void testOnActivityResultInternal_confirmRequestTriggeringShowFinal() {
doReturn(true).when(mMainClear)
.isValidRequestCode(eq(MainClear.CREDENTIAL_CONFIRM_REQUEST));
doNothing().when(mMainClear).showFinalConfirmation();
mMainClear.onActivityResultInternal(
MainClear.CREDENTIAL_CONFIRM_REQUEST, Activity.RESULT_OK, null);
verify(mMainClear, times(1))
.isValidRequestCode(eq(MainClear.CREDENTIAL_CONFIRM_REQUEST));
verify(mMainClear, times(0)).establishInitialState();
verify(mMainClear, times(0)).getAccountConfirmationIntent();
verify(mMainClear, times(1)).showFinalConfirmation();
}
@Test
public void testGetAccountConfirmationIntent_unsupported() {
when(mMainClear.getActivity()).thenReturn(mActivity);
/* Using the default resources, account confirmation shouldn't trigger */
assertThat(mMainClear.getAccountConfirmationIntent()).isNull();
}
@Test
public void testGetAccountConfirmationIntent_no_relevant_accounts() {
when(mMainClear.getActivity()).thenReturn(mMockActivity);
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package))
.thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class))
.thenReturn(TEST_CONFIRMATION_CLASS);
Account[] accounts = new Account[0];
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
assertThat(mMainClear.getAccountConfirmationIntent()).isNull();
}
@Test
public void testGetAccountConfirmationIntent_unresolved() {
when(mMainClear.getActivity()).thenReturn(mMockActivity);
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package))
.thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class))
.thenReturn(TEST_CONFIRMATION_CLASS);
Account[] accounts = new Account[]{new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE)};
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
// The package manager should not resolve the confirmation intent targeting the non-existent
// confirmation package.
when(mMockActivity.getPackageManager()).thenReturn(mPackageManager);
assertThat(mMainClear.getAccountConfirmationIntent()).isNull();
}
@Test
public void testTryShowAccountConfirmation_ok() {
when(mMainClear.getActivity()).thenReturn(mMockActivity);
// Only try to show account confirmation if the appropriate resource overlays are available.
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package))
.thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class))
.thenReturn(TEST_CONFIRMATION_CLASS);
// Add accounts to trigger the search for a resolving intent.
Account[] accounts = new Account[]{new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE)};
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
// The package manager should not resolve the confirmation intent targeting the non-existent
// confirmation package.
when(mMockActivity.getPackageManager()).thenReturn(mPackageManager);
ActivityInfo activityInfo = new ActivityInfo();
activityInfo.packageName = TEST_CONFIRMATION_PACKAGE;
ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.activityInfo = activityInfo;
when(mPackageManager.resolveActivity(any(), eq(0))).thenReturn(resolveInfo);
Intent actualIntent = mMainClear.getAccountConfirmationIntent();
assertThat(TEST_CONFIRMATION_PACKAGE).isEqualTo(
actualIntent.getComponent().getPackageName());
assertThat(TEST_CONFIRMATION_CLASS).isEqualTo(actualIntent.getComponent().getClassName());
}
@Test
public void testShowAccountCredentialConfirmation() {
// Finally mock out the startActivityForResultCall
doNothing().when(mMainClear)
.startActivityForResult(eq(mMockIntent),
eq(MainClear.CREDENTIAL_CONFIRM_REQUEST));
mMainClear.showAccountCredentialConfirmation(mMockIntent);
verify(mMainClear, times(1))
.startActivityForResult(eq(mMockIntent),
eq(MainClear.CREDENTIAL_CONFIRM_REQUEST));
}
@Test
public void testIsValidRequestCode() {
assertThat(mMainClear.isValidRequestCode(MainClear.KEYGUARD_REQUEST)).isTrue();
assertThat(mMainClear.isValidRequestCode(MainClear.CREDENTIAL_CONFIRM_REQUEST))
.isTrue();
assertThat(mMainClear.isValidRequestCode(0)).isFalse();
}
@Test
public void testOnGlobalLayout_shouldNotRemoveListener() {
final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
mMainClear.mScrollView = mScrollView;
doNothing().when(mMainClear).onGlobalLayout();
doReturn(true).when(mMainClear).hasReachedBottom(any());
when(mScrollView.getViewTreeObserver()).thenReturn(viewTreeObserver);
mMainClear.onGlobalLayout();
verify(viewTreeObserver, never()).removeOnGlobalLayoutListener(mMainClear);
}
private void prepareEuiccState(
boolean isEuiccEnabled, boolean isEuiccProvisioned, boolean isDeveloper) {
doReturn(mActivity).when(mMainClear).getContext();
doReturn(isEuiccEnabled).when(mMainClear).isEuiccEnabled(any());
ContentResolver cr = mActivity.getContentResolver();
Settings.Global.putInt(cr, Settings.Global.EUICC_PROVISIONED, isEuiccProvisioned ? 1 : 0);
DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(mActivity, isDeveloper);
}
private void initScrollView(int height, int scrollY, int childBottom) {
when(mScrollView.getHeight()).thenReturn(height);
when(mScrollView.getScrollY()).thenReturn(scrollY);
when(mLinearLayout.getBottom()).thenReturn(childBottom);
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static android.view.HapticFeedbackConstants.CONTEXT_CLICK;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.SeekBar;
import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowInteractionJankMonitor.class})
public class PointerSpeedPreferenceTest {
private Context mContext;
private AttributeSet mAttrs;
private SeekBar mSeekBar;
private PointerSpeedPreference mPointerSpeedPreference;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mSeekBar = new SeekBar(mContext, mAttrs);
mPointerSpeedPreference = new PointerSpeedPreference(mContext, mAttrs);
}
@Test
public void onProgressChanged_minimumValue_clockTickFeedbackPerformed() {
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
mPointerSpeedPreference.onProgressChanged(mSeekBar, 0, true);
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
}
}

View File

@@ -0,0 +1,124 @@
/*
* 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;
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.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import android.view.LayoutInflater;
import android.widget.TextView;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowRecoverySystem;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;
@RunWith(RobolectricTestRunner.class)
@LooperMode(LooperMode.Mode.LEGACY)
@Config(shadows = {ShadowRecoverySystem.class, ShadowBluetoothAdapter.class})
public class ResetNetworkConfirmTest {
private static final String TEST_PACKAGE = "com.android.settings";
private FragmentActivity mActivity;
@Mock
private ResetNetworkConfirm mResetNetworkConfirm;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mResetNetworkConfirm = new ResetNetworkConfirm();
mActivity = spy(Robolectric.setupActivity(FragmentActivity.class));
mResetNetworkConfirm.mActivity = mActivity;
}
@After
public void tearDown() {
ShadowRecoverySystem.reset();
}
@Test
public void testResetNetworkData_notResetEsim() {
mResetNetworkConfirm.mResetNetworkRequest =
new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
mResetNetworkConfirm.mResetSubscriptionContract =
new ResetSubscriptionContract(mActivity,
mResetNetworkConfirm.mResetNetworkRequest) {
@Override
public void onSubscriptionInactive(int subscriptionId) {
mActivity.onBackPressed();
}
};
mResetNetworkConfirm.mFinalClickListener.onClick(null /* View */);
Robolectric.getBackgroundThreadScheduler().advanceToLastPostedRunnable();
assertThat(ShadowRecoverySystem.getWipeEuiccCalledCount()).isEqualTo(0);
}
@Test
public void setSubtitle_eraseEsim() {
mResetNetworkConfirm.mResetNetworkRequest =
new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
mResetNetworkConfirm.mResetNetworkRequest.setResetEsim(TEST_PACKAGE);
mResetNetworkConfirm.mContentView =
LayoutInflater.from(mActivity).inflate(R.layout.reset_network_confirm, null);
mResetNetworkConfirm.setSubtitle();
assertThat(((TextView) mResetNetworkConfirm.mContentView
.findViewById(R.id.reset_network_confirm)).getText())
.isEqualTo(mActivity.getString(R.string.reset_network_final_desc_esim));
}
@Test
public void setSubtitle_notEraseEsim() {
mResetNetworkConfirm.mResetNetworkRequest =
new ResetNetworkRequest(ResetNetworkRequest.RESET_NONE);
mResetNetworkConfirm.mContentView =
LayoutInflater.from(mActivity).inflate(R.layout.reset_network_confirm, null);
mResetNetworkConfirm.setSubtitle();
assertThat(((TextView) mResetNetworkConfirm.mContentView
.findViewById(R.id.reset_network_confirm)).getText())
.isEqualTo(mActivity.getString(R.string.reset_network_final_desc));
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.CheckBox;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class ResetNetworkTest {
private Activity mActivity;
private ResetNetwork mResetNetwork;
@Before
public void setUp() {
mActivity = Robolectric.setupActivity(Activity.class);
mResetNetwork = spy(new ResetNetwork());
when(mResetNetwork.getContext()).thenReturn(mActivity);
mResetNetwork.mEsimContainer = new View(mActivity);
mResetNetwork.mEsimCheckbox = new CheckBox(mActivity);
}
@Test
@Ignore
public void showFinalConfirmation_checkboxVisible_eraseEsimChecked() {
mResetNetwork.mEsimContainer.setVisibility(View.VISIBLE);
mResetNetwork.mEsimCheckbox.setChecked(true);
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
.isNotNull();
}
@Test
public void showFinalConfirmation_checkboxVisible_eraseEsimUnchecked() {
mResetNetwork.mEsimContainer.setVisibility(View.VISIBLE);
mResetNetwork.mEsimCheckbox.setChecked(false);
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
.isNull();
}
@Test
public void showFinalConfirmation_checkboxGone_eraseEsimChecked() {
mResetNetwork.mEsimContainer.setVisibility(View.GONE);
mResetNetwork.mEsimCheckbox.setChecked(true);
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
.isNull();
}
@Test
public void showFinalConfirmation_checkboxGone_eraseEsimUnchecked() {
mResetNetwork.mEsimContainer.setVisibility(View.GONE);
mResetNetwork.mEsimCheckbox.setChecked(false);
mResetNetwork.showFinalConfirmation();
Intent intent = shadowOf(mActivity).getNextStartedActivity();
assertThat(intent.getStringExtra(ResetNetworkRequest.KEY_ESIM_PACKAGE))
.isNull();
}
}

View File

@@ -0,0 +1,128 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.AttributeSet;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedPreferenceHelper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowKeyguardManager;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowUserManager.class, ShadowKeyguardManager.class})
public class RestrictedListPreferenceTest {
private static final int PROFILE_USER_ID = 11;
// From UnlaunchableAppActivity
private static final int UNLAUNCHABLE_REASON_QUIET_MODE = 1;
private static final String EXTRA_UNLAUNCHABLE_REASON = "unlaunchable_reason";
private Activity mActivity;
private ShadowUserManager mShadowUserManager;
private ShadowKeyguardManager mShadowKeyguardManager;
private RestrictedListPreference mPreference;
private RestrictedPreferenceHelper mMockHelper;
@Before
public void setUp() {
mActivity = Robolectric.setupActivity(Activity.class);
mShadowKeyguardManager =
Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
mMockHelper = mock(RestrictedPreferenceHelper.class);
mShadowUserManager = ShadowUserManager.getShadow();
AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new RestrictedListPreference(mActivity, attributeSet);
mPreference.setProfileUserId(PROFILE_USER_ID);
ReflectionHelpers.setField(mPreference, "mHelper", mMockHelper);
}
@Test
public void performClick_profileLocked() {
mPreference.setRequiresActiveUnlockedProfile(true);
mShadowUserManager.setQuietModeEnabled(false);
mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, true);
// Device has to be marked as secure so the real KeyguardManager will create a non-null
// intent.
mShadowKeyguardManager.setIsDeviceSecure(PROFILE_USER_ID, true);
mPreference.performClick();
// Make sure that the performClick method on the helper is never reached.
verify(mMockHelper, never()).performClick();
// Assert that a CONFIRM_DEVICE_CREDENTIAL intent has been started.
Intent started = Shadows.shadowOf(mActivity).getNextStartedActivity();
assertThat(started.getExtras().getInt(Intent.EXTRA_USER_ID)).isEqualTo(PROFILE_USER_ID);
assertThat(started.getAction())
.isEqualTo(KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
}
@Test
public void performClick_profileDisabled() {
mPreference.setRequiresActiveUnlockedProfile(true);
mShadowUserManager.setQuietModeEnabled(true);
mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, false);
mPreference.performClick();
// Make sure that the performClick method on the helper is never reached.
verify(mMockHelper, never()).performClick();
// Assert that a new intent for enabling the work profile is started.
Intent started = Shadows.shadowOf(mActivity).getNextStartedActivity();
Bundle extras = started.getExtras();
int reason = extras.getInt(EXTRA_UNLAUNCHABLE_REASON);
assertThat(reason).isEqualTo(UNLAUNCHABLE_REASON_QUIET_MODE);
}
@Test
public void performClick_profileAvailable() {
// Verify that the helper's perfomClick method is called if the profile is
// available and unlocked.
mPreference.setRequiresActiveUnlockedProfile(true);
mShadowUserManager.setQuietModeEnabled(false);
mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, false);
when(mMockHelper.performClick()).thenReturn(true);
mPreference.performClick();
verify(mMockHelper).performClick();
}
@Test
public void performClick_profileLockedAndUnlockedProfileNotRequired() {
// Verify that even if the profile is disabled, if the Preference class does not
// require it than the regular flow takes place.
mPreference.setRequiresActiveUnlockedProfile(false);
mShadowUserManager.setQuietModeEnabled(true);
when(mMockHelper.performClick()).thenReturn(true);
mPreference.performClick();
verify(mMockHelper).performClick();
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.Activity;
import androidx.appcompat.app.AlertDialog;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class RestrictedSettingsFragmentTest {
@Mock
private AlertDialog mAlertDialog;
private RestrictedSettingsFragment mFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void onActivityResult_dismissesDialogOnOk() {
mFragment = new RestrictedSettingsFragment("fake_key") {
@Override
public int getMetricsCategory() {
return 0;
}
};
doReturn(true).when(mAlertDialog).isShowing();
mFragment.mActionDisabledDialog = mAlertDialog;
mFragment.onActivityResult(RestrictedSettingsFragment.REQUEST_PIN_CHALLENGE,
Activity.RESULT_OK,
null);
// dialog should be gone
verify(mAlertDialog, times(1)).setOnDismissListener(isNull());
verify(mAlertDialog, times(1)).dismiss();
}
}

View File

@@ -0,0 +1,126 @@
/*
* 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.SettingsActivity.EXTRA_SHOW_FRAGMENT;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
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.ActivityManager;
import android.content.Context;
import android.content.Intent;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.android.settings.core.OnActivityResultListener;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowUserManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowUserManager.class)
public class SettingsActivityTest {
@Mock
private FragmentManager mFragmentManager;
@Mock
private ActivityManager.TaskDescription mTaskDescription;
private SettingsActivity mActivity;
private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mActivity = spy(Robolectric.buildActivity(SettingsActivity.class).create().get());
}
@Test
public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash() {
when(mActivity.getSupportFragmentManager()).thenReturn(mFragmentManager);
doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver();
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
doReturn(RuntimeEnvironment.application.getClassLoader()).when(mActivity).getClassLoader();
mActivity.launchSettingFragment(null, mock(Intent.class));
}
@Test
public void setTaskDescription_shouldUpdateIcon() {
mActivity.setTaskDescription(mTaskDescription);
verify(mTaskDescription).setIcon(any());
}
@Test
public void getSharedPreferences_intentExtraIsNull_shouldNotCrash() {
final Intent intent = new Intent();
intent.putExtra(EXTRA_SHOW_FRAGMENT, (String)null);
doReturn(intent).when(mActivity).getIntent();
doReturn(mContext.getPackageName()).when(mActivity).getPackageName();
FakeFeatureFactory.setupForTest();
mActivity.getSharedPreferences(mContext.getPackageName() + "_preferences", 0);
}
@Test
public void onActivityResult_shouldDelegateToListener() {
final List<Fragment> fragments = new ArrayList<>();
fragments.add(new Fragment());
fragments.add(new ListenerFragment());
final FragmentManager manager = mock(FragmentManager.class);
when(mActivity.getSupportFragmentManager()).thenReturn(manager);
when(manager.getFragments()).thenReturn(fragments);
mActivity.onActivityResult(0, 0, new Intent());
assertThat(((ListenerFragment) fragments.get(1)).mOnActivityResultCalled).isTrue();
}
public static class ListenerFragment extends Fragment implements OnActivityResultListener {
private boolean mOnActivityResultCalled;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
mOnActivityResultCalled = true;
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.junit.Assert.fail;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Dialog;
import androidx.fragment.app.Fragment;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class SettingsDialogFragmentTest {
private static final int DIALOG_ID = 15;
@Mock
private DialogCreatableFragment mDialogCreatable;
private SettingsPreferenceFragment.SettingsDialogFragment mDialogFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testGetMetrics_shouldGetMetricFromDialogCreatable() {
when(mDialogCreatable.getDialogMetricsCategory(DIALOG_ID)).thenReturn(1);
mDialogFragment = SettingsPreferenceFragment.SettingsDialogFragment.newInstance(
mDialogCreatable, DIALOG_ID);
mDialogFragment.onAttach(RuntimeEnvironment.application);
mDialogFragment.getMetricsCategory();
// getDialogMetricsCategory called in onAttach, and explicitly in test.
verify(mDialogCreatable, times(2)).getDialogMetricsCategory(DIALOG_ID);
}
@Test
public void testGetInvalidMetricsValue_shouldCrash() {
when(mDialogCreatable.getDialogMetricsCategory(DIALOG_ID)).thenReturn(-1);
try {
mDialogFragment = SettingsPreferenceFragment.SettingsDialogFragment.newInstance(
mDialogCreatable, DIALOG_ID);
mDialogFragment.onAttach(RuntimeEnvironment.application);
fail("Should fail with IllegalStateException");
} catch (IllegalStateException e) {
// getDialogMetricsCategory called in constructor
verify(mDialogCreatable).getDialogMetricsCategory(DIALOG_ID);
}
}
public static class DialogCreatableFragment extends Fragment implements DialogCreatable {
@Override
public Dialog onCreateDialog(int dialogId) {
return null;
}
@Override
public int getDialogMetricsCategory(int dialogId) {
return 0;
}
}
}

View File

@@ -0,0 +1,110 @@
/*
* 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.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
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.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.io.PrintWriter;
import java.io.StringWriter;
@RunWith(RobolectricTestRunner.class)
public class SettingsDumpServiceTest {
private static final String PACKAGE_BROWSER = "com.android.test.browser";
private static final String PACKAGE_NULL = "android";
private static final int ANOMALY_VERSION = 2;
@Mock
private PackageManager mPackageManager;
@Mock
private ResolveInfo mResolveInfo;
private TestService mTestService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mPackageManager.resolveActivity(TestService.BROWSER_INTENT,
PackageManager.MATCH_DEFAULT_ONLY)).thenReturn(mResolveInfo);
mTestService = spy(new TestService());
mTestService.setPackageManager(mPackageManager);
}
@Test
public void testDumpDefaultBrowser_DefaultBrowser_ReturnBrowserName() {
mResolveInfo.activityInfo = new ActivityInfo();
mResolveInfo.activityInfo.packageName = PACKAGE_BROWSER;
assertThat(mTestService.dumpDefaultBrowser()).isEqualTo(PACKAGE_BROWSER);
}
@Test
public void testDumpDefaultBrowser_NoDefault_ReturnNull() {
mResolveInfo.activityInfo = new ActivityInfo();
mResolveInfo.activityInfo.packageName = PACKAGE_NULL;
assertThat(mTestService.dumpDefaultBrowser()).isEqualTo(null);
}
@Test
public void testDump_printServiceAsKey() {
mResolveInfo.activityInfo = new ActivityInfo();
mResolveInfo.activityInfo.packageName = PACKAGE_BROWSER;
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
mTestService.dump(null, printWriter, null);
assertThat(stringWriter.toString())
.contains("{\"" + SettingsDumpService.KEY_SERVICE + "\":");
}
/**
* Test service used to pass in the mock {@link PackageManager}
*/
private class TestService extends SettingsDumpService {
private PackageManager mPm;
public void setPackageManager(PackageManager pm) {
mPm = pm;
}
@Override
public PackageManager getPackageManager() {
return mPm;
}
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class SettingsInitializeTest {
private Context mContext;
private SettingsInitialize mSettingsInitialize;
private ShortcutManager mShortcutManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mSettingsInitialize = new SettingsInitialize();
mShortcutManager = (ShortcutManager) mContext.getSystemService(Context.SHORTCUT_SERVICE);
}
@Test
public void refreshExistingShortcuts_shouldUpdateLaunchIntentFlagsForExistingShortcut() {
final String id = "test_shortcut_id";
final Intent intent = new Intent(Intent.ACTION_DEFAULT);
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
final ShortcutInfo info = new ShortcutInfo.Builder(mContext, id)
.setShortLabel("test123")
.setIntent(intent)
.build();
mShortcutManager.addDynamicShortcuts(Collections.singletonList(info));
mShortcutManager.requestPinShortcut(info, null);
mSettingsInitialize.refreshExistingShortcuts(mContext);
final List<ShortcutInfo> updatedShortcuts = mShortcutManager.getPinnedShortcuts();
assertThat(updatedShortcuts).hasSize(1);
final ShortcutInfo updateInfo = updatedShortcuts.get(0);
assertThat(updateInfo.getId()).isEqualTo(id);
final int flags = updateInfo.getIntent().getFlags();
// The original flag should be removed
assertThat(flags & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED).isEqualTo(0);
// The new flags should be set
assertThat(flags & Intent.FLAG_ACTIVITY_NEW_TASK).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK);
assertThat(flags & Intent.FLAG_ACTIVITY_CLEAR_TOP).isEqualTo(
Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
@Test
public void refreshExistingShortcuts_shouldNotUpdateImmutableShortcut() {
final String id = "test_shortcut_id";
final ShortcutInfo info = new ShortcutInfo.Builder(mContext, id)
.setShortLabel("test123")
.setIntent(new Intent(Intent.ACTION_DEFAULT))
.build();
info.addFlags(ShortcutInfo.FLAG_IMMUTABLE);
mShortcutManager.addDynamicShortcuts(Collections.singletonList(info));
mShortcutManager.requestPinShortcut(info, null);
mSettingsInitialize.refreshExistingShortcuts(mContext);
final List<ShortcutInfo> updatedShortcuts = mShortcutManager.getPinnedShortcuts();
assertThat(updatedShortcuts).hasSize(1);
assertThat(updatedShortcuts.get(0)).isSameInstanceAs(info);
}
}

View File

@@ -0,0 +1,102 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.app.Application;
import android.content.Intent;
import android.net.Uri;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.android.controller.ActivityController;
import java.io.File;
@RunWith(RobolectricTestRunner.class)
public class SettingsLicenseActivityTest {
private ActivityController<SettingsLicenseActivity> mActivityController;
private SettingsLicenseActivity mActivity;
private Application mApplication;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mApplication = RuntimeEnvironment.application;
mActivityController = Robolectric.buildActivity(SettingsLicenseActivity.class);
mActivity = spy(mActivityController.get());
}
private void assertEqualIntents(Intent actual, Intent expected) {
assertThat(actual.getAction()).isEqualTo(expected.getAction());
assertThat(actual.getDataString()).isEqualTo(expected.getDataString());
assertThat(actual.getType()).isEqualTo(expected.getType());
assertThat(actual.getCategories()).isEqualTo(expected.getCategories());
assertThat(actual.getPackage()).isEqualTo(expected.getPackage());
assertThat(actual.getFlags()).isEqualTo(expected.getFlags());
}
@Test
public void testOnCreateWithValidHtmlFile() {
doReturn(true).when(mActivity).isFileValid(any());
mActivity.onCreate(null);
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file:///system/etc/NOTICE.html.gz"), "text/html");
intent.putExtra(Intent.EXTRA_TITLE, mActivity.getString(
R.string.settings_license_activity_title));
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setPackage("com.android.htmlviewer");
assertEqualIntents(Shadows.shadowOf(mApplication).getNextStartedActivity(), intent);
}
@Test
public void testOnCreateWithGeneratedHtmlFile() {
doReturn(Uri.parse("content://com.android.settings.files/my_cache/generated_test.html"))
.when(mActivity).getUriFromGeneratedHtmlFile(any());
mActivity.onCreate(null);
mActivity.onLoadFinished(null, new File("/generated_test.html"));
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("content://com.android.settings.files/my_cache/generated_test.html"),
"text/html");
intent.putExtra(Intent.EXTRA_TITLE, mActivity.getString(
R.string.settings_license_activity_title));
intent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setPackage("com.android.htmlviewer");
assertEqualIntents(Shadows.shadowOf(mApplication).getNextStartedActivity(), intent);
}
}

View File

@@ -0,0 +1,294 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
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.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.FrameLayout;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.widget.WorkOnlyCategory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
})
public class SettingsPreferenceFragmentTest {
private static final int ITEM_COUNT = 5;
@Mock
private FragmentActivity mActivity;
@Mock
private View mListContainer;
@Mock
private PreferenceScreen mPreferenceScreen;
private Context mContext;
private TestFragment mFragment;
private TestFragment2 mFragment2;
private View mEmptyView;
private int mInitDeviceProvisionedValue;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest();
mContext = RuntimeEnvironment.application;
mFragment = spy(new TestFragment());
mFragment2 = spy(new TestFragment2());
doReturn(mActivity).when(mFragment).getActivity();
when(mFragment.getContext()).thenReturn(mContext);
when(mFragment2.getContext()).thenReturn(mContext);
mEmptyView = new View(mContext);
ReflectionHelpers.setField(mFragment, "mEmptyView", mEmptyView);
doReturn(ITEM_COUNT).when(mPreferenceScreen).getPreferenceCount();
mInitDeviceProvisionedValue = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0);
}
@After
public void tearDown() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, mInitDeviceProvisionedValue);
}
@Test
public void removePreference_nested_shouldRemove() {
final String key = "test_key";
final PreferenceScreen mScreen = spy(new PreferenceScreen(mContext, null));
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
final PreferenceCategory nestedCategory = new ProgressCategory(mContext);
final Preference preference = new Preference(mContext);
preference.setKey(key);
preference.setPersistent(false);
mScreen.addPreference(nestedCategory);
nestedCategory.addPreference(preference);
assertThat(mFragment.removePreference(mScreen, key)).isTrue();
assertThat(nestedCategory.getPreferenceCount()).isEqualTo(0);
}
@Test
public void removePreference_flat_shouldRemove() {
final String key = "test_key";
final PreferenceScreen mScreen = spy(new PreferenceScreen(mContext, null));
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
final Preference preference = mock(Preference.class);
when(preference.getKey()).thenReturn(key);
mScreen.addPreference(preference);
assertThat(mFragment.removePreference(mScreen, key)).isTrue();
assertThat(mScreen.getPreferenceCount()).isEqualTo(0);
}
@Test
public void removePreference_doNotExist_shouldNotRemove() {
final String key = "test_key";
final PreferenceScreen mScreen = spy(new PreferenceScreen(mContext, null));
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
final Preference preference = mock(Preference.class);
when(preference.getKey()).thenReturn(key);
mScreen.addPreference(preference);
assertThat(mFragment.removePreference(mScreen, "not" + key)).isFalse();
assertThat(mScreen.getPreferenceCount()).isEqualTo(1);
}
@Test
public void testUpdateEmptyView_containerInvisible_emptyViewVisible() {
doReturn(View.INVISIBLE).when(mListContainer).getVisibility();
doReturn(mListContainer).when(mActivity).findViewById(android.R.id.list_container);
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
mFragment.updateEmptyView();
assertThat(mEmptyView.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void testUpdateEmptyView_containerNull_emptyViewGone() {
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
mFragment.updateEmptyView();
assertThat(mEmptyView.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void onCreate_hasExtraFragmentKey_shouldExpandPreferences() {
doReturn(mContext.getTheme()).when(mActivity).getTheme();
doReturn(mContext.getResources()).when(mFragment).getResources();
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
final Bundle bundle = new Bundle();
bundle.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, "test_key");
when(mFragment.getArguments()).thenReturn(bundle);
mFragment.onCreate(null /* icicle */);
verify(mPreferenceScreen).setInitialExpandedChildrenCount(Integer.MAX_VALUE);
}
@Test
public void onCreate_noPreferenceScreen_shouldNotCrash() {
doReturn(mContext.getTheme()).when(mActivity).getTheme();
doReturn(mContext.getResources()).when(mFragment).getResources();
doReturn(null).when(mFragment).getPreferenceScreen();
final Bundle bundle = new Bundle();
bundle.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, "test_key");
when(mFragment.getArguments()).thenReturn(bundle);
mFragment.onCreate(null /* icicle */);
// no crash
}
@Test
public void checkAvailablePrefs_selfAvialbalePreferenceNotAvailable_shouldHidePreference() {
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
final WorkOnlyCategory workOnlyCategory = mock(WorkOnlyCategory.class);
when(mPreferenceScreen.getPreferenceCount()).thenReturn(1);
when(mPreferenceScreen.getPreference(0)).thenReturn(workOnlyCategory);
when(workOnlyCategory.isAvailable(any(Context.class))).thenReturn(false);
mFragment.checkAvailablePrefs(mPreferenceScreen);
verify(mPreferenceScreen, never()).removePreference(workOnlyCategory);
verify(workOnlyCategory).setVisible(false);
}
@Test
public void showPinnedHeader_shouldBeVisible() {
mFragment.mPinnedHeaderFrameLayout = new FrameLayout(mContext);
mFragment.showPinnedHeader(true);
assertThat(mFragment.mPinnedHeaderFrameLayout.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void hidePinnedHeader_shouldBeInvisible() {
mFragment.mPinnedHeaderFrameLayout = new FrameLayout(mContext);
mFragment.showPinnedHeader(false);
assertThat(mFragment.mPinnedHeaderFrameLayout.getVisibility()).isEqualTo(View.INVISIBLE);
}
@Test
public void onAttach_shouldNotSkipForSUWAndDeviceIsProvisioned_notCallFinish() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
mFragment.onAttach(mContext);
verify(mFragment, never()).finish();
}
@Test
public void onAttach_shouldNotSkipForSUWAndDeviceIsNotProvisioned_notCallFinish() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0);
mFragment.onAttach(mContext);
verify(mFragment, never()).finish();
}
@Test
public void onAttach_shouldSkipForSUWAndDeviceIsDeviceProvisioned_notCallFinish() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 1);
mFragment2.onAttach(mContext);
verify(mFragment2, never()).finish();
}
@Test
public void onAttach_shouldSkipForSUWAndDeviceProvisioned_notCallFinish() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0);
mFragment2.onAttach(mContext);
verify(mFragment2, times(1)).finish();
}
public static class TestFragment extends SettingsPreferenceFragment {
@Override
protected boolean shouldSkipForInitialSUW() {
return false;
}
@Override
public int getMetricsCategory() {
return 0;
}
}
public static class TestFragment2 extends SettingsPreferenceFragment {
@Override
protected boolean shouldSkipForInitialSUW() {
return true;
}
@Override
public int getMetricsCategory() {
return 0;
}
}
}

View File

@@ -0,0 +1,277 @@
/*
* 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.google.common.truth.Truth.assertThat;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.sysprop.SetupWizardProperties;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider;
import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
import com.google.android.setupcompat.util.WizardManagerHelper;
import com.google.android.setupdesign.util.ThemeHelper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class SetupWizardUtilsTest {
private Context mContext;
@Before
public void setup() {
PartnerConfigHelper.resetInstance();
mContext = ApplicationProvider.getApplicationContext();
}
@Test
public void testCopySetupExtras() {
Intent fromIntent = new Intent();
final String theme = "TEST_THEME";
fromIntent.putExtra(WizardManagerHelper.EXTRA_THEME, theme);
fromIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true);
Intent toIntent = new Intent();
SetupWizardUtils.copySetupExtras(fromIntent, toIntent);
assertThat(theme).isEqualTo(toIntent.getStringExtra(WizardManagerHelper.EXTRA_THEME));
assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, false))
.isTrue();
assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true))
.isFalse();
}
@Test
public void testCopyLifecycleExtra() {
Intent fromIntent = new Intent();
final String theme = "TEST_THEME";
fromIntent.putExtra(WizardManagerHelper.EXTRA_THEME, theme);
fromIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true);
Bundle dstBundle = new Bundle();
dstBundle = SetupWizardUtils.copyLifecycleExtra(fromIntent.getExtras(), dstBundle);
assertThat(dstBundle).isNotNull();
assertThat(dstBundle.getString(WizardManagerHelper.EXTRA_THEME)).isNull();
assertThat(dstBundle.getBoolean(WizardManagerHelper.EXTRA_IS_SETUP_FLOW))
.isTrue();
assertThat(dstBundle.getBoolean(WizardManagerHelper.EXTRA_IS_FIRST_RUN))
.isFalse();
}
@Test
public void testGetTheme_withIntentExtra_shouldReturnTheme() {
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF);
Intent intent = createSetupWizardIntent();
intent.putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2);
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV2Theme);
}
@Test
public void testGetTheme_withEmptyIntent_shouldReturnSystemProperty() {
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT);
Intent intent = createSetupWizardIntent();
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV2Theme_Light);
}
@Test
public void testGetTheme_whenSuwDayNightEnabledAndWithIntentExtra_shouldReturnDayNightTheme() {
FakePartnerContentProvider provider =
Robolectric.setupContentProvider(
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
provider.injectFakeDayNightEnabledResult(true);
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT);
Intent intent = createSetupWizardIntent();
intent.putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2);
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV2Theme_DayNight);
}
@Test
public void testGetTheme_glifV3Light_shouldReturnLightTheme() {
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3_LIGHT);
Intent intent = createSetupWizardIntent();
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme_Light);
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme_Light_Transparent);
}
@Test
public void testGetTheme_glifV3_shouldReturnTheme() {
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3);
Intent intent = createSetupWizardIntent();
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme);
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme_Transparent);
}
@Test
public void testGetTheme_whenSuwDayNightDisabledAndGlifV2_shouldReturnLightTheme() {
FakePartnerContentProvider provider =
Robolectric.setupContentProvider(
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
provider.injectFakeDayNightEnabledResult(false);
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT);
Intent intent = createSetupWizardIntent();
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV2Theme_Light);
}
@Test
public void testGetTheme_whenSuwDayNightEnabledAndGlifV2_shouldReturnDayNightTheme() {
FakePartnerContentProvider provider =
Robolectric.setupContentProvider(
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
provider.injectFakeDayNightEnabledResult(true);
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT);
Intent intent = createSetupWizardIntent();
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV2Theme_DayNight);
}
@Test
public void testGetTheme_whenSuwDayNightDisabledAndGlifV3_shouldReturnTheme() {
FakePartnerContentProvider provider =
Robolectric.setupContentProvider(
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
provider.injectFakeDayNightEnabledResult(false);
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3);
Intent intent = createSetupWizardIntent();
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme);
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme_Transparent);
}
@Test
public void testGetTheme_whenSuwDayNightEnabledAndGlifV3_shouldReturnDayNightTheme() {
FakePartnerContentProvider provider =
Robolectric.setupContentProvider(
FakePartnerContentProvider.class, "com.google.android.setupwizard.partner");
provider.injectFakeDayNightEnabledResult(true);
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3);
Intent intent = createSetupWizardIntent();
assertThat(SetupWizardUtils.getTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme_DayNight);
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme_DayNight_Transparent);
}
@Test
public void testGetTheme_nonSuw_shouldReturnTheme() {
SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3_LIGHT);
Intent intent = new Intent();
assertThat(SetupWizardUtils.getTheme(mContext, intent)).isEqualTo(R.style.GlifV3Theme);
assertThat(SetupWizardUtils.getTransparentTheme(mContext, intent))
.isEqualTo(R.style.GlifV3Theme_Transparent);
}
private Intent createSetupWizardIntent() {
return new Intent()
.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)
.putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true);
}
private static final class FakePartnerContentProvider extends ContentProvider {
private final Bundle mFakeProviderDayNightEnabledResultBundle = new Bundle();
@Override
public boolean onCreate() {
return true;
}
@Override
public Cursor query(
@NonNull Uri uri,
@Nullable String[] projection,
@Nullable String selection,
@Nullable String[] selectionArgs,
@Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(
@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(
@NonNull Uri uri,
@Nullable ContentValues values,
@Nullable String selection,
@Nullable String[] selectionArgs) {
return 0;
}
@Override
public Bundle call(String method, String arg, Bundle extras) {
if (TextUtils.equals(method, "isSuwDayNightEnabled")) {
return mFakeProviderDayNightEnabledResultBundle;
}
return null;
}
public FakePartnerContentProvider injectFakeDayNightEnabledResult(boolean dayNightEnabled) {
mFakeProviderDayNightEnabledResultBundle.putBoolean(
"isSuwDayNightEnabled", dayNightEnabled);
return this;
}
}
}

View File

@@ -0,0 +1,78 @@
/*
* 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.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class SummaryPreferenceTest {
private PreferenceViewHolder mHolder;
private SummaryPreference mPreference;
@Before
public void setUp() {
final Context context = RuntimeEnvironment.application;
mPreference = new SummaryPreference(context, null);
LayoutInflater inflater = LayoutInflater.from(context);
final View view =
inflater.inflate(mPreference.getLayoutResource(), new LinearLayout(context), false);
mHolder = PreferenceViewHolder.createInstanceForTests(view);
}
@Test
public void disableChart_shouldNotRender() {
mPreference.setChartEnabled(false);
mPreference.onBindViewHolder(mHolder);
final TextView textView1 = (TextView) mHolder.findViewById(android.R.id.text1);
assertThat(textView1.getText()).isEqualTo("");
final TextView textView2 = (TextView) mHolder.findViewById(android.R.id.text2);
assertThat(textView2.getText()).isEqualTo("");
}
@Test
public void enableChart_shouldRender() {
final String testLabel1 = "label1";
final String testLabel2 = "label2";
mPreference.setChartEnabled(true);
mPreference.setLabels(testLabel1, testLabel2);
mPreference.onBindViewHolder(mHolder);
final TextView textView1 = (TextView) mHolder.findViewById(android.R.id.text1);
assertThat(textView1.getText()).isEqualTo(testLabel1);
final TextView textView2 = (TextView) mHolder.findViewById(android.R.id.text2);
assertThat(textView2.getText()).isEqualTo(testLabel2);
}
}

View File

@@ -0,0 +1,41 @@
/*
* 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;
import android.content.Context;
import android.content.Intent;
import android.provider.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;
public static void setScheduledLevel(Context context, int scheduledLevel) {
Settings.Global.putInt(context.getContentResolver(),
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, scheduledLevel);
}
public static int getScheduledLevel(Context context) {
return Settings.Global.getInt(context.getContentResolver(),
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, /*defaultValue*/ 0);
}
}

View File

@@ -0,0 +1,81 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
@RunWith(RobolectricTestRunner.class)
public class TestingSettingsBroadcastReceiverTest {
private Context mContext;
private Application mApplication;
private TestingSettingsBroadcastReceiver mReceiver;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mApplication = RuntimeEnvironment.application;
mReceiver = new TestingSettingsBroadcastReceiver();
}
@Test
public void onReceive_nullIntent_shouldNotCrash() {
final Intent intent = new Intent();
mReceiver.onReceive(mContext, null);
mReceiver.onReceive(mContext, intent);
final Intent next = Shadows.shadowOf(mApplication).getNextStartedActivity();
assertThat(next).isNull();
}
@Test
public void onReceive_wrongIntent_shouldNotStartActivity() {
final Intent intent = new Intent();
intent.setAction("");
mReceiver.onReceive(mContext, intent);
final Intent next = Shadows.shadowOf(mApplication).getNextStartedActivity();
assertThat(next).isNull();
}
@Test
public void onReceive_correctIntent_shouldStartActivity() {
final Intent intent = new Intent();
intent.setAction(TelephonyManager.ACTION_SECRET_CODE);
mReceiver.onReceive(mContext, intent);
final Intent next = Shadows.shadowOf(mApplication).getNextStartedActivity();
assertThat(next).isNotNull();
final String dest = next.getComponent().getClassName();
assertThat(dest).isEqualTo(Settings.TestingSettingsActivity.class.getName());
}
}

View File

@@ -0,0 +1,441 @@
/*
* 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;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
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.ActionBar;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyResourcesManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.VectorDrawable;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.util.IconDrawableFactory;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.core.graphics.drawable.IconCompat;
import androidx.fragment.app.FragmentActivity;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowBinder;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowLockPatternUtils.class)
public class UtilsTest {
private static final String PACKAGE_NAME = "com.android.app";
private static final int USER_ID = 1;
@Mock
private WifiManager wifiManager;
@Mock
private Network network;
@Mock
private ConnectivityManager connectivityManager;
@Mock
private DevicePolicyManager mDevicePolicyManager;
@Mock
private DevicePolicyResourcesManager mDevicePolicyResourcesManager;
@Mock
private UserManager mMockUserManager;
@Mock
private PackageManager mPackageManager;
@Mock
private IconDrawableFactory mIconDrawableFactory;
@Mock
private ApplicationInfo mApplicationInfo;
private Context mContext;
private UserManager mUserManager;
private static final int FLAG_SYSTEM = 0x00000000;
private static final int FLAG_MAIN = 0x00004000;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
when(mContext.getSystemService(WifiManager.class)).thenReturn(wifiManager);
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
.thenReturn(connectivityManager);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
}
@After
public void tearDown() {
ShadowLockPatternUtils.reset();
}
@Test
public void getWifiIpAddresses_succeeds() throws Exception {
when(wifiManager.getCurrentNetwork()).thenReturn(network);
LinkAddress address = new LinkAddress(InetAddress.getByName("127.0.0.1"), 0);
LinkProperties lp = new LinkProperties();
lp.addLinkAddress(address);
when(connectivityManager.getLinkProperties(network)).thenReturn(lp);
assertThat(Utils.getWifiIpAddresses(mContext)).isEqualTo("127.0.0.1");
}
@Test
public void getWifiIpAddresses_nullLinkProperties() {
when(wifiManager.getCurrentNetwork()).thenReturn(network);
// Explicitly set the return value to null for readability sake.
when(connectivityManager.getLinkProperties(network)).thenReturn(null);
assertThat(Utils.getWifiIpAddresses(mContext)).isNull();
}
@Test
public void getWifiIpAddresses_nullNetwork() {
// Explicitly set the return value to null for readability sake.
when(wifiManager.getCurrentNetwork()).thenReturn(null);
assertThat(Utils.getWifiIpAddresses(mContext)).isNull();
}
@Test
public void initializeVolumeDoesntBreakOnNullVolume() {
VolumeInfo info = new VolumeInfo("id", 0, new DiskInfo("id", 0), "");
StorageManager storageManager = mock(StorageManager.class, RETURNS_DEEP_STUBS);
when(storageManager.findVolumeById(anyString())).thenReturn(info);
Utils.maybeInitializeVolume(storageManager, new Bundle());
}
@Test
public void isProfileOrDeviceOwner_deviceOwnerApp_returnTrue() {
when(mDevicePolicyManager.isDeviceOwnerAppOnAnyUser(PACKAGE_NAME)).thenReturn(true);
assertThat(
Utils.isProfileOrDeviceOwner(mMockUserManager, mDevicePolicyManager, PACKAGE_NAME))
.isTrue();
}
@Test
public void isProfileOrDeviceOwner_profileOwnerApp_returnTrue() {
final List<UserInfo> userInfos = new ArrayList<>();
userInfos.add(new UserInfo());
when(mMockUserManager.getUsers()).thenReturn(userInfos);
when(mDevicePolicyManager.getProfileOwnerAsUser(userInfos.get(0).id))
.thenReturn(new ComponentName(PACKAGE_NAME, ""));
assertThat(
Utils.isProfileOrDeviceOwner(mMockUserManager, mDevicePolicyManager, PACKAGE_NAME))
.isTrue();
}
@Test
public void setEditTextCursorPosition_shouldGetExpectedEditTextLenght() {
final EditText editText = new EditText(mContext);
final CharSequence text = "test";
editText.setText(text, TextView.BufferType.EDITABLE);
final int length = editText.getText().length();
Utils.setEditTextCursorPosition(editText);
assertThat(editText.getSelectionEnd()).isEqualTo(length);
}
@Test
public void createIconWithDrawable_BitmapDrawable() {
final Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
final BitmapDrawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
final IconCompat icon = Utils.createIconWithDrawable(drawable);
assertThat(icon.getBitmap()).isNotNull();
}
@Test
public void createIconWithDrawable_ColorDrawable() {
final ColorDrawable drawable = new ColorDrawable(Color.BLACK);
final IconCompat icon = Utils.createIconWithDrawable(drawable);
assertThat(icon.getBitmap()).isNotNull();
}
@Test
public void createIconWithDrawable_VectorDrawable() {
final VectorDrawable drawable = VectorDrawable.create(mContext.getResources(),
R.drawable.ic_settings_accent);
final IconCompat icon = Utils.createIconWithDrawable(drawable);
assertThat(icon.getBitmap()).isNotNull();
}
@Test
public void getBadgedIcon_usePackageNameAndUserId()
throws PackageManager.NameNotFoundException {
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfoAsUser(
PACKAGE_NAME, PackageManager.GET_META_DATA, USER_ID);
Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, PACKAGE_NAME, USER_ID);
// Verify that it uses the correct user id
verify(mPackageManager).getApplicationInfoAsUser(eq(PACKAGE_NAME), anyInt(), eq(USER_ID));
verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID);
}
@Test
public void isPackageEnabled_appEnabled_returnTrue()
throws PackageManager.NameNotFoundException{
mApplicationInfo.enabled = true;
when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isTrue();
}
@Test
public void isPackageEnabled_appDisabled_returnTrue()
throws PackageManager.NameNotFoundException{
mApplicationInfo.enabled = false;
when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
}
@Test
public void isPackageEnabled_noApp_returnFalse() {
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
}
@Test
public void setActionBarShadowAnimation_nullParameters_shouldNotCrash() {
// no crash here
Utils.setActionBarShadowAnimation(null, null, null);
}
@Test
public void setActionBarShadowAnimation_shouldSetElevationToZero() {
final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
final ActionBar actionBar = activity.getActionBar();
Utils.setActionBarShadowAnimation(activity, activity.getLifecycle(),
new ScrollView(mContext));
assertThat(actionBar.getElevation()).isEqualTo(0.f);
}
@Test
public void isSettingsIntelligence_IsSI_returnTrue() {
final String siPackageName = mContext.getString(
R.string.config_settingsintelligence_package_name);
ShadowBinder.setCallingUid(USER_ID);
when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{siPackageName});
assertThat(Utils.isSettingsIntelligence(mContext)).isTrue();
}
@Test
public void isSettingsIntelligence_IsNotSI_returnFalse() {
ShadowBinder.setCallingUid(USER_ID);
when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{PACKAGE_NAME});
assertThat(Utils.isSettingsIntelligence(mContext)).isFalse();
}
@Test
public void canCurrentUserDream_isMainUser_returnTrue() {
Context mockContext = mock(Context.class);
UserManager mockUserManager = mock(UserManager.class);
when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
// mock MainUser
UserHandle mainUser = new UserHandle(10);
when(mockUserManager.getMainUser()).thenReturn(mainUser);
when(mockUserManager.isUserForeground()).thenReturn(true);
when(mockContext.createContextAsUser(mainUser, 0)).thenReturn(mockContext);
assertThat(Utils.canCurrentUserDream(mockContext)).isTrue();
}
@Test
public void canCurrentUserDream_nullMainUser_returnFalse() {
Context mockContext = mock(Context.class);
UserManager mockUserManager = mock(UserManager.class);
when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
when(mockUserManager.getMainUser()).thenReturn(null);
assertThat(Utils.canCurrentUserDream(mockContext)).isFalse();
}
@Test
public void canCurrentUserDream_notMainUser_returnFalse() {
Context mockContext = mock(Context.class);
UserManager mockUserManager = mock(UserManager.class);
when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
when(mockUserManager.isUserForeground()).thenReturn(false);
assertThat(Utils.canCurrentUserDream(mockContext)).isFalse();
}
@Test
public void checkUserOwnsFrpCredential_userOwnsFrpCredential_returnUserId() {
ShadowLockPatternUtils.setUserOwnsFrpCredential(true);
assertThat(Utils.checkUserOwnsFrpCredential(mContext, 123)).isEqualTo(123);
}
@Test
public void checkUserOwnsFrpCredential_userNotOwnsFrpCredential_returnUserId() {
ShadowLockPatternUtils.setUserOwnsFrpCredential(false);
assertThrows(
SecurityException.class,
() -> Utils.checkUserOwnsFrpCredential(mContext, 123));
}
@Test
public void getConfirmCredentialStringForUser_Pin_shouldReturnCorrectString() {
setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
when(mContext.getString(R.string.lockpassword_confirm_your_pin_generic))
.thenReturn("PIN");
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PIN);
assertThat(confirmCredentialString).isEqualTo("PIN");
}
@Test
public void getConfirmCredentialStringForUser_Pattern_shouldReturnCorrectString() {
setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
when(mContext.getString(R.string.lockpassword_confirm_your_pattern_generic))
.thenReturn("PATTERN");
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
assertThat(confirmCredentialString).isEqualTo("PATTERN");
}
@Test
public void getConfirmCredentialStringForUser_Password_shouldReturnCorrectString() {
setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
when(mContext.getString(R.string.lockpassword_confirm_your_password_generic))
.thenReturn("PASSWORD");
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
assertThat(confirmCredentialString).isEqualTo("PASSWORD");
}
@Test
public void getConfirmCredentialStringForUser_workPin_shouldReturnNull() {
setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PIN);
assertNull(confirmCredentialString);
}
@Test
public void getConfirmCredentialStringForUser_workPattern_shouldReturnNull() {
setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
assertNull(confirmCredentialString);
}
@Test
public void getConfirmCredentialStringForUser_workPassword_shouldReturnNull() {
setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
assertNull(confirmCredentialString);
}
@Test
public void getConfirmCredentialStringForUser_credentialTypeNone_shouldReturnNull() {
setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
USER_ID, LockPatternUtils.CREDENTIAL_TYPE_NONE);
assertNull(confirmCredentialString);
}
private void setUpForConfirmCredentialString(boolean isEffectiveUserManagedProfile) {
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
when(mMockUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(USER_ID);
when(mMockUserManager.isManagedProfile(USER_ID)).thenReturn(isEffectiveUserManagedProfile);
}
}

View File

@@ -0,0 +1,100 @@
/*
* 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 android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.icu.text.MessageFormat;
import android.text.Html;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityButtonFooterPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityButtonFooterPreferenceControllerTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Spy
private final Resources mResources = mContext.getResources();
@Mock
private PreferenceScreen mScreen;
private AccessibilityButtonFooterPreferenceController mController;
private AccessibilityFooterPreference mPreference;
@Before
public void setUp() {
mController = new AccessibilityButtonFooterPreferenceController(mContext, "test_key");
mPreference = new AccessibilityFooterPreference(mContext);
mPreference.setKey("test_key");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mContext.getResources()).thenReturn(mResources);
}
@Test
public void displayPreference_navigationGestureEnabled_setCorrectTitle() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_GESTURAL);
mController.displayPreference(mScreen);
assertThat(mPreference.getTitle().toString()).isEqualTo(
Html.fromHtml(
MessageFormat.format(mContext.getString(
R.string.accessibility_button_gesture_description), 1, 2, 3),
Html.FROM_HTML_MODE_COMPACT).toString());
}
@Test
public void displayPreference_navigationGestureDisabled_setCorrectTitle() {
when(mResources.getInteger(
com.android.internal.R.integer.config_navBarInteractionMode)).thenReturn(
NAV_BAR_MODE_2BUTTON);
mController.displayPreference(mScreen);
assertThat(mPreference.getTitle().toString()).isEqualTo(
Html.fromHtml(
MessageFormat.format(
mContext.getString(
R.string.accessibility_button_description), 1, 2, 3),
Html.FROM_HTML_MODE_COMPACT).toString());
}
}

View File

@@ -0,0 +1,153 @@
/*
* 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 android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowFragment;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.List;
/** Tests for {@link AccessibilityButtonFragment}. */
@Config(shadows = ShadowFragment.class)
@RunWith(RobolectricTestRunner.class)
public class AccessibilityButtonFragmentTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Spy
private Resources mResources = spy(mContext.getResources());
private AccessibilityButtonFragment mFragment;
@Before
public void setUp() {
mFragment = spy(new TestAccessibilityButtonFragment(mContext));
when(mContext.getResources()).thenReturn(mResources);
when(mFragment.getResources()).thenReturn(mResources);
when(mFragment.getActivity()).thenReturn(Robolectric.setupActivity(FragmentActivity.class));
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_BUTTON_SETTINGS);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo("AccessibilityButtonFragment");
}
@Test
public void onCreate_navigationGestureEnabled_setCorrectTitle() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_GESTURAL);
mFragment.onAttach(mContext);
mFragment.onCreate(Bundle.EMPTY);
assertThat(mFragment.getActivity().getTitle().toString()).isEqualTo(
mContext.getString(R.string.accessibility_button_gesture_title));
}
@Test
public void onCreate_navigationGestureDisabled_setCorrectTitle() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_2BUTTON);
mFragment.onAttach(mContext);
mFragment.onCreate(Bundle.EMPTY);
assertThat(mFragment.getActivity().getTitle().toString()).isEqualTo(
mContext.getString(R.string.accessibility_button_title));
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_button_settings);
assertThat(keys).containsAtLeastElementsIn(niks);
}
private static class TestAccessibilityButtonFragment extends AccessibilityButtonFragment {
private final Context mContext;
private final PreferenceManager mPreferenceManager;
TestAccessibilityButtonFragment(Context context) {
super();
mContext = context;
mPreferenceManager = new PreferenceManager(context);
mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context));
}
@Override
public int getPreferenceScreenResId() {
return R.xml.placeholder_prefs;
}
@Override
public PreferenceScreen getPreferenceScreen() {
return mPreferenceManager.getPreferenceScreen();
}
@Override
public PreferenceManager getPreferenceManager() {
return mPreferenceManager;
}
@Override
public Context getContext() {
return mContext;
}
}
}

View File

@@ -0,0 +1,95 @@
/*
* 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 android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
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.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.provider.Settings;
import androidx.preference.ListPreference;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityButtonGesturePreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityButtonGesturePreferenceControllerTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Spy
private final Resources mResources = mContext.getResources();
private final ContentResolver mContentResolver = mContext.getContentResolver();
private final ListPreference mListPreference = new ListPreference(mContext);
private AccessibilityButtonGesturePreferenceController mController;
@Before
public void setUp() {
mController = new AccessibilityButtonGesturePreferenceController(mContext,
"test_key");
when(mContext.getResources()).thenReturn(mResources);
}
@Test
public void getAvailabilityStatus_navigationGestureEnabled_returnAvailable() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_GESTURAL);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_navigationGestureDisabled_returnConditionallyUnavailable() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_2BUTTON);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void updateState_a11yBtnModeGesture_navigationBarValue() {
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
ACCESSIBILITY_BUTTON_MODE_GESTURE);
mController.updateState(mListPreference);
final String gestureValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_GESTURE);
assertThat(mListPreference.getValue()).isEqualTo(gestureValue);
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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 android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
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.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.provider.Settings;
import androidx.preference.ListPreference;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityButtonLocationPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityButtonLocationPreferenceControllerTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Spy
private final Resources mResources = mContext.getResources();
private final ContentResolver mContentResolver = mContext.getContentResolver();
private final ListPreference mListPreference = new ListPreference(mContext);
private AccessibilityButtonLocationPreferenceController mController;
@Before
public void setUp() {
mController = new AccessibilityButtonLocationPreferenceController(mContext,
"test_key");
when(mContext.getResources()).thenReturn(mResources);
}
@Test
public void getAvailabilityStatus_navigationGestureEnabled_returnConditionallyUnavailable() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_GESTURAL);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_navigationGestureDisabled_returnAvailable() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_2BUTTON);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void updateState_a11yBtnModeNavigationBar_navigationBarValue() {
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
mController.updateState(mListPreference);
final String navigationBarValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
assertThat(mListPreference.getValue()).isEqualTo(navigationBarValue);
}
}

View File

@@ -0,0 +1,127 @@
/*
* 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 android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.search.SearchIndexableRaw;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import java.util.ArrayList;
import java.util.List;
/** Tests for {@link AccessibilityButtonPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityButtonPreferenceControllerTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Spy
private final Resources mResources = mContext.getResources();
@Mock
private PreferenceScreen mScreen;
private Preference mPreference;
private AccessibilityButtonPreferenceController mController;
@Before
public void setUp() {
mController = new AccessibilityButtonPreferenceController(mContext, "test_key");
mPreference = new Preference(mContext);
mPreference.setKey("test_key");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mContext.getResources()).thenReturn(mResources);
}
@Test
public void displayPreference_navigationGestureEnabled_setCorrectTitle() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_GESTURAL);
mController.displayPreference(mScreen);
assertThat(mPreference.getTitle()).isEqualTo(
mContext.getText(R.string.accessibility_button_gesture_title));
}
@Test
public void displayPreference_navigationGestureDisabled_setCorrectTitle() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_2BUTTON);
mController.displayPreference(mScreen);
assertThat(mPreference.getTitle()).isEqualTo(
mContext.getText(R.string.accessibility_button_title));
}
@Test
public void updateDynamicRawDataToIndex_navigationGestureEnabled_setCorrectIndex() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_GESTURAL);
List<SearchIndexableRaw> rawDataList = new ArrayList<>();
mController.updateDynamicRawDataToIndex(rawDataList);
assertThat(rawDataList).hasSize(1);
SearchIndexableRaw raw = rawDataList.get(0);
assertThat(raw.title).isEqualTo(
mResources.getString(R.string.accessibility_button_gesture_title));
assertThat(raw.screenTitle).isEqualTo(
mResources.getString(R.string.accessibility_shortcuts_settings_title));
}
@Test
public void updateDynamicRawDataToIndex_navigationGestureDisabled_setCorrectIndex() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_2BUTTON);
List<SearchIndexableRaw> rawDataList = new ArrayList<>();
mController.updateDynamicRawDataToIndex(rawDataList);
assertThat(rawDataList).hasSize(1);
SearchIndexableRaw raw = rawDataList.get(0);
assertThat(raw.title).isEqualTo(
mResources.getString(R.string.accessibility_button_title));
assertThat(raw.screenTitle).isEqualTo(
mResources.getString(R.string.accessibility_shortcuts_settings_title));
}
}

View File

@@ -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.accessibility;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
import static com.android.settings.testutils.ImageTestUtils.drawableToBitmap;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.widget.IllustrationPreference;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityButtonPreviewPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityButtonPreviewPreferenceControllerTest {
@Rule
public MockitoRule mocks = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private ContentResolver mContentResolver;
private AccessibilityButtonPreviewPreferenceController mController;
@Before
public void setUp() {
when(mContext.getContentResolver()).thenReturn(mContentResolver);
mController = new AccessibilityButtonPreviewPreferenceController(mContext, "test_key");
mController.mIllustrationPreference = new IllustrationPreference(mContext);
}
@Test
public void onChange_a11yBtnModeNavigationBar_getNavigationBarDrawable() {
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
mController.mContentObserver.onChange(false);
final Drawable navigationBarDrawable = mContext.getDrawable(
R.drawable.a11y_button_navigation);
assertThat(drawableToBitmap(mController.mIllustrationPreference.getImageDrawable()).sameAs(
drawableToBitmap(navigationBarDrawable))).isTrue();
}
@Test
public void onChange_updatePreviewPreferenceWithConfig_expectedPreviewDrawable() {
Settings.Secure.putInt(mContentResolver,
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
Settings.Secure.putInt(mContentResolver,
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, /* small size */ 0);
Settings.Secure.putFloat(mContentResolver,
Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.1f);
mController.mContentObserver.onChange(false);
final Drawable smallFloatingMenuWithTenOpacityDrawable =
AccessibilityLayerDrawable.createLayerDrawable(mContext,
R.drawable.a11y_button_preview_small_floating_menu, 10);
assertThat(
mController.mIllustrationPreference.getImageDrawable().getConstantState())
.isEqualTo(smallFloatingMenuWithTenOpacityDrawable.getConstantState());
}
@Test
public void onResume_registerSpecificContentObserver() {
mController.onResume();
verify(mContentResolver).registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE), false,
mController.mContentObserver);
verify(mContentResolver).registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE), false,
mController.mContentObserver);
verify(mContentResolver).registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY),
false,
mController.mContentObserver);
}
@Test
public void onPause_unregisterContentObserver() {
mController.onPause();
verify(mContentResolver).unregisterContentObserver(mController.mContentObserver);
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2022 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.app.settings.SettingsEnums;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link AccessibilityControlTimeoutPreferenceFragment}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityControlTimeoutPreferenceFragmentTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private AccessibilityControlTimeoutPreferenceFragment mFragment;
@Before
public void setUp() {
mFragment = new AccessibilityControlTimeoutPreferenceFragment();
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_TIMEOUT);
}
@Test
public void getPreferenceScreenResId_returnsCorrectXml() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
R.xml.accessibility_control_timeout_settings);
}
@Test
public void getHelpResource_returnsCorrectHelpResource() {
assertThat(mFragment.getHelpResource()).isEqualTo(R.string.help_url_timeout);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo(
"AccessibilityControlTimeoutPreferenceFragment");
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks =
AccessibilityControlTimeoutPreferenceFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_control_timeout_settings);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,227 @@
/*
* 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.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_BUTTON_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
import static com.google.common.truth.Truth.assertThat;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.view.accessibility.AccessibilityManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.SettingsActivity;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowAccessibilityManager;
import org.robolectric.shadows.androidx.fragment.FragmentController;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/** Tests for {@link AccessibilityDetailsSettingsFragment}. */
@Config(shadows = {
ShadowDevicePolicyManager.class,
ShadowRestrictedLockUtilsInternal.class
})
@RunWith(RobolectricTestRunner.class)
public class AccessibilityDetailsSettingsFragmentTest {
private static final String PACKAGE_NAME = "com.foo.bar";
private static final String CLASS_NAME = PACKAGE_NAME + ".fake_a11y_service";
private static final String COMPONENT_NAME = PACKAGE_NAME + "/" + CLASS_NAME;
private Context mContext;
private FragmentController<AccessibilityDetailsSettingsFragment> mFragmentController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
ShadowAccessibilityManager shadowAccessibilityManager = Shadow.extract(
AccessibilityManager.getInstance(mContext));
shadowAccessibilityManager.setInstalledAccessibilityServiceList(getMockServiceList());
}
@Test
public void onCreate_afterSuccessfullyLaunch_shouldBeFinished() {
final Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME);
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
assertThat(fragment.getActivity().isFinishing()).isTrue();
}
@Test
public void onCreate_hasValidExtraComponentName_launchExpectedFragment() {
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME);
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
assertStartActivityWithExpectedFragment(fragment.getActivity(),
ToggleAccessibilityServicePreferenceFragment.class.getName());
}
@Test
public void onCreate_hasInvalidExtraComponentName_launchAccessibilitySettings() {
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, PACKAGE_NAME + "/.service");
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
assertStartActivityWithExpectedFragment(fragment.getActivity(),
AccessibilitySettings.class.getName());
}
@Test
public void onCreate_hasNoExtraComponentName_launchAccessibilitySettings() {
AccessibilityDetailsSettingsFragment fragment = startFragment(/* intent= */ null);
assertStartActivityWithExpectedFragment(fragment.getActivity(),
AccessibilitySettings.class.getName());
}
@Test
public void onCreate_extraComponentNameIsDisallowed_launchAccessibilitySettings() {
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME);
DevicePolicyManager dpm = mContext.getSystemService(
DevicePolicyManager.class);
((ShadowDevicePolicyManager) Shadows.shadowOf(dpm)).setPermittedAccessibilityServices(
ImmutableList.of());
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
assertStartActivityWithExpectedFragment(fragment.getActivity(),
AccessibilitySettings.class.getName());
}
@Test
public void onCreate_magnificationComponentName_launchMagnificationFragment() {
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
MAGNIFICATION_COMPONENT_NAME.flattenToString());
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
assertStartActivityWithExpectedFragment(fragment.getActivity(),
ToggleScreenMagnificationPreferenceFragment.class.getName());
}
@Test
public void onCreate_accessibilityButton_launchAccessibilityButtonFragment() {
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
ACCESSIBILITY_BUTTON_COMPONENT_NAME.flattenToString());
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
assertStartActivityWithExpectedFragment(fragment.getActivity(),
AccessibilityButtonFragment.class.getName());
}
@Test
public void onCreate_hearingAidsComponentName_launchAccessibilityHearingAidsFragment() {
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
AccessibilityDetailsSettingsFragment fragment = startFragment(intent);
assertStartActivityWithExpectedFragment(fragment.getActivity(),
AccessibilityHearingAidsFragment.class.getName());
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
AccessibilityDetailsSettingsFragment fragment = startFragment(/* intent= */ null);
assertThat(fragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_DETAILS_SETTINGS);
}
private AccessibilityDetailsSettingsFragment startFragment(Intent intent) {
mFragmentController = FragmentController.of(
new AccessibilityDetailsSettingsFragment(), intent)
.create()
.visible();
return mFragmentController.get();
}
private AccessibilityServiceInfo getMockAccessibilityServiceInfo() {
final ApplicationInfo applicationInfo = new ApplicationInfo();
final ServiceInfo serviceInfo = new ServiceInfo();
applicationInfo.packageName = PACKAGE_NAME;
serviceInfo.packageName = PACKAGE_NAME;
serviceInfo.name = CLASS_NAME;
serviceInfo.applicationInfo = applicationInfo;
final ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.serviceInfo = serviceInfo;
try {
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
mContext);
ComponentName componentName = ComponentName.unflattenFromString(COMPONENT_NAME);
info.setComponentName(componentName);
return info;
} catch (XmlPullParserException | IOException e) {
// Do nothing
}
return null;
}
private List<AccessibilityServiceInfo> getMockServiceList() {
final List<AccessibilityServiceInfo> infoList = new ArrayList<>();
infoList.add(getMockAccessibilityServiceInfo());
return infoList;
}
private void assertStartActivityWithExpectedFragment(Activity activity, String fragmentName) {
Intent intent = Shadows.shadowOf(activity).getNextStartedActivity();
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
fragmentName);
}
}

View File

@@ -0,0 +1,70 @@
/*
* 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 android.app.Dialog;
import android.content.Context;
import androidx.appcompat.app.AlertDialog;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityDialogUtils} */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityDialogUtilsTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
@Before
public void setUp() {
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
}
@Test
public void updateShortcutInDialog_correctDialogType_success() {
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC, "Title",
null);
assertThat(
AccessibilityDialogUtils.updateShortcutInDialog(mContext, dialog)).isTrue();
}
@Test
public void updateShortcutInDialog_useNotSupportedDialog_fail() {
final AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle("Title").show();
assertThat(AccessibilityDialogUtils.updateShortcutInDialog(mContext,
dialog)).isFalse();
}
@Test
public void showDialog_createCustomDialog_isShowing() {
final Dialog dialog = AccessibilityDialogUtils.createCustomDialog(mContext,
"Title", /* customView= */ null, "positiveButton", /* positiveListener= */ null,
"negativeButton", /* negativeListener= */ null);
dialog.show();
assertThat(dialog.isShowing()).isTrue();
}
}

View File

@@ -0,0 +1,137 @@
/*
* 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.when;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/**
* Tests for {@link AccessibilityFooterPreferenceController}.
*/
@RunWith(RobolectricTestRunner.class)
public class AccessibilityFooterPreferenceControllerTest {
private static final String TEST_KEY = "test_pref_key";
private static final String TEST_TITLE = "test_title";
private static final String TEST_INTRODUCTION_TITLE = "test_introduction_title";
private static final String TEST_CONTENT_DESCRIPTION = "test_content_description";
private static final int TEST_HELP_ID = 12345;
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private PreferenceScreen mScreen;
private AccessibilityFooterPreferenceController mController;
private AccessibilityFooterPreference mPreference;
private PreferenceViewHolder mPreferenceViewHolder;
@Before
public void setUp() {
mController = new AccessibilityFooterPreferenceController(mContext, TEST_KEY);
mPreference = new AccessibilityFooterPreference(mContext);
mPreference.setKey(TEST_KEY);
mPreference.setTitle(TEST_TITLE);
final LayoutInflater inflater = LayoutInflater.from(mContext);
final View view = inflater.inflate(
com.android.settingslib.widget.preference.footer.R.layout.preference_footer, null);
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(view);
mPreference.onBindViewHolder(mPreferenceViewHolder);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
}
@Test
public void setIntroductionTitle_setCorrectIntroductionTitle() {
mController.setIntroductionTitle(TEST_INTRODUCTION_TITLE);
assertThat(mController.getIntroductionTitle()).isEqualTo(TEST_INTRODUCTION_TITLE);
}
@Test
public void onBindViewHolder_setIntroductionTitle_setCorrectIntroductionTitle() {
mController.setIntroductionTitle(TEST_INTRODUCTION_TITLE);
mController.displayPreference(mScreen);
mPreference.onBindViewHolder(mPreferenceViewHolder);
final TextView summaryView = (TextView) mPreferenceViewHolder
.findViewById(android.R.id.title);
assertThat(summaryView.getContentDescription().toString())
.contains(TEST_INTRODUCTION_TITLE);
}
@Test
public void setupHelpLink_setCorrectHelpLinkAndLearnMoreText() {
mController.setupHelpLink(TEST_HELP_ID, TEST_CONTENT_DESCRIPTION);
assertThat(mController.getHelpResource()).isEqualTo(TEST_HELP_ID);
assertThat(mController.getLearnMoreText())
.isEqualTo(TEST_CONTENT_DESCRIPTION);
}
@Test
public void onBindViewHolder_setHelpResource_emptyString_notVisible() {
mController.setupHelpLink(R.string.help_url_timeout, TEST_CONTENT_DESCRIPTION);
mController.displayPreference(mScreen);
mPreference.onBindViewHolder(mPreferenceViewHolder);
final TextView learnMoreView = (TextView) mPreferenceViewHolder
.findViewById(com.android.settingslib.widget.preference.footer.R.id.settingslib_learn_more);
assertThat(learnMoreView.getContentDescription()).isNull();
assertThat(learnMoreView.getVisibility()).isEqualTo(View.GONE);
assertThat(mPreference.isLinkEnabled()).isFalse();
}
@Test
public void onBindViewHolder_setHelpResource_expectSummaryViewIsNonFocusable() {
mController.setupHelpLink(R.string.help_url_timeout, TEST_CONTENT_DESCRIPTION);
mController.displayPreference(mScreen);
mPreference.onBindViewHolder(mPreferenceViewHolder);
final TextView summaryView = (TextView) mPreferenceViewHolder
.findViewById(android.R.id.title);
assertThat(summaryView.isFocusable()).isFalse();
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.text.method.MovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/** Tests for {@link AccessibilityFooterPreference} */
@RunWith(RobolectricTestRunner.class)
public final class AccessibilityFooterPreferenceTest {
private AccessibilityFooterPreference mAccessibilityFooterPreference;
private PreferenceViewHolder mPreferenceViewHolder;
@Before
public void setUp() {
final Context context = RuntimeEnvironment.application;
mAccessibilityFooterPreference = new AccessibilityFooterPreference(context);
final LayoutInflater inflater = LayoutInflater.from(context);
final View view =
inflater.inflate(com.android.settingslib.widget.preference.footer.R.layout.preference_footer, null);
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(view);
}
@Test
public void onBindViewHolder_LinkDisabledByDefault_notReturnLinkMovement() {
mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
android.R.id.title);
assertThat(summaryView.getMovementMethod()).isNull();
}
@Test
public void onBindViewHolder_setLinkEnabled_returnLinkMovement() {
mAccessibilityFooterPreference.setLinkEnabled(true);
mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
android.R.id.title);
assertThat(summaryView.getMovementMethod()).isInstanceOf(MovementMethod.class);
}
@Test
public void onBindViewHolder_setLinkEnabled_expectSummaryViewIsNonFocusable() {
mAccessibilityFooterPreference.setLinkEnabled(true);
mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
android.R.id.title);
assertThat(summaryView.isFocusable()).isFalse();
}
}

View File

@@ -0,0 +1,237 @@
/*
* 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.AccessibilityGestureNavigationTutorial.createAccessibilityTutorialDialog;
import static com.android.settings.accessibility.AccessibilityGestureNavigationTutorial.createAccessibilityTutorialDialogForSetupWizard;
import static com.android.settings.accessibility.AccessibilityGestureNavigationTutorial.createShortcutTutorialPages;
import static com.android.settings.accessibility.AccessibilityGestureNavigationTutorial.showGestureNavigationTutorialDialog;
import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.view.View;
import androidx.appcompat.app.AlertDialog;
import androidx.test.core.app.ApplicationProvider;
import com.android.server.accessibility.Flags;
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.LooperMode;
/** Tests for {@link AccessibilityGestureNavigationTutorial}. */
@RunWith(RobolectricTestRunner.class)
@LooperMode(LooperMode.Mode.LEGACY)
public final class AccessibilityGestureNavigationTutorialTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock
private DialogInterface.OnClickListener mOnClickListener;
@Mock
private DialogInterface.OnDismissListener mOnDismissListener;
private final Context mContext = ApplicationProvider.getApplicationContext();
private int mShortcutTypes;
@Before
public void setUp() {
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
mShortcutTypes = /* initial */ 0;
}
@Test(expected = IllegalArgumentException.class)
public void createTutorialPages_shortcutListIsEmpty_throwsException() {
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
}
@Test
public void createTutorialPages_turnOnTripleTapShortcut_hasOnePage() {
mShortcutTypes |= UserShortcutType.TRIPLETAP;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
assertThat(createShortcutTutorialPages(mContext,
mShortcutTypes)).hasSize(/* expectedSize= */ 1);
assertThat(alertDialog).isNotNull();
}
@Test
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
public void createTutorialPages_turnOnTwoFingerTripleTapShortcut_hasOnePage() {
mShortcutTypes |= UserShortcutType.TWOFINGERTRIPLETAP;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
assertThat(createShortcutTutorialPages(mContext,
mShortcutTypes)).hasSize(/* expectedSize= */ 1);
assertThat(alertDialog).isNotNull();
}
@Test
public void createTutorialPages_turnOnSoftwareShortcut_hasOnePage() {
mShortcutTypes |= UserShortcutType.SOFTWARE;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
assertThat(createShortcutTutorialPages(mContext,
mShortcutTypes)).hasSize(/* expectedSize= */ 1);
assertThat(alertDialog).isNotNull();
}
@Test
public void createTutorialPages_turnOnSoftwareAndHardwareShortcuts_hasTwoPages() {
mShortcutTypes |= UserShortcutType.SOFTWARE;
mShortcutTypes |= UserShortcutType.HARDWARE;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
assertThat(createShortcutTutorialPages(mContext,
mShortcutTypes)).hasSize(/* expectedSize= */ 2);
assertThat(alertDialog).isNotNull();
}
@Test
public void createTutorialPages_turnOnSoftwareShortcut_linkButtonVisible() {
mShortcutTypes |= UserShortcutType.SOFTWARE;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
alertDialog.show();
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
.isEqualTo(View.VISIBLE);
}
@Test
public void createTutorialPages_turnOnSoftwareAndHardwareShortcut_linkButtonVisible() {
mShortcutTypes |= UserShortcutType.SOFTWARE;
mShortcutTypes |= UserShortcutType.HARDWARE;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
alertDialog.show();
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
.isEqualTo(View.VISIBLE);
}
@Test
public void createTutorialPages_turnOnHardwareShortcut_linkButtonGone() {
mShortcutTypes |= UserShortcutType.HARDWARE;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
alertDialog.show();
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void createTutorialPages_turnOnSoftwareShortcut_showFromSuW_linkButtonGone() {
mShortcutTypes |= UserShortcutType.SOFTWARE;
final AlertDialog alertDialog =
createAccessibilityTutorialDialogForSetupWizard(mContext, mShortcutTypes);
alertDialog.show();
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void performClickOnPositiveButton_turnOnSoftwareShortcut_dismiss() {
mShortcutTypes |= UserShortcutType.SOFTWARE;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
alertDialog.show();
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
assertThat(alertDialog.isShowing()).isFalse();
}
@Test
public void performClickOnPositiveButton_turnOnSoftwareShortcut_callOnClickListener() {
mShortcutTypes |= UserShortcutType.SOFTWARE;
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes, mOnClickListener);
alertDialog.show();
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
verify(mOnClickListener).onClick(alertDialog, DialogInterface.BUTTON_POSITIVE);
}
@Test
public void performClickOnNegativeButton_turnOnSoftwareShortcut_directToSettingsPage() {
mShortcutTypes |= UserShortcutType.SOFTWARE;
Activity activity = Robolectric.buildActivity(Activity.class).create().get();
final AlertDialog alertDialog = createAccessibilityTutorialDialog(activity, mShortcutTypes);
alertDialog.show();
alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
final Intent intent = shadowOf(activity).peekNextStartedActivity();
assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName());
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
.isEqualTo(AccessibilityButtonFragment.class.getName());
assertThat(intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1))
.isEqualTo(SettingsEnums.SWITCH_SHORTCUT_DIALOG_ACCESSIBILITY_BUTTON_SETTINGS);
}
@Test
public void performClickOnPositiveButton_turnOnGestureShortcut_callOnDismissListener() {
final AlertDialog alertDialog =
showGestureNavigationTutorialDialog(mContext, mOnDismissListener);
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
assertThat(alertDialog.isShowing()).isFalse();
verify(mOnDismissListener).onDismiss(alertDialog);
}
}

View File

@@ -0,0 +1,320 @@
/*
* Copyright 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import android.app.Application;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHapClient;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.HapClientProfile;
import com.android.settingslib.bluetooth.HearingAidInfo;
import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowApplication;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/** Tests for {@link AccessibilityHearingAidPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class, ShadowBluetoothUtils.class})
public class AccessibilityHearingAidPreferenceControllerTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
private static final String TEST_DEVICE_ADDRESS_2 = "00:A2:A2:A2:A2:A2";
private static final String TEST_DEVICE_NAME = "TEST_HEARING_AID_BT_DEVICE_NAME";
private static final String HEARING_AID_PREFERENCE = "hearing_aid_preference";
private BluetoothAdapter mBluetoothAdapter;
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
private BluetoothDevice mBluetoothDevice;
private final Context mContext = ApplicationProvider.getApplicationContext();
private Preference mHearingAidPreference;
private AccessibilityHearingAidPreferenceController mPreferenceController;
private ShadowApplication mShadowApplication;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
@Mock
private CachedBluetoothDevice mCachedSubBluetoothDevice;
@Mock
private CachedBluetoothDeviceManager mCachedDeviceManager;
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
@Mock
private BluetoothEventManager mEventManager;
@Mock
private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
@Mock
private HearingAidProfile mHearingAidProfile;
@Mock
private HapClientProfile mHapClientProfile;
@Before
public void setUp() {
mShadowApplication = shadowOf((Application) ApplicationProvider.getApplicationContext());
setupEnvironment();
mHearingAidPreference = new Preference(mContext);
mHearingAidPreference.setKey(HEARING_AID_PREFERENCE);
mPreferenceController = new AccessibilityHearingAidPreferenceController(mContext,
HEARING_AID_PREFERENCE);
mPreferenceController.setPreference(mHearingAidPreference);
mHearingAidPreference.setSummary("");
}
@After
public void tearDown() {
ShadowBluetoothUtils.reset();
}
@Test
public void getSummary_connectedAshaHearingAidRightSide_connectedRightSideSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_RIGHT);
when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
mPreferenceController.onStart();
Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_CONNECTED);
sendIntent(intent);
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
"TEST_HEARING_AID_BT_DEVICE_NAME, right only")).isTrue();
}
@Test
public void getSummary_connectedAshaHearingAidBothSide_connectedBothSideSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_LEFT);
when(mCachedSubBluetoothDevice.isConnected()).thenReturn(true);
when(mCachedBluetoothDevice.getSubDevice()).thenReturn(mCachedSubBluetoothDevice);
when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
mPreferenceController.onStart();
Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_CONNECTED);
sendIntent(intent);
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
"TEST_HEARING_AID_BT_DEVICE_NAME, left and right")).isTrue();
}
@Test
public void getSummary_connectedLeAudioHearingAidLeftSide_connectedLeftSideSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_LEFT);
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(new HashSet<>());
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
mPreferenceController.onStart();
Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHapClient.STATE_CONNECTED);
sendIntent(intent);
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
"TEST_HEARING_AID_BT_DEVICE_NAME, left only")).isTrue();
}
@Test
public void getSummary_connectedLeAudioHearingAidRightSide_connectedRightSideSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_RIGHT);
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(new HashSet<>());
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
mPreferenceController.onStart();
Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHapClient.STATE_CONNECTED);
sendIntent(intent);
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
"TEST_HEARING_AID_BT_DEVICE_NAME, right only")).isTrue();
}
@Test
public void getSummary_connectedLeAudioHearingAidLeftAndRightSide_connectedSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_LEFT_AND_RIGHT);
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(new HashSet<>());
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
mPreferenceController.onStart();
Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHapClient.STATE_CONNECTED);
sendIntent(intent);
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
"TEST_HEARING_AID_BT_DEVICE_NAME, left and right")).isTrue();
}
@Test
public void getSummary_connectedLeAudioHearingAidBothSide_connectedBothSideSummary() {
when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(generateMemberDevices());
when(mCachedSubBluetoothDevice.isConnected()).thenReturn(true);
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
mPreferenceController.onStart();
Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHapClient.STATE_CONNECTED);
sendIntent(intent);
assertThat(mHearingAidPreference.getSummary().toString()).isEqualTo(
"TEST_HEARING_AID_BT_DEVICE_NAME, left and right");
}
@Test
public void getSummary_connectedMultipleHearingAids_connectedMultipleDevicesSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_LEFT);
when(mHearingAidProfile.getConnectedDevices()).thenReturn(
generateMultipleHearingAidDeviceList());
mPreferenceController.onStart();
Intent intent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothHearingAid.EXTRA_STATE, BluetoothHearingAid.STATE_CONNECTED);
sendIntent(intent);
assertThat(mHearingAidPreference.getSummary().toString().contentEquals(
"TEST_HEARING_AID_BT_DEVICE_NAME +1 more")).isTrue();
}
@Test
public void getSummary_bluetoothOff_disconnectedSummary() {
mPreferenceController.onStart();
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
sendIntent(intent);
assertThat(mHearingAidPreference.getSummary()).isEqualTo(
mContext.getText(R.string.accessibility_hearingaid_not_connected_summary));
}
@Test
public void onServiceConnected_onHearingAidProfileConnected_updateSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_LEFT);
when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
mPreferenceController.onStart();
mPreferenceController.onServiceConnected();
assertThat(mHearingAidPreference.getSummary().toString()).isEqualTo(
"TEST_HEARING_AID_BT_DEVICE_NAME, left only");
}
@Test
public void onServiceConnected_onHapClientProfileConnected_updateSummary() {
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_RIGHT);
when(mHapClientProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
mPreferenceController.onStart();
mPreferenceController.onServiceConnected();
assertThat(mHearingAidPreference.getSummary().toString()).isEqualTo(
"TEST_HEARING_AID_BT_DEVICE_NAME, right only");
}
private void setupEnvironment() {
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mShadowBluetoothAdapter = Shadow.extract(mBluetoothAdapter);
mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HAP_CLIENT);
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS);
mBluetoothAdapter.enable();
doReturn(mEventManager).when(mLocalBluetoothManager).getEventManager();
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
when(mLocalBluetoothProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile);
when(mHearingAidProfile.isProfileReady()).thenReturn(true);
when(mHapClientProfile.isProfileReady()).thenReturn(true);
when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
when(mCachedBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME);
}
private void sendIntent(Intent intent) {
for (BroadcastReceiver receiver : mShadowApplication.getReceiversForIntent(intent)) {
receiver.onReceive(mContext, intent);
}
}
private List<BluetoothDevice> generateHearingAidDeviceList() {
final List<BluetoothDevice> deviceList = new ArrayList<>(1);
deviceList.add(mBluetoothDevice);
return deviceList;
}
private List<BluetoothDevice> generateMultipleHearingAidDeviceList() {
// Generates different Bluetooth devices for testing multiple devices
final List<BluetoothDevice> deviceList = new ArrayList<>(2);
deviceList.add(mBluetoothDevice);
deviceList.add(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2));
return deviceList;
}
private Set<CachedBluetoothDevice> generateMemberDevices() {
final Set<CachedBluetoothDevice> memberDevices = new HashSet<>();
memberDevices.add(mCachedSubBluetoothDevice);
return memberDevices;
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2022 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.telephony.TelephonyManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link AccessibilityHearingAidsFragment}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityHearingAidsFragmentTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private TelephonyManager mTelephonyManager;
@Before
public void setUp() {
mTelephonyManager = spy(mContext.getSystemService(TelephonyManager.class));
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
doReturn(true).when(mTelephonyManager).isHearingAidCompatibilitySupported();
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = AccessibilityHearingAidsFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_hearing_aids);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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 android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.ImageTestUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityLayerDrawable}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityLayerDrawableTest {
private static final int TEST_RES_ID =
com.android.internal.R.drawable.ic_accessibility_magnification;
private static final int TEST_RES_ID_2 =
com.android.internal.R.drawable.ic_accessibility_color_inversion;
private final Context mContext = ApplicationProvider.getApplicationContext();
@Test
public void createLayerDrawable_configCorrect() {
final Drawable expected1stDrawable = mContext.getDrawable(
R.drawable.a11y_button_preview_base);
final Drawable expected2ndDrawable = mContext.getDrawable(TEST_RES_ID);
final AccessibilityLayerDrawable actualDrawable =
AccessibilityLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID,
/* opacity= */ 27);
final Drawable actual1stDrawable = actualDrawable.getDrawable(0);
final Drawable actual2ndDrawable = actualDrawable.getDrawable(1);
assertThat(ImageTestUtils.drawableToBitmap(actual1stDrawable).sameAs(
ImageTestUtils.drawableToBitmap(expected1stDrawable))).isTrue();
assertThat(ImageTestUtils.drawableToBitmap(actual2ndDrawable).sameAs(
ImageTestUtils.drawableToBitmap(expected2ndDrawable))).isTrue();
}
@Test
public void updateLayerDrawable_expectedFloatingMenuLayerDrawableState() {
final AccessibilityLayerDrawable originalDrawable =
AccessibilityLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID, /* opacity= */
72);
originalDrawable.updateLayerDrawable(mContext, TEST_RES_ID_2, /* opacity= */ 27);
assertThat(originalDrawable.getConstantState()).isEqualTo(
new AccessibilityLayerDrawable.AccessibilityLayerDrawableState(mContext,
TEST_RES_ID_2, /* opacity= */ 27));
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2022 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 org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityQuickSettingUtils}. */
@RunWith(RobolectricTestRunner.class)
public final class AccessibilityQuickSettingUtilsTest {
private static final String DUMMY_PACKAGE_NAME = "com.mock.example";
private static final String DUMMY_CLASS_NAME = DUMMY_PACKAGE_NAME + ".mock_a11y_service";
private static final String DUMMY_CLASS_NAME2 = DUMMY_PACKAGE_NAME + ".mock_a11y_service2";
private static final ComponentName DUMMY_COMPONENT_NAME = new ComponentName(DUMMY_PACKAGE_NAME,
DUMMY_CLASS_NAME);
private static final ComponentName DUMMY_COMPONENT_NAME2 = new ComponentName(DUMMY_PACKAGE_NAME,
DUMMY_CLASS_NAME2);
private final Context mContext = ApplicationProvider.getApplicationContext();
@Test
public void optInValueToSharedPreferences_optInValue_haveMatchString() {
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(mContext,
DUMMY_COMPONENT_NAME);
assertThat(AccessibilityQuickSettingUtils.hasValueInSharedPreferences(mContext,
DUMMY_COMPONENT_NAME)).isTrue();
}
@Test
public void optInValueToSharedPreferences_optInTwoValues_haveMatchString() {
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(mContext,
DUMMY_COMPONENT_NAME);
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(mContext,
DUMMY_COMPONENT_NAME2);
assertThat(AccessibilityQuickSettingUtils.hasValueInSharedPreferences(mContext,
DUMMY_COMPONENT_NAME)).isTrue();
assertThat(AccessibilityQuickSettingUtils.hasValueInSharedPreferences(mContext,
DUMMY_COMPONENT_NAME2)).isTrue();
}
}

View File

@@ -0,0 +1,198 @@
/*
* Copyright (C) 2022 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.ToggleFeaturePreferenceFragment.KEY_SAVED_QS_TOOLTIP_RESHOW;
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.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settingslib.PrimarySwitchPreference;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowApplication;
/**
* Tests for {@link AccessibilityQuickSettingsPrimarySwitchPreferenceController}.
*/
@RunWith(RobolectricTestRunner.class)
@LooperMode(LooperMode.Mode.LEGACY)
public class AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest {
private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
private static final String PLACEHOLDER_TILE_CLASS_NAME =
PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
private static final CharSequence PLACEHOLDER_TILE_CONTENT =
PLACEHOLDER_TILE_CLASS_NAME + ".tile.content";
private static final String TEST_KEY = "test_pref_key";
private static final String TEST_TITLE = "test_title";
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private TestAccessibilityQuickSettingsPrimarySwitchPreferenceController mController;
private PrimarySwitchPreference mPreference;
private TestFragment mFragment;
private PreferenceScreen mScreen;
private PreferenceViewHolder mHolder;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceManager mPreferenceManager;
private static PopupWindow getLatestPopupWindow() {
final ShadowApplication shadowApplication =
Shadow.extract(ApplicationProvider.getApplicationContext());
return shadowApplication.getLatestPopupWindow();
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
mFragment = spy(new TestFragment());
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
when(mFragment.getContext()).thenReturn(mContext);
mScreen = spy(new PreferenceScreen(mContext, /* attrs= */ null));
when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
doReturn(mScreen).when(mFragment).getPreferenceScreen();
mPreference = new PrimarySwitchPreference(mContext);
mPreference.setKey(TEST_KEY);
mPreference.setTitle(TEST_TITLE);
LayoutInflater inflater = LayoutInflater.from(mContext);
mHolder = PreferenceViewHolder.createInstanceForTests(inflater.inflate(
com.android.settingslib.widget.preference.twotarget.R.layout.preference_two_target, null));
LinearLayout mWidgetView = mHolder.itemView.findViewById(android.R.id.widget_frame);
inflater.inflate(R.layout.preference_widget_primary_switch, mWidgetView, true);
mPreference.onBindViewHolder(mHolder);
mController = new TestAccessibilityQuickSettingsPrimarySwitchPreferenceController(mContext,
TEST_KEY);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
}
@Test
public void setChecked_showTooltipView() {
mController.displayPreference(mScreen);
mController.setChecked(true);
assertThat(getLatestPopupWindow().isShowing()).isTrue();
}
@Test
public void setChecked_notCallDisplayPreference_notShowTooltipView() {
// Simulates the slice highlight menu that does not call {@link #displayPreference} before
// {@link #setChecked} called.
mController.setChecked(true);
assertThat(getLatestPopupWindow()).isNull();
}
@Test
public void setChecked_tooltipViewShown_notShowTooltipView() {
mController.displayPreference(mScreen);
mController.setChecked(true);
getLatestPopupWindow().dismiss();
mController.setChecked(false);
mController.setChecked(true);
assertThat(getLatestPopupWindow().isShowing()).isFalse();
}
@Test
@Config(shadows = ShadowFragment.class)
public void restoreValueFromSavedInstanceState_showTooltipView() {
final Bundle savedInstanceState = new Bundle();
savedInstanceState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
mController.onCreate(savedInstanceState);
mController.displayPreference(mScreen);
assertThat(getLatestPopupWindow().isShowing()).isTrue();
}
public static class TestAccessibilityQuickSettingsPrimarySwitchPreferenceController
extends AccessibilityQuickSettingsPrimarySwitchPreferenceController {
public TestAccessibilityQuickSettingsPrimarySwitchPreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey);
}
@Override
ComponentName getTileComponentName() {
return PLACEHOLDER_TILE_COMPONENT_NAME;
}
@Override
CharSequence getTileTooltipContent() {
return PLACEHOLDER_TILE_CONTENT;
}
}
private static class TestFragment extends SettingsPreferenceFragment {
@Override
protected boolean shouldSkipForInitialSUW() {
return false;
}
@Override
public int getMetricsCategory() {
return 0;
}
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2022 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.verify;
import static org.robolectric.Shadows.shadowOf;
import android.app.Application;
import android.content.Context;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.PopupWindow;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowLooper;
/** Tests for {@link AccessibilityQuickSettingsTooltipWindow}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityQuickSettingsTooltipWindowTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PopupWindow.OnDismissListener mMockOnDismissListener;
private static final String TEST_PACKAGE_NAME = "com.test.package";
private static final int TEST_RES_ID = 1234;
private final Context mContext = ApplicationProvider.getApplicationContext();
private AccessibilityQuickSettingsTooltipWindow mTooltipView;
private View mView;
@Before
public void setUp() {
mTooltipView = new AccessibilityQuickSettingsTooltipWindow(mContext);
mView = new View(mContext);
}
@Test
public void initTooltipView_atMostAvailableTextWidth() {
final String quickSettingsTooltipsContent = mContext.getString(
R.string.accessibility_service_qs_tooltip_content, TEST_PACKAGE_NAME);
mTooltipView.setup(quickSettingsTooltipsContent, TEST_RES_ID);
final int getMaxWidth = mTooltipView.getAvailableWindowWidth();
assertThat(mTooltipView.getWidth()).isAtMost(getMaxWidth);
}
@Test
public void showTooltipView_success() {
mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
assertThat(getLatestPopupWindow()).isNull();
mTooltipView.showAtTopCenter(mView);
assertThat(getLatestPopupWindow()).isSameInstanceAs(mTooltipView);
}
@Test
public void accessibilityClickActionOnTooltipViewShown_shouldInvokeCallbackAndNotShowing() {
mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
mTooltipView.setOnDismissListener(mMockOnDismissListener);
mTooltipView.showAtTopCenter(mView);
final boolean isActionPerformed =
mTooltipView.getContentView().performAccessibilityAction(
AccessibilityNodeInfo.ACTION_CLICK,
/* arguments= */ null);
assertThat(isActionPerformed).isTrue();
verify(mMockOnDismissListener).onDismiss();
assertThat(getLatestPopupWindow().isShowing()).isFalse();
}
@Test
public void dismiss_tooltipViewShown_shouldInvokeCallbackAndNotShowing() {
mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
mTooltipView.setOnDismissListener(mMockOnDismissListener);
mTooltipView.showAtTopCenter(mView);
mTooltipView.dismiss();
verify(mMockOnDismissListener).onDismiss();
assertThat(getLatestPopupWindow().isShowing()).isFalse();
}
@Test
public void waitAutoCloseDelayTime_tooltipViewShown_shouldInvokeCallbackAndNotShowing() {
mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID, /* closeDelayTimeMillis= */ 1);
mTooltipView.setOnDismissListener(mMockOnDismissListener);
mTooltipView.showAtTopCenter(mView);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
verify(mMockOnDismissListener).onDismiss();
assertThat(getLatestPopupWindow().isShowing()).isFalse();
}
private static PopupWindow getLatestPopupWindow() {
final ShadowApplication shadowApplication = shadowOf(
(Application) ApplicationProvider.getApplicationContext());
return shadowApplication.getLatestPopupWindow();
}
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 2022 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.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.os.Handler;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowContentResolver;
import java.util.Collection;
import java.util.List;
/** Test for {@link AccessibilitySettingsContentObserver}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilitySettingsContentObserverTest {
private static final String SPECIFIC_KEY_A_1 = "SPECIFIC_KEY_A_1";
private static final String SPECIFIC_KEY_A_2 = "SPECIFIC_KEY_A_2";
private static final String SPECIFIC_KEY_B_1 = "SPECIFIC_KEY_B_1";
private final Context mContext = ApplicationProvider.getApplicationContext();
private final AccessibilitySettingsContentObserver mObserver =
new AccessibilitySettingsContentObserver(new Handler());
private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackA =
spy(new TestableContentObserverCallback());
private final AccessibilitySettingsContentObserver.ContentObserverCallback mObserverCallbackB =
spy(new TestableContentObserverCallback());
private final ContentResolver mContentResolver = mContext.getContentResolver();
@Test
public void register_shouldRegisterContentObserverForDefaultKeys() {
mObserver.register(mContentResolver);
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
assertObserverToUri(shadowContentResolver,
Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
assertObserverToUri(shadowContentResolver,
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
}
@Test
public void unregister_shouldUnregisterContentObserver() {
mObserver.register(mContentResolver);
mObserver.unregister(mContentResolver);
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
assertNotObserverToUri(shadowContentResolver, Settings.Secure.ACCESSIBILITY_ENABLED);
assertNotObserverToUri(shadowContentResolver,
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
}
@Test
public void register_addSpecificKeys_shouldRegisterContentObserverForSpecificAndDefaultKeys() {
mObserver.registerKeysToObserverCallback(List.of(SPECIFIC_KEY_A_1), mObserverCallbackA);
mObserver.register(mContentResolver);
ShadowContentResolver shadowContentResolver = Shadow.extract(mContentResolver);
assertObserverToUri(shadowContentResolver,
Settings.Secure.ACCESSIBILITY_ENABLED, mObserver);
assertObserverToUri(shadowContentResolver,
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mObserver);
assertObserverToUri(shadowContentResolver, SPECIFIC_KEY_A_1, mObserver);
}
@Test
public void onChange_shouldTriggerCallbackOnDefaultKey() {
mObserver.registerObserverCallback(mObserverCallbackA);
mObserver.register(mContentResolver);
mObserver.onChange(/* selfChange= */ false,
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_ENABLED));
verify(mObserverCallbackA).onChange(Settings.Secure.ACCESSIBILITY_ENABLED);
}
@Test
public void onChange_registerSpecificKeys_shouldTriggerSpecificCallback() {
mObserver.registerKeysToObserverCallback(
List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
mObserver.register(mContentResolver);
mObserver.onChange(/* selfChange= */ false,
Settings.Secure.getUriFor(SPECIFIC_KEY_A_2));
verify(mObserverCallbackA).onChange(SPECIFIC_KEY_A_2);
}
@Test
public void onChange_registerSpecificKeys_withoutTriggerOtherCallback() {
mObserver.registerKeysToObserverCallback(
List.of(SPECIFIC_KEY_A_1, SPECIFIC_KEY_A_2), mObserverCallbackA);
mObserver.registerKeysToObserverCallback(
List.of(SPECIFIC_KEY_B_1), mObserverCallbackB);
mObserver.register(mContentResolver);
mObserver.onChange(/* selfChange= */ false,
Settings.Secure.getUriFor(SPECIFIC_KEY_B_1));
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_1);
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_A_2);
verify(mObserverCallbackA, never()).onChange(SPECIFIC_KEY_B_1);
verify(mObserverCallbackB).onChange(SPECIFIC_KEY_B_1);
}
@After
public void tearDown() {
mObserver.unregister(mContentResolver);
}
private void assertNotObserverToUri(ShadowContentResolver resolver, String key) {
assertThat(resolver.getContentObservers(Settings.Secure.getUriFor(key))).isEmpty();
}
private void assertObserverToUri(ShadowContentResolver resolver,
String key, ContentObserver observer) {
Collection<ContentObserver> observers =
resolver.getContentObservers(Settings.Secure.getUriFor(key));
assertThat(observers).contains(observer);
}
private static class TestableContentObserverCallback implements
AccessibilitySettingsContentObserver.ContentObserverCallback {
@Override
public void onChange(String key) {
// do nothing
}
}
}

View File

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2022 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.AccessibilitySettingsForSetupWizard.SCREEN_READER_PACKAGE_NAME;
import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SCREEN_READER_SERVICE_NAME;
import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SELECT_TO_SPEAK_PACKAGE_NAME;
import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizard.SELECT_TO_SPEAK_SERVICE_NAME;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
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.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.view.accessibility.AccessibilityManager;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.RestrictedPreference;
import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupdesign.GlifPreferenceLayout;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
/**
* Tests for {@link AccessibilitySettingsForSetupWizard}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
})
public class AccessibilitySettingsForSetupWizardTest {
private static final ComponentName TEST_SCREEN_READER_COMPONENT_NAME = new ComponentName(
SCREEN_READER_PACKAGE_NAME, SCREEN_READER_SERVICE_NAME);
private static final ComponentName TEST_SELECT_TO_SPEAK_COMPONENT_NAME = new ComponentName(
SELECT_TO_SPEAK_PACKAGE_NAME, SELECT_TO_SPEAK_SERVICE_NAME);
private final Context mContext = ApplicationProvider.getApplicationContext();
private final List<AccessibilityServiceInfo> mAccessibilityServices = new ArrayList<>();
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private AccessibilityManager mAccessibilityManager;
@Mock
private FragmentActivity mActivity;
@Mock
private GlifPreferenceLayout mGlifLayoutView;
@Mock
private FooterBarMixin mFooterBarMixin;
private AccessibilitySettingsForSetupWizard mFragment;
@Before
public void setUp() {
mFragment = spy(new TestAccessibilitySettingsForSetupWizard(mContext));
doReturn(mAccessibilityManager).when(mActivity).getSystemService(
AccessibilityManager.class);
when(mAccessibilityManager.getInstalledAccessibilityServiceList()).thenReturn(
mAccessibilityServices);
doReturn(mActivity).when(mFragment).getActivity();
doReturn(mock(LifecycleOwner.class)).when(mFragment).getViewLifecycleOwner();
doReturn(mFooterBarMixin).when(mGlifLayoutView).getMixin(FooterBarMixin.class);
}
@Test
public void onViewCreated_verifyAction() {
mFragment.onViewCreated(mGlifLayoutView, null);
verify(mGlifLayoutView).setHeaderText(
mContext.getString(R.string.vision_settings_title));
verify(mGlifLayoutView).setDescriptionText(
mContext.getString(R.string.vision_settings_description));
verify(mFooterBarMixin).setPrimaryButton(any());
}
@Test
public void onResume_accessibilityServiceListInstalled_returnExpectedValue() {
addEnabledServiceInfo(TEST_SCREEN_READER_COMPONENT_NAME, true);
addEnabledServiceInfo(TEST_SELECT_TO_SPEAK_COMPONENT_NAME, true);
mFragment.onAttach(mContext);
mFragment.onViewCreated(mGlifLayoutView, null);
mFragment.onResume();
assertRestrictedPreferenceMatch(mFragment.mScreenReaderPreference,
TEST_SCREEN_READER_COMPONENT_NAME.getPackageName(),
TEST_SCREEN_READER_COMPONENT_NAME.flattenToString());
assertRestrictedPreferenceMatch(mFragment.mSelectToSpeakPreference,
TEST_SELECT_TO_SPEAK_COMPONENT_NAME.getPackageName(),
TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
}
@Test
public void onResume_accessibilityServiceListNotInstalled_returnNull() {
mFragment.onAttach(mContext);
mFragment.onViewCreated(mGlifLayoutView, null);
mFragment.onResume();
assertThat(mFragment.mScreenReaderPreference.getKey()).isNull();
assertThat(mFragment.mSelectToSpeakPreference.getKey()).isNull();
}
private void addEnabledServiceInfo(ComponentName componentName, boolean isAccessibilityTool) {
final AccessibilityServiceInfo a11yServiceInfo = mock(AccessibilityServiceInfo.class);
when(a11yServiceInfo.getComponentName()).thenReturn(componentName);
when(a11yServiceInfo.isAccessibilityTool()).thenReturn(isAccessibilityTool);
final ResolveInfo resolveInfo = mock(ResolveInfo.class);
when(a11yServiceInfo.getResolveInfo()).thenReturn(resolveInfo);
resolveInfo.serviceInfo = mock(ServiceInfo.class);
resolveInfo.serviceInfo.packageName = componentName.getPackageName();
resolveInfo.serviceInfo.name = componentName.getClassName();
when(resolveInfo.loadLabel(mActivity.getPackageManager())).thenReturn(
componentName.getPackageName());
mAccessibilityServices.add(a11yServiceInfo);
}
private void assertRestrictedPreferenceMatch(RestrictedPreference preference, String title,
String key) {
assertThat(preference.getTitle().toString()).isEqualTo(title);
assertThat(preference.getKey()).isEqualTo(key);
assertThat(preference.getExtras().getString(AccessibilitySettings.EXTRA_TITLE))
.isEqualTo(title);
assertThat(preference.getExtras().getString(AccessibilitySettings.EXTRA_PREFERENCE_KEY))
.isEqualTo(key);
}
private static class TestAccessibilitySettingsForSetupWizard
extends AccessibilitySettingsForSetupWizard {
private final Context mContext;
private final PreferenceManager mPreferenceManager;
TestAccessibilitySettingsForSetupWizard(Context context) {
super();
mContext = context;
mPreferenceManager = new PreferenceManager(context);
mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context));
mDisplayMagnificationPreference = new Preference(context);
mScreenReaderPreference = new RestrictedPreference(context);
mSelectToSpeakPreference = new RestrictedPreference(context);
}
@Override
public int getPreferenceScreenResId() {
return R.xml.placeholder_prefs;
}
@Override
public PreferenceScreen getPreferenceScreen() {
return mPreferenceManager.getPreferenceScreen();
}
@Override
public PreferenceManager getPreferenceManager() {
return mPreferenceManager;
}
@Override
public Context getContext() {
return mContext;
}
}
}

View File

@@ -0,0 +1,494 @@
/*
* 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 com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import static java.util.Collections.singletonList;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityShortcutInfo;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.database.ContentObserver;
import android.os.Build;
import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
import androidx.fragment.app.Fragment;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.content.PackageMonitor;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowApplicationPackageManager;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.testutils.shadow.ShadowColorDisplayManager;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowAccessibilityManager;
import org.robolectric.shadows.ShadowContentResolver;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/** Test for {@link AccessibilitySettings}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ShadowBluetoothAdapter.class,
ShadowUserManager.class,
ShadowColorDisplayManager.class,
ShadowApplicationPackageManager.class,
ShadowRestrictedLockUtilsInternal.class,
})
public class AccessibilitySettingsTest {
private static final String PACKAGE_NAME = "com.android.test";
private static final String CLASS_NAME = PACKAGE_NAME + ".test_a11y_service";
private static final ComponentName COMPONENT_NAME = new ComponentName(PACKAGE_NAME, CLASS_NAME);
private static final String EMPTY_STRING = "";
private static final String DEFAULT_SUMMARY = "default summary";
private static final String DEFAULT_DESCRIPTION = "default description";
private static final String DEFAULT_LABEL = "default label";
private static final Boolean SERVICE_ENABLED = true;
private static final Boolean SERVICE_DISABLED = false;
@Rule
public final MockitoRule mocks = MockitoJUnit.rule();
private final Context mContext = ApplicationProvider.getApplicationContext();
@Spy
private final AccessibilityServiceInfo mServiceInfo = getMockAccessibilityServiceInfo(
PACKAGE_NAME, CLASS_NAME);
@Mock
private AccessibilityShortcutInfo mShortcutInfo;
private ShadowAccessibilityManager mShadowAccessibilityManager;
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
private ActivityController<SettingsActivity> mActivityController;
private AccessibilitySettings mFragment;
@Before
public void setup() {
mShadowAccessibilityManager = Shadow.extract(AccessibilityManager.getInstance(mContext));
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(new ArrayList<>());
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
setMockAccessibilityShortcutInfo(mShortcutInfo);
Intent intent = new Intent();
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT,
AccessibilitySettings.class.getName());
mActivityController = ActivityController.of(new SettingsActivity(), intent);
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_settings);
assertThat(keys).containsAtLeastElementsIn(niks);
}
@Test
public void getRawDataToIndex_isNull() {
final List<SearchIndexableRaw> indexableRawList =
AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER
.getRawDataToIndex(mContext, true);
assertThat(indexableRawList).isNull();
}
@Test
public void getServiceSummary_serviceCrash_showsStopped() {
mServiceInfo.crashed = true;
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED);
assertThat(summary).isEqualTo(
mContext.getString(R.string.accessibility_summary_state_stopped));
}
@Test
public void getServiceSummary_invisibleToggle_shortcutEnabled_showsOnSummary() {
setInvisibleToggleFragmentType(mServiceInfo);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED);
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_invisibleToggle_shortcutDisabled_showsOffSummary() {
setInvisibleToggleFragmentType(mServiceInfo);
setShortcutEnabled(mServiceInfo.getComponentName(), false);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED);
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_enableServiceShortcutOn_showsServiceEnabledShortcutOn() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.generic_accessibility_service_on));
}
@Test
public void getServiceSummary_enableServiceShortcutOff_showsServiceEnabledShortcutOff() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), false);
String summary = AccessibilitySettings.getServiceSummary(
mContext, mServiceInfo, SERVICE_ENABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.generic_accessibility_service_on));
}
@Test
public void getServiceSummary_disableServiceShortcutOff_showsDisabledShortcutOff() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), false);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.generic_accessibility_service_off));
}
@Test
public void getServiceSummary_disableServiceShortcutOn_showsDisabledShortcutOn() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.generic_accessibility_service_off));
}
@Test
public void getServiceSummary_enableServiceShortcutOffAndHasSummary_showsEnabledSummary() {
setShortcutEnabled(mServiceInfo.getComponentName(), false);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_service_on),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_enableServiceShortcutOnAndHasSummary_showsEnabledSummary() {
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_service_on),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_disableServiceShortcutOnAndHasSummary_showsDisabledSummary() {
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_service_off),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_disableServiceShortcutOffAndHasSummary_showsDisabledSummary() {
setShortcutEnabled(mServiceInfo.getComponentName(), false);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_service_off),
DEFAULT_SUMMARY));
}
@Test
public void getServiceDescription_serviceCrash_showsStopped() {
mServiceInfo.crashed = true;
String description = AccessibilitySettings.getServiceDescription(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(description).isEqualTo(
mContext.getString(R.string.accessibility_description_state_stopped));
}
@Test
public void getServiceDescription_haveDescription_showsDescription() {
doReturn(DEFAULT_DESCRIPTION).when(mServiceInfo).loadDescription(any());
String description = AccessibilitySettings.getServiceDescription(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(description).isEqualTo(DEFAULT_DESCRIPTION);
}
@Test
public void onCreate_haveRegisterToSpecificUrisAndActions() {
setupFragment();
ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver());
Collection<ContentObserver> a11yButtonTargetsObservers =
shadowContentResolver.getContentObservers(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
Collection<ContentObserver> a11yShortcutTargetServiceObservers =
shadowContentResolver.getContentObservers(Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
List<BroadcastReceiver> broadcastReceivers =
shadowOf((Application) ApplicationProvider.getApplicationContext())
.getRegisteredReceivers()
.stream().map(wrapper -> wrapper.broadcastReceiver).toList();
assertThat(
a11yButtonTargetsObservers.stream()
.anyMatch(contentObserver ->
contentObserver instanceof AccessibilitySettingsContentObserver))
.isTrue();
assertThat(
a11yShortcutTargetServiceObservers.stream()
.anyMatch(contentObserver ->
contentObserver instanceof AccessibilitySettingsContentObserver))
.isTrue();
assertThat(broadcastReceivers.stream().anyMatch(
broadcastReceiver -> broadcastReceiver instanceof PackageMonitor)).isTrue();
}
@Test
public void onDestroy_unregisterObserverAndReceiver() {
setupFragment();
mActivityController.pause().stop().destroy();
ShadowContentResolver shadowContentResolver = shadowOf(mContext.getContentResolver());
Collection<ContentObserver> a11yButtonTargetsObservers =
shadowContentResolver.getContentObservers(
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
Collection<ContentObserver> a11yShortcutTargetServiceObservers =
shadowContentResolver.getContentObservers(Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
List<BroadcastReceiver> broadcastReceivers =
shadowOf((Application) ApplicationProvider.getApplicationContext())
.getRegisteredReceivers()
.stream().map(wrapper -> wrapper.broadcastReceiver).toList();
assertThat(
a11yButtonTargetsObservers.stream()
.anyMatch(contentObserver ->
contentObserver instanceof AccessibilitySettingsContentObserver))
.isFalse();
assertThat(
a11yShortcutTargetServiceObservers.stream()
.anyMatch(contentObserver ->
contentObserver instanceof AccessibilitySettingsContentObserver))
.isFalse();
assertThat(broadcastReceivers.stream().anyMatch(
broadcastReceiver -> broadcastReceiver instanceof PackageMonitor)).isFalse();
}
@Test
public void onContentChanged_updatePreferenceInForeground_preferenceUpdated() {
setupFragment();
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(
singletonList(mServiceInfo));
mFragment.onContentChanged();
RestrictedPreference preference = mFragment.getPreferenceScreen().findPreference(
COMPONENT_NAME.flattenToString());
assertThat(preference).isNotNull();
}
@Test
public void onContentChanged_updatePreferenceInBackground_preferenceUpdated() {
setupFragment();
mFragment.onPause();
mFragment.onStop();
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(
singletonList(mServiceInfo));
mFragment.onContentChanged();
mFragment.onStart();
RestrictedPreference preference = mFragment.getPreferenceScreen().findPreference(
COMPONENT_NAME.flattenToString());
assertThat(preference).isNotNull();
}
@Test
public void testAccessibilityMenuInSystem_IncludedInInteractionControl() {
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(
List.of(getMockAccessibilityServiceInfo(
AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM)));
setupFragment();
final RestrictedPreference pref = mFragment.getPreferenceScreen().findPreference(
AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM.flattenToString());
final String prefCategory = mFragment.mServicePreferenceToPreferenceCategoryMap.get(
pref).getKey();
assertThat(prefCategory).isEqualTo(AccessibilitySettings.CATEGORY_INTERACTION_CONTROL);
}
@Test
public void testAccessibilityMenuInSystem_NoPrefWhenNotInstalled() {
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(List.of());
setupFragment();
final RestrictedPreference pref = mFragment.getPreferenceScreen().findPreference(
AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM.flattenToString());
assertThat(pref).isNull();
}
private AccessibilityServiceInfo getMockAccessibilityServiceInfo(String packageName,
String className) {
return getMockAccessibilityServiceInfo(new ComponentName(packageName, className));
}
private AccessibilityServiceInfo getMockAccessibilityServiceInfo(ComponentName componentName) {
final ApplicationInfo applicationInfo = new ApplicationInfo();
final ServiceInfo serviceInfo = new ServiceInfo();
applicationInfo.packageName = componentName.getPackageName();
serviceInfo.packageName = componentName.getPackageName();
serviceInfo.name = componentName.getClassName();
serviceInfo.applicationInfo = applicationInfo;
final ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.serviceInfo = serviceInfo;
try {
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
mContext);
info.setComponentName(componentName);
return info;
} catch (XmlPullParserException | IOException e) {
// Do nothing
}
return null;
}
private void setMockAccessibilityShortcutInfo(AccessibilityShortcutInfo mockInfo) {
final ActivityInfo activityInfo = Mockito.mock(ActivityInfo.class);
activityInfo.applicationInfo = new ApplicationInfo();
when(mockInfo.getActivityInfo()).thenReturn(activityInfo);
when(activityInfo.loadLabel(any())).thenReturn(DEFAULT_LABEL);
when(mockInfo.loadSummary(any())).thenReturn(DEFAULT_SUMMARY);
when(mockInfo.loadDescription(any())).thenReturn(DEFAULT_DESCRIPTION);
when(mockInfo.getComponentName()).thenReturn(COMPONENT_NAME);
}
private void setInvisibleToggleFragmentType(AccessibilityServiceInfo info) {
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
}
private void setupFragment() {
mActivityController.create().start().resume();
Fragment fragment = mActivityController.get().getSupportFragmentManager().findFragmentById(
R.id.main_content);
assertThat(fragment).isNotNull();
assertThat(fragment).isInstanceOf(AccessibilitySettings.class);
mFragment = (AccessibilitySettings) fragment;
}
private void setShortcutEnabled(ComponentName componentName, boolean enabled) {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
enabled ? componentName.flattenToString() : "");
}
}

View File

@@ -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.accessibility;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.test.core.app.ApplicationProvider;
import com.google.android.setupdesign.GlifPreferenceLayout;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilitySetupWizardUtils} */
@RunWith(RobolectricTestRunner.class)
public class AccessibilitySetupWizardUtilsTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
@Test
public void setupGlifPreferenceLayout_assignValueToVariable() {
final String title = "title";
final String description = "description";
final Drawable icon = mock(Drawable.class);
GlifPreferenceLayout layout = mock(GlifPreferenceLayout.class);
AccessibilitySetupWizardUtils.updateGlifPreferenceLayout(mContext, layout, title,
description, icon);
verify(layout).setHeaderText(title);
verify(layout).setDescriptionText(description);
verify(layout).setIcon(icon);
verify(layout).setHeaderText(title);
}
@Test
public void setupGlifPreferenceLayout_descriptionIsNull_doesNotCallSetDescriptionText() {
GlifPreferenceLayout layout = mock(GlifPreferenceLayout.class);
AccessibilitySetupWizardUtils.updateGlifPreferenceLayout(mContext, layout, "title",
/* description= */ null, /* icon= */ null);
verify(layout, times(0)).setDescriptionText(any());
}
}

View File

@@ -0,0 +1,332 @@
/*
* 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.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_QS_TOOLTIP_RESHOW;
import static com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_USER_SHORTCUT_TYPE;
import static com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
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.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.testutils.shadow.ShadowFragment;
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;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowApplication;
/** Tests for {@link AccessibilityShortcutPreferenceFragment} */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
})
public class AccessibilityShortcutPreferenceFragmentTest {
private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
private static final String PLACEHOLDER_CLASS_NAME = PLACEHOLDER_PACKAGE_NAME + ".placeholder";
private static final String PLACEHOLDER_TILE_CLASS_NAME =
PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
private static final String PLACEHOLDER_TILE_TOOLTIP_CONTENT =
PLACEHOLDER_PACKAGE_NAME + "tooltip_content";
private static final String PLACEHOLDER_DIALOG_TITLE = "title";
private static final String SOFTWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
private static final String HARDWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
private TestAccessibilityShortcutPreferenceFragment mFragment;
private PreferenceScreen mScreen;
private Context mContext = ApplicationProvider.getApplicationContext();
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceManager mPreferenceManager;
@Before
public void setUpTestFragment() {
MockitoAnnotations.initMocks(this);
mFragment = spy(new TestAccessibilityShortcutPreferenceFragment(null));
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
when(mFragment.getContext()).thenReturn(mContext);
when(mFragment.getActivity()).thenReturn(Robolectric.setupActivity(FragmentActivity.class));
mScreen = spy(new PreferenceScreen(mContext, null));
when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
doReturn(mScreen).when(mFragment).getPreferenceScreen();
}
@Test
public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
mFragment.updateShortcutPreferenceData();
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
mFragment.getComponentName().flattenToString());
// Compare to default UserShortcutType
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE);
}
@Test
public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
mFragment.updateShortcutPreferenceData();
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
mFragment.getComponentName().flattenToString());
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
}
@Test
public void updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable() {
final PreferredShortcut hardwareShortcut = new PreferredShortcut(
PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
putUserShortcutTypeIntoSharedPreference(mContext, hardwareShortcut);
mFragment.updateShortcutPreferenceData();
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
mFragment.getComponentName().flattenToString());
assertThat(expectedType).isEqualTo(UserShortcutType.HARDWARE);
}
@Test
public void setupEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue() {
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
PLACEHOLDER_DIALOG_TITLE,
this::callEmptyOnClicked);
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
null);
mFragment.mShortcutPreference = shortcutPreference;
mFragment.mShortcutPreference.setChecked(false);
mFragment.setupEditShortcutDialog(dialog);
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
assertThat(checkboxValue).isEqualTo(UserShortcutType.EMPTY);
}
@Test
public void setupEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue() {
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
PLACEHOLDER_DIALOG_TITLE,
this::callEmptyOnClicked);
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
null);
final PreferredShortcut hardwareShortcut = new PreferredShortcut(
PLACEHOLDER_COMPONENT_NAME.flattenToString(), UserShortcutType.HARDWARE);
mFragment.mShortcutPreference = shortcutPreference;
PreferredShortcuts.saveUserShortcutType(mContext, hardwareShortcut);
mFragment.mShortcutPreference.setChecked(true);
mFragment.setupEditShortcutDialog(dialog);
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
assertThat(checkboxValue).isEqualTo(UserShortcutType.HARDWARE);
}
@Test
@Config(shadows = ShadowFragment.class)
public void restoreValueFromSavedInstanceState_assignShortcutTypeToVariable() {
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
PLACEHOLDER_DIALOG_TITLE,
this::callEmptyOnClicked);
final Bundle savedInstanceState = new Bundle();
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
null);
mFragment.mShortcutPreference = shortcutPreference;
savedInstanceState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE,
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
mFragment.onAttach(mContext);
mFragment.onCreate(savedInstanceState);
mFragment.setupEditShortcutDialog(dialog);
final int value = mFragment.getShortcutTypeCheckBoxValue();
mFragment.saveNonEmptyUserShortcutType(value);
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
mFragment.getComponentName().flattenToString());
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
}
@Test
@Config(shadows = ShadowFragment.class)
public void restoreValueFromSavedInstanceState_showTooltipView() {
mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat);
mFragment.showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_EDIT);
assertThat(getLatestPopupWindow().isShowing()).isTrue();
final Bundle savedInstanceState = new Bundle();
savedInstanceState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
mFragment.onAttach(mContext);
mFragment.onCreate(savedInstanceState);
mFragment.onCreateView(LayoutInflater.from(mContext), mock(ViewGroup.class), Bundle.EMPTY);
mFragment.onViewCreated(mFragment.getView(), savedInstanceState);
assertThat(getLatestPopupWindow().isShowing()).isTrue();
}
@Test
@Config(shadows = ShadowFragment.class)
public void showGeneralCategory_shouldInitCategory() {
final Bundle savedInstanceState = new Bundle();
when(mFragment.showGeneralCategory()).thenReturn(true);
mFragment.onAttach(mContext);
mFragment.onCreate(savedInstanceState);
verify(mFragment).initGeneralCategory();
}
@Test
public void showGeneralCategory_shouldSetDefaultDescription() {
assertThat(mFragment.getGeneralCategoryDescription(null)).isNotNull();
}
private void callEmptyOnClicked(DialogInterface dialog, int which) {}
private void putStringIntoSettings(String key, String componentName) {
Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
}
private void putUserShortcutTypeIntoSharedPreference(Context context,
PreferredShortcut shortcut) {
PreferredShortcuts.saveUserShortcutType(context, shortcut);
}
private static PopupWindow getLatestPopupWindow() {
final ShadowApplication shadowApplication =
Shadow.extract(ApplicationProvider.getApplicationContext());
return shadowApplication.getLatestPopupWindow();
}
public static class TestAccessibilityShortcutPreferenceFragment
extends AccessibilityShortcutPreferenceFragment {
public TestAccessibilityShortcutPreferenceFragment(String restrictionKey) {
super(restrictionKey);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return mock(View.class);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// do nothing
}
@Override
protected ComponentName getComponentName() {
return PLACEHOLDER_COMPONENT_NAME;
}
@Override
protected CharSequence getLabelName() {
return PLACEHOLDER_PACKAGE_NAME;
}
@Override
protected ComponentName getTileComponentName() {
return PLACEHOLDER_TILE_COMPONENT_NAME;
}
@Override
protected CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
return PLACEHOLDER_TILE_TOOLTIP_CONTENT;
}
@Override
public int getUserShortcutTypes() {
return 0;
}
@Override
protected CharSequence getGeneralCategoryDescription(@Nullable CharSequence title) {
return super.getGeneralCategoryDescription(null);
}
@Override
protected boolean showGeneralCategory() {
// For showGeneralCategory_shouldInitCategory()
return true;
}
@Override
public int getMetricsCategory() {
return 0;
}
@Override
protected int getPreferenceScreenResId() {
return 0;
}
@Override
protected String getLogTag() {
return null;
}
@Override
public View getView() {
return mock(View.class);
}
};
}

View File

@@ -0,0 +1,156 @@
/*
* 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.accessibility;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
import com.android.settingslib.accessibility.AccessibilityUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowAccessibilityManager;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class AccessibilitySlicePreferenceControllerTest {
private final String PACKAGE_NAME = "com.android.settings.fake";
private final String CLASS_NAME = "com.android.settings.fake.classname";
private final String SERVICE_NAME = PACKAGE_NAME + "/" + CLASS_NAME;
private Context mContext;
private AccessibilitySlicePreferenceController mController;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
final ContentResolver contentResolver = mContext.getContentResolver();
Settings.Secure.putInt(contentResolver, Settings.Secure.ACCESSIBILITY_ENABLED, 1 /* on */);
Settings.Secure.putString(contentResolver, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
SERVICE_NAME);
// Register the fake a11y Service
ShadowAccessibilityManager shadowAccessibilityManager = Shadow.extract(
RuntimeEnvironment.application.getSystemService(AccessibilityManager.class));
shadowAccessibilityManager.setInstalledAccessibilityServiceList(getFakeServiceList());
mController = new AccessibilitySlicePreferenceController(mContext, SERVICE_NAME);
}
@Test
public void getAvailability_availableService_returnsAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailability_unknownService_returnsUnsupported() {
AccessibilitySlicePreferenceController controller =
new AccessibilitySlicePreferenceController(mContext, "fake_service/name");
assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void setChecked_availableService_serviceIsEnabled() {
mController.setChecked(true);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setNotChecked_availableService_serviceIsDisabled() {
mController.setChecked(false);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_serviceEnabled_returnsTrue() {
AccessibilityUtils.setAccessibilityServiceState(mContext,
ComponentName.unflattenFromString(mController.getPreferenceKey()), true);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void isChecked_serviceNotEnabled_returnsFalse() {
AccessibilitySlicePreferenceController controller =
new AccessibilitySlicePreferenceController(mContext, "fake_service/name");
assertThat(controller.isChecked()).isFalse();
}
@Test(expected = IllegalArgumentException.class)
public void illegalServiceName_exceptionThrown() {
new AccessibilitySlicePreferenceController(mContext, "not_split_by_slash");
}
@Test
public void isSliceable_returnTrue() {
assertThat(mController.isSliceable()).isTrue();
}
@Test
public void isPublicSlice_returnTrue() {
assertThat(mController.isPublicSlice()).isTrue();
}
private List<AccessibilityServiceInfo> getFakeServiceList() {
final List<AccessibilityServiceInfo> infoList = new ArrayList<>();
final ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.packageName = PACKAGE_NAME;
serviceInfo.name = CLASS_NAME;
final ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.serviceInfo = serviceInfo;
try {
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
mContext);
ComponentName componentName = new ComponentName(PACKAGE_NAME, CLASS_NAME);
info.setComponentName(componentName);
infoList.add(info);
} catch (XmlPullParserException | IOException e) {
}
return infoList;
}
}

View File

@@ -0,0 +1,128 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.SelectorWithWidgetPreference;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityTimeoutController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityTimeoutControllerTest {
private static final String PREF_KEY = "accessibility_control_timeout_30secs";
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private SelectorWithWidgetPreference mMockPref;
@Mock
private PreferenceScreen mScreen;
@Mock
private AccessibilitySettingsContentObserver mAccessibilitySettingsContentObserver;
private Context mContext = ApplicationProvider.getApplicationContext();
private ContentResolver mContentResolver;
private AccessibilityTimeoutController mController;
@Before
public void setup() {
mContentResolver = mContext.getContentResolver();
mController = new AccessibilityTimeoutController(mContext, PREF_KEY,
mAccessibilitySettingsContentObserver);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
when(mMockPref.getKey()).thenReturn(PREF_KEY);
final String prefTitle =
mContext.getResources().getString(R.string.accessibility_timeout_30secs);
when(mMockPref.getTitle()).thenReturn(prefTitle);
mController.displayPreference(mScreen);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void updateState_notChecked() {
Settings.Secure.putString(mContentResolver,
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "0");
mController.updateState(mMockPref);
// the first checked state is set to false by control
verify(mMockPref).setChecked(false);
verify(mMockPref).setChecked(false);
}
@Test
public void updateState_checked() {
Settings.Secure.putString(mContentResolver,
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "30000");
mController.updateState(mMockPref);
// the first checked state is set to false by control
verify(mMockPref).setChecked(false);
verify(mMockPref).setChecked(true);
}
@Test
public void onRadioButtonClick() {
mController.onRadioButtonClicked(mMockPref);
String accessibilityUiTimeoutValue = Settings.Secure.getString(mContentResolver,
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS);
assertThat(accessibilityUiTimeoutValue).isEqualTo("30000");
}
@Test
public void onStart_registerSpecificContentObserverForSpecificKeys() {
mController.onStart();
verify(mAccessibilitySettingsContentObserver).register(mContentResolver);
}
@Test
public void onStop_unregisterContentObserver() {
mController.onStop();
verify(mAccessibilitySettingsContentObserver).unregister(mContentResolver);
}
}

View File

@@ -0,0 +1,81 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityTimeoutPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityTimeoutPreferenceControllerTest {
private Context mContext = ApplicationProvider.getApplicationContext();
private AccessibilityTimeoutPreferenceController mController;
@Before
public void setUp() {
mController = new AccessibilityTimeoutPreferenceController(mContext, "control_timeout");
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_byDefault_shouldReturnDefaultSummary() {
final String[] timeoutSummaries = mContext.getResources().getStringArray(
R.array.accessibility_timeout_summaries);
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "0");
assertThat(mController.getSummary().toString()).isEqualTo(timeoutSummaries[0]);
}
@Test
public void getSummary_invalidTimeout_shouldReturnDefaultSummary() {
final String[] timeoutSummaries = mContext.getResources().getStringArray(
R.array.accessibility_timeout_summaries);
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "invalid_timeout");
assertThat(mController.getSummary().toString()).isEqualTo(timeoutSummaries[0]);
}
@Test
public void getSummary_validTimeout_shouldReturnValidSummary() {
final String[] timeoutSummaries = mContext.getResources().getStringArray(
R.array.accessibility_timeout_summaries);
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "60000");
assertThat(mController.getSummary().toString()).isEqualTo(timeoutSummaries[3]);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2022 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 org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityTimeoutUtils}. */
@RunWith(RobolectricTestRunner.class)
public final class AccessibilityTimeoutUtilsTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
@Test
public void getSecureAccessibilityTimeoutValue_byDefault_shouldReturnDefaultValue() {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "0");
final int timeOutValue = AccessibilityTimeoutUtils.getSecureAccessibilityTimeoutValue(
mContext.getContentResolver());
assertThat(timeOutValue).isEqualTo(0);
}
@Test
public void getSecureAccessibilityTimeoutValue_invalidTimeout_shouldReturnDefaultValue() {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "invalid_timeout");
final int timeOutValue = AccessibilityTimeoutUtils.getSecureAccessibilityTimeoutValue(
mContext.getContentResolver());
assertThat(timeOutValue).isEqualTo(0);
}
@Test
public void getSecureAccessibilityTimeoutValue_validTimeout_shouldReturnValidValue() {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, "60000");
final int timeOutValue = AccessibilityTimeoutUtils.getSecureAccessibilityTimeoutValue(
mContext.getContentResolver());
assertThat(timeOutValue).isEqualTo(60000);
}
}

View File

@@ -0,0 +1,298 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.StringJoiner;
@RunWith(RobolectricTestRunner.class)
public final class AccessibilityUtilTest {
private static final String SECURE_TEST_KEY = "secure_test_key";
private static final String MOCK_PACKAGE_NAME = "com.mock.example";
private static final String MOCK_CLASS_NAME = MOCK_PACKAGE_NAME + ".mock_a11y_service";
private static final String MOCK_CLASS_NAME2 = MOCK_PACKAGE_NAME + ".mock_a11y_service2";
private static final ComponentName MOCK_COMPONENT_NAME = new ComponentName(MOCK_PACKAGE_NAME,
MOCK_CLASS_NAME);
private static final ComponentName MOCK_COMPONENT_NAME2 = new ComponentName(MOCK_PACKAGE_NAME,
MOCK_CLASS_NAME2);
private static final String SOFTWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
private static final String HARDWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
private static final String PLACEHOLDER_SETTING_FEATURE = "placeholderSettingFeature";
private Context mContext;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
}
@Test
public void capitalize_shouldReturnCapitalizedString() {
assertThat(AccessibilityUtil.capitalize(null)).isNull();
assertThat(AccessibilityUtil.capitalize("")).isEmpty();
assertThat(AccessibilityUtil.capitalize("Hans")).isEqualTo("Hans");
assertThat(AccessibilityUtil.capitalize("hans")).isEqualTo("Hans");
assertThat(AccessibilityUtil.capitalize(",hans")).isEqualTo(",hans");
assertThat(AccessibilityUtil.capitalize("Hans, Hans")).isEqualTo("Hans, hans");
}
@Test
public void getSummary_hasValueAndEqualsToOne_shouldReturnOnString() {
setSettingsFeatureEnabled(SECURE_TEST_KEY, true);
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
R.string.switch_on_text, R.string.switch_off_text);
assertThat(result)
.isEqualTo(mContext.getText(R.string.switch_on_text));
}
@Test
public void getSummary_hasValueAndEqualsToZero_shouldReturnOffString() {
setSettingsFeatureEnabled(SECURE_TEST_KEY, false);
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
R.string.switch_on_text, R.string.switch_off_text);
assertThat(result)
.isEqualTo(mContext.getText(R.string.switch_off_text));
}
@Test
public void getSummary_noValue_shouldReturnOffString() {
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
R.string.switch_on_text, R.string.switch_off_text);
assertThat(result)
.isEqualTo(mContext.getText(R.string.switch_off_text));
}
@Test
public void getAccessibilityServiceFragmentType_targetSdkQ_volumeShortcutType() {
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
AccessibilityUtil.AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE);
}
@Test
public void getAccessibilityServiceFragmentType_targetSdkR_HaveA11yButton_invisibleType() {
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
AccessibilityUtil.AccessibilityServiceFragmentType.INVISIBLE_TOGGLE);
}
@Test
public void getAccessibilityServiceFragmentType_targetSdkR_NoA11yButton_toggleType() {
final AccessibilityServiceInfo info = getMockAccessibilityServiceInfo();
info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
info.flags |= ~AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
assertThat(AccessibilityUtil.getAccessibilityServiceFragmentType(info)).isEqualTo(
AccessibilityUtil.AccessibilityServiceFragmentType.TOGGLE);
}
@Test
public void hasValueInSettings_putValue_hasValue() {
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
assertThat(AccessibilityUtil.hasValueInSettings(mContext, UserShortcutType.SOFTWARE,
MOCK_COMPONENT_NAME)).isTrue();
}
@Test
public void getUserShortcutTypeFromSettings_putOneValue_hasValue() {
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
final int shortcutType = AccessibilityUtil.getUserShortcutTypesFromSettings(mContext,
MOCK_COMPONENT_NAME);
assertThat(
(shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE).isTrue();
}
@Test
public void getUserShortcutTypeFromSettings_putTwoValues_hasValue() {
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.HARDWARE, MOCK_COMPONENT_NAME.flattenToString());
final int shortcutType = AccessibilityUtil.getUserShortcutTypesFromSettings(mContext,
MOCK_COMPONENT_NAME);
assertThat(
(shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE).isTrue();
assertThat(
(shortcutType & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE).isTrue();
}
@Test
public void optInAllValuesToSettings_optInValue_haveMatchString() {
clearShortcuts();
int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE;
AccessibilityUtil.optInAllValuesToSettings(mContext, shortcutTypes, MOCK_COMPONENT_NAME);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
MOCK_COMPONENT_NAME.flattenToString());
assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEqualTo(
MOCK_COMPONENT_NAME.flattenToString());
}
@Test
public void optInValueToSettings_optInValue_haveMatchString() {
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
MOCK_COMPONENT_NAME2);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
MOCK_COMPONENT_NAME.flattenToString() + ":"
+ MOCK_COMPONENT_NAME2.flattenToString());
}
@Test
public void optInValueToSettings_optInTwoValues_haveMatchString() {
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
MOCK_COMPONENT_NAME2);
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
MOCK_COMPONENT_NAME2);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
MOCK_COMPONENT_NAME.flattenToString() + ":"
+ MOCK_COMPONENT_NAME2.flattenToString());
}
@Test
public void optOutAllValuesToSettings_optOutValue_emptyString() {
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.HARDWARE, MOCK_COMPONENT_NAME.flattenToString());
int shortcutTypes =
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP;
AccessibilityUtil.optOutAllValuesFromSettings(mContext, shortcutTypes,
MOCK_COMPONENT_NAME);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty();
assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEmpty();
}
@Test
public void optOutValueFromSettings_optOutValue_emptyString() {
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
AccessibilityUtil.optOutValueFromSettings(mContext, UserShortcutType.SOFTWARE,
MOCK_COMPONENT_NAME);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty();
}
@Test
public void optOutValueFromSettings_optOutValue_haveMatchString() {
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString(),
MOCK_COMPONENT_NAME2.flattenToString());
AccessibilityUtil.optOutValueFromSettings(mContext, UserShortcutType.SOFTWARE,
MOCK_COMPONENT_NAME2);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
MOCK_COMPONENT_NAME.flattenToString());
}
private AccessibilityServiceInfo getMockAccessibilityServiceInfo() {
final ApplicationInfo applicationInfo = new ApplicationInfo();
final ServiceInfo serviceInfo = new ServiceInfo();
applicationInfo.packageName = MOCK_PACKAGE_NAME;
serviceInfo.packageName = MOCK_PACKAGE_NAME;
serviceInfo.name = MOCK_CLASS_NAME;
serviceInfo.applicationInfo = applicationInfo;
final ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.serviceInfo = serviceInfo;
try {
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
mContext);
info.setComponentName(MOCK_COMPONENT_NAME);
return info;
} catch (XmlPullParserException | IOException e) {
// Do nothing
}
return null;
}
private String getStringFromSettings(String key) {
return Settings.Secure.getString(mContext.getContentResolver(), key);
}
private void setSettingsFeatureEnabled(String settingsKey, boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
settingsKey,
enabled ? AccessibilityUtil.State.ON : AccessibilityUtil.State.OFF);
}
private void setShortcut(@UserShortcutType int shortcutType, String... componentNames) {
StringJoiner shortcutComponents = new StringJoiner(":");
for (String componentName : componentNames) {
shortcutComponents.add(componentName);
}
Settings.Secure.putString(mContext.getContentResolver(),
shortcutType == UserShortcutType.SOFTWARE ? SOFTWARE_SHORTCUT_KEY
: HARDWARE_SHORTCUT_KEY, shortcutComponents.toString());
}
private void clearShortcuts() {
Settings.Secure.putString(mContext.getContentResolver(), SOFTWARE_SHORTCUT_KEY, "");
Settings.Secure.putString(mContext.getContentResolver(), HARDWARE_SHORTCUT_KEY, "");
}
}

View File

@@ -0,0 +1,165 @@
/*
* Copyright (C) 2022 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.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.media.AudioManager;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowInteractionJankMonitor.class})
public class AlarmVibrationIntensityPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Mock private PreferenceScreen mScreen;
@Mock private AudioManager mAudioManager;
private Lifecycle mLifecycle;
private Context mContext;
private Vibrator mVibrator;
private AlarmVibrationIntensityPreferenceController mController;
private SeekBarPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycle = new Lifecycle(() -> mLifecycle);
mContext = spy(ApplicationProvider.getApplicationContext());
when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
mVibrator = mContext.getSystemService(Vibrator.class);
mController = new AlarmVibrationIntensityPreferenceController(mContext, PREFERENCE_KEY,
Vibrator.VIBRATION_INTENSITY_HIGH);
mLifecycle.addObserver(mController);
mPreference = new SeekBarPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
}
@Test
public void verifyConstants() {
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
}
@Test
public void missingSetting_shouldReturnDefault() {
Settings.System.putString(mContext.getContentResolver(),
Settings.System.ALARM_VIBRATION_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_ALARM));
}
@Test
public void updateState_ringerModeUpdates_shouldNotAffectSettings() {
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(mPreference.isEnabled()).isTrue();
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(mPreference.isEnabled()).isTrue();
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(mPreference.isEnabled()).isTrue();
}
@Test
public void updateState_shouldDisplayIntensityInSliderPosition() {
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
}
@Test
public void setProgress_updatesIntensitySetting() throws Exception {
mController.setSliderPosition(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
mController.setSliderPosition(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
mController.setSliderPosition(Vibrator.VIBRATION_INTENSITY_MEDIUM);
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.setSliderPosition(Vibrator.VIBRATION_INTENSITY_HIGH);
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
}

View File

@@ -0,0 +1,153 @@
/*
* Copyright (C) 2022 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.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.media.AudioManager;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class AlarmVibrationTogglePreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Mock private PreferenceScreen mScreen;
@Mock AudioManager mAudioManager;
private Lifecycle mLifecycle;
private Context mContext;
private Vibrator mVibrator;
private AlarmVibrationTogglePreferenceController mController;
private SwitchPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycle = new Lifecycle(() -> mLifecycle);
mContext = spy(ApplicationProvider.getApplicationContext());
when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
mVibrator = mContext.getSystemService(Vibrator.class);
mController = new AlarmVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
mLifecycle.addObserver(mController);
mPreference = new SwitchPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
}
@Test
public void verifyConstants() {
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void missingSetting_shouldReturnDefault() {
Settings.System.putString(mContext.getContentResolver(),
Settings.System.ALARM_VIBRATION_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void updateState_ringerModeUpdates_shouldNotAffectSettings() {
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
assertThat(mPreference.isEnabled()).isTrue();
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
assertThat(mPreference.isEnabled()).isTrue();
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
assertThat(mPreference.isEnabled()).isTrue();
}
@Test
public void updateState_shouldDisplayOnOffState() {
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
updateSetting(Settings.System.ALARM_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
mController.setChecked(true);
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY)).isEqualTo(
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_ALARM));
mController.setChecked(false);
assertThat(readSetting(Settings.System.ALARM_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2024 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 com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link ArrowPreference} */
@RunWith(RobolectricTestRunner.class)
public class ArrowPreferenceTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private ArrowPreference mPreference;
@Before
public void setUp() {
mPreference = new ArrowPreference(mContext);
}
@Test
public void construct_withArrow() {
assertThat(mPreference.getWidgetLayoutResource()).isEqualTo(
R.layout.preference_widget_arrow);
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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 android.app.settings.SettingsEnums;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link AudioAdjustmentFragment}. */
@RunWith(RobolectricTestRunner.class)
public class AudioAdjustmentFragmentTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private AudioAdjustmentFragment mFragment;
@Before
public void setUp() {
mFragment = new AudioAdjustmentFragment();
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_AUDIO_ADJUSTMENT);
}
@Test
public void getPreferenceScreenResId_returnsCorrectXml() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
R.xml.accessibility_audio_adjustment);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo("AudioAdjustmentFragment");
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = AudioAdjustmentFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_audio_adjustment);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class AudioDescriptionPreferenceControllerTest {
private static final String KEY_AUDIO_DESCRIPTION =
Settings.Secure.ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT;
private static final int UNKNOWN = -1;
private final Context mContext = ApplicationProvider.getApplicationContext();
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
private final AudioDescriptionPreferenceController mController =
new AudioDescriptionPreferenceController(mContext,
AudioDescriptionPreferenceController.PREF_KEY);
@Before
public void setUp() {
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
mSwitchPreference.setKey(AudioDescriptionPreferenceController.PREF_KEY);
screen.addPreference(mSwitchPreference);
mController.displayPreference(screen);
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void isChecked_disableAudioDescription_onResumeShouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, OFF);
mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
@Test
public void isChecked_enableAudioDescription_onResumeShouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, ON);
mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mSwitchPreference.isChecked()).isTrue();
}
@Test
public void performClick_enableAudioDescription_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, OFF);
mController.updateState(mSwitchPreference);
mSwitchPreference.performClick();
verify(mSwitchPreference).setChecked(true);
assertThat(mController.isChecked()).isTrue();
assertThat(mSwitchPreference.isChecked()).isTrue();
}
@Test
public void performClick_disableAudioDescription_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, ON);
mController.updateState(mSwitchPreference);
mSwitchPreference.performClick();
verify(mSwitchPreference).setChecked(false);
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
@Test
public void setChecked_setFalse_shouldDisableAudioDescription() {
mController.setChecked(false);
assertThat(Settings.Secure.getInt(
mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, UNKNOWN)).isEqualTo(OFF);
}
@Test
public void setChecked_setTrue_shouldEnableAudioDescription() {
mController.setChecked(true);
assertThat(Settings.Secure.getInt(
mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, UNKNOWN)).isEqualTo(ON);
}
}

View File

@@ -0,0 +1,87 @@
/*
* 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.accessibility;
import static android.view.accessibility.AccessibilityManager.AUTOCLICK_DELAY_DEFAULT;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AutoclickPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AutoclickPreferenceControllerTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private AutoclickPreferenceController mController;
@Before
public void setUp() {
mController = new AutoclickPreferenceController(mContext, "auto_click");
}
@Test
public void getAvailabilityStatus_shouldReturnAvailableUnsearchable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_disabledAutoclick_shouldReturnOffSummary() {
setAutoClickEnabled(false);
assertThat(mController.getSummary().toString())
.isEqualTo(mContext.getText(R.string.autoclick_disabled));
}
@Test
public void getSummary_enabledAutoclick_shouldReturnOnSummary() {
setAutoClickEnabled(true);
setAutoClickDelayed(AUTOCLICK_DELAY_DEFAULT);
assertThat(mController.getSummary().toString())
.isEqualTo(AutoclickUtils.getAutoclickDelaySummary(
mContext,
R.string.accessibilty_autoclick_preference_subtitle_medium_delay,
AUTOCLICK_DELAY_DEFAULT).toString());
}
private void setAutoClickEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, enabled ? ON : OFF);
}
private void setAutoClickDelayed(int delayedInMs) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, delayedInMs);
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2022 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.AutoclickUtils.MAX_AUTOCLICK_DELAY_MS;
import static com.android.settings.accessibility.AutoclickUtils.MIN_AUTOCLICK_DELAY_MS;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AutoclickUtils}. */
@RunWith(RobolectricTestRunner.class)
public final class AutoclickUtilsTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
@Test
public void getAutoclickDelaySummary_minDelay_shouldReturnOnSummary() {
final CharSequence summary = AutoclickUtils.getAutoclickDelaySummary(
mContext, R.string.accessibilty_autoclick_delay_unit_second,
MIN_AUTOCLICK_DELAY_MS);
assertThat(summary.toString()).isEqualTo("0.2 seconds");
}
@Test
public void getAutoclickDelaySummary_maxDelay_shouldReturnOnSummary() {
final CharSequence summary = AutoclickUtils.getAutoclickDelaySummary(
mContext, R.string.accessibilty_autoclick_delay_unit_second,
MAX_AUTOCLICK_DELAY_MS);
assertThat(summary.toString()).isEqualTo("1 second");
}
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2023 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.when;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.bluetooth.Utils;
import com.android.settings.connecteddevice.DevicePreferenceCallback;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
/** Tests for {@link AvailableHearingDeviceUpdater}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothUtils.class})
public class AvailableHearingDeviceUpdaterTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private DevicePreferenceCallback mDevicePreferenceCallback;
@Mock
private CachedBluetoothDeviceManager mCachedDeviceManager;
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
@Mock
private BluetoothDevice mBluetoothDevice;
private AvailableHearingDeviceUpdater mUpdater;
@Before
public void setUp() {
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mUpdater = new AvailableHearingDeviceUpdater(mContext,
mDevicePreferenceCallback, /* metricsCategory= */ 0);
}
@Test
public void isFilterMatch_connectedHearingDevice_returnTrue() {
CachedBluetoothDevice connectedHearingDevice = mCachedBluetoothDevice;
when(connectedHearingDevice.isHearingAidDevice()).thenReturn(true);
when(mBluetoothDevice.isConnected()).thenReturn(true);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
new ArrayList<>(List.of(connectedHearingDevice)));
assertThat(mUpdater.isFilterMatched(connectedHearingDevice)).isEqualTo(true);
}
@Test
public void isFilterMatch_nonConnectedHearingDevice_returnFalse() {
CachedBluetoothDevice nonConnectedHearingDevice = mCachedBluetoothDevice;
when(nonConnectedHearingDevice.isHearingAidDevice()).thenReturn(true);
when(mBluetoothDevice.isConnected()).thenReturn(false);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
new ArrayList<>(List.of(nonConnectedHearingDevice)));
assertThat(mUpdater.isFilterMatched(nonConnectedHearingDevice)).isEqualTo(false);
}
@Test
public void isFilterMatch_connectedBondingHearingDevice_returnFalse() {
CachedBluetoothDevice connectedBondingHearingDevice = mCachedBluetoothDevice;
when(connectedBondingHearingDevice.isHearingAidDevice()).thenReturn(true);
when(mBluetoothDevice.isConnected()).thenReturn(true);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDING);
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
new ArrayList<>(List.of(connectedBondingHearingDevice)));
assertThat(mUpdater.isFilterMatched(connectedBondingHearingDevice)).isEqualTo(false);
}
@Test
public void isFilterMatch_hearingDeviceNotInCachedDevicesList_returnFalse() {
CachedBluetoothDevice notInCachedDevicesListDevice = mCachedBluetoothDevice;
when(notInCachedDevicesListDevice.isHearingAidDevice()).thenReturn(true);
when(mBluetoothDevice.isConnected()).thenReturn(true);
when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(new ArrayList<>());
assertThat(mUpdater.isFilterMatched(notInCachedDevicesListDevice)).isEqualTo(false);
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2024 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 org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link BackgroundPreference} */
@RunWith(RobolectricTestRunner.class)
public class BackgroundPreferenceTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private View mRootView = new View(mContext);
@Spy
private PreferenceViewHolder mViewHolder = PreferenceViewHolder.createInstanceForTests(
mRootView);
@Spy
private LinearLayout mLinearLayout = new LinearLayout(mContext);
private BackgroundPreference mPreference;
@Before
public void setUp() {
mPreference = new BackgroundPreference(mContext);
}
@Test
public void setBackground_success() {
doReturn(mLinearLayout).when(mViewHolder).findViewById(R.id.background);
mPreference.setBackground(android.R.drawable.screen_background_dark);
mPreference.onBindViewHolder(mViewHolder);
verify(mLinearLayout).setBackground(any());
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import androidx.preference.PreferenceViewHolder;
import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowInteractionJankMonitor.class})
public class BalanceSeekBarPreferenceTest {
private static final int BALANCE_CENTER_VALUE = 100;
private static final int BALANCE_MAX_VALUE = 200;
private Context mContext;
private AttributeSet mAttrs;
private PreferenceViewHolder mHolder;
private BalanceSeekBar mSeekBar;
private BalanceSeekBarPreference mSeekBarPreference;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mSeekBarPreference = new BalanceSeekBarPreference(mContext, mAttrs);
LayoutInflater inflater = LayoutInflater.from(mContext);
final View view =
inflater.inflate(mSeekBarPreference.getLayoutResource(),
new LinearLayout(mContext), false);
mHolder = PreferenceViewHolder.createInstanceForTests(view);
mSeekBar = (BalanceSeekBar) view.findViewById(com.android.internal.R.id.seekbar);
}
@Test
public void seekBarPreferenceOnBindViewHolder_shouldInitSeekBarValue() {
mSeekBarPreference.onBindViewHolder(mHolder);
assertThat(mSeekBar.getMax()).isEqualTo(BALANCE_MAX_VALUE);
assertThat(mSeekBar.getProgress()).isEqualTo(BALANCE_CENTER_VALUE);
}
}

View File

@@ -0,0 +1,155 @@
/*
* 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.accessibility;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static android.view.HapticFeedbackConstants.CONTEXT_CLICK;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.SeekBar;
import com.android.settings.testutils.shadow.ShadowSystemSettings;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {
ShadowSystemSettings.class,
})
public class BalanceSeekBarTest {
// Fix the maximum process value to 200 for testing the BalanceSeekBar.
// It affects the SeekBar value of center(100) and snapThreshold(200 * SNAP_TO_PERCENTAGE).
private static final int MAX_PROGRESS_VALUE = 200;
private Context mContext;
private AttributeSet mAttrs;
private BalanceSeekBar mSeekBar;
private BalanceSeekBar.OnSeekBarChangeListener mProxySeekBarListener;
private SeekBar.OnSeekBarChangeListener mockSeekBarChangeListener;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mSeekBar = new BalanceSeekBar(mContext, mAttrs);
mProxySeekBarListener = shadowOf(mSeekBar).getOnSeekBarChangeListener();
mockSeekBarChangeListener = mock(SeekBar.OnSeekBarChangeListener.class);
mSeekBar.setOnSeekBarChangeListener(mockSeekBarChangeListener);
}
@Test
public void onStartTrackingTouch_shouldInvokeMethod() {
mProxySeekBarListener.onStartTrackingTouch(mSeekBar);
verify(mockSeekBarChangeListener, times(1)).onStartTrackingTouch(mSeekBar);
}
@Test
public void onStopTrackingTouch_shouldInvokeMethod() {
mProxySeekBarListener.onStopTrackingTouch(mSeekBar);
verify(mockSeekBarChangeListener, times(1)).onStopTrackingTouch(mSeekBar);
}
@Test
public void onProgressChanged_shouldInvokeMethod() {
// Assign the test value of SeekBar progress
mProxySeekBarListener.onProgressChanged(mSeekBar, MAX_PROGRESS_VALUE, true);
verify(mockSeekBarChangeListener, times(1)).onProgressChanged(eq(mSeekBar),
eq(MAX_PROGRESS_VALUE), eq(true));
}
@Test
public void onProgressChanged_minimumValue_clockTickFeedbackPerformed() {
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
mProxySeekBarListener.onProgressChanged(mSeekBar, 0, true);
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
}
@Test
public void onProgressChanged_centerValue_clockTickFeedbackPerformed() {
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
mProxySeekBarListener.onProgressChanged(mSeekBar, MAX_PROGRESS_VALUE / 2, true);
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
}
@Test
public void onProgressChanged_maximumValue_clockTickFeedbackPerformed() {
mSeekBar.setMax(MAX_PROGRESS_VALUE);
mSeekBar.performHapticFeedback(CONTEXT_CLICK);
mProxySeekBarListener.onProgressChanged(mSeekBar, MAX_PROGRESS_VALUE, true);
assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK);
}
@Test
public void setMaxTest_shouldSetValue() {
mSeekBar.setMax(MAX_PROGRESS_VALUE);
assertThat(getBalanceSeekBarCenter(mSeekBar)).isEqualTo(MAX_PROGRESS_VALUE / 2);
assertThat(getBalanceSeekBarSnapThreshold(mSeekBar)).isEqualTo(
MAX_PROGRESS_VALUE * BalanceSeekBar.SNAP_TO_PERCENTAGE);
}
@Test
public void setProgressTest_shouldSnapToCenter() {
// Assign the test value of SeekBar progress within the threshold (94-106 in this case).
final int progressWithinThreshold = 102;
mSeekBar.setMax(MAX_PROGRESS_VALUE);
mSeekBar.setProgress(progressWithinThreshold + 10); //set progress which is over threshold.
mProxySeekBarListener.onProgressChanged(mSeekBar, progressWithinThreshold, true);
assertThat(mSeekBar.getProgress()).isEqualTo(getBalanceSeekBarCenter(mSeekBar));
}
@Test
public void setProgressTest_shouldMaintainInputValue() {
// Assign the test value of SeekBar progress without the threshold.
final int progressWithoutThreshold = 107;
mSeekBar.setMax(MAX_PROGRESS_VALUE);
mSeekBar.setProgress(progressWithoutThreshold);
mProxySeekBarListener.onProgressChanged(mSeekBar, progressWithoutThreshold, true);
assertThat(mSeekBar.getProgress()).isEqualTo(progressWithoutThreshold);
}
// method to get the center from BalanceSeekBar for testing setMax().
private int getBalanceSeekBarCenter(BalanceSeekBar seekBar) {
return seekBar.getMax() / 2;
}
// method to get the snapThreshold from BalanceSeekBar for testing setMax().
private float getBalanceSeekBarSnapThreshold(BalanceSeekBar seekBar) {
return seekBar.getMax() * BalanceSeekBar.SNAP_TO_PERCENTAGE;
}
}

View File

@@ -0,0 +1,135 @@
/*
* Copyright (C) 2023 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.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import android.content.Context;
import android.content.pm.PackageManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.bluetooth.Utils;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Tests for {@link BaseBluetoothDevicePreferenceController}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothUtils.class})
public class BaseBluetoothDevicePreferenceControllerTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
private static final String FAKE_KEY = "fake_key";
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
@Mock
private PackageManager mPackageManager;
private PreferenceCategory mPreferenceCategory;
private PreferenceManager mPreferenceManager;
private PreferenceScreen mScreen;
private TestBaseBluetoothDevicePreferenceController mController;
@Before
public void setUp() {
FakeFeatureFactory.setupForTest();
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
mPreferenceCategory = new PreferenceCategory(mContext);
mPreferenceCategory.setKey(FAKE_KEY);
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
mPreferenceManager = new PreferenceManager(mContext);
mScreen = mPreferenceManager.createPreferenceScreen(mContext);
mScreen.addPreference(mPreferenceCategory);
doReturn(mPackageManager).when(mContext).getPackageManager();
mController = new TestBaseBluetoothDevicePreferenceController(mContext, FAKE_KEY);
}
@Test
public void getAvailabilityStatus_hasBluetoothFeature_available() {
doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_noBluetoothFeature_conditionallyUnavailalbe() {
doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void displayPreference_preferenceCategoryInVisible() {
mController.displayPreference(mScreen);
assertThat(mPreferenceCategory.isVisible()).isFalse();
}
@Test
public void onDeviceAdded_preferenceCategoryVisible() {
Preference preference = new Preference(mContext);
mController.displayPreference(mScreen);
mController.onDeviceAdded(preference);
assertThat(mPreferenceCategory.isVisible()).isTrue();
}
@Test
public void onDeviceRemoved_addedPreferenceFirst_preferenceCategoryInVisible() {
Preference preference = new Preference(mContext);
mController.displayPreference(mScreen);
mController.onDeviceAdded(preference);
mController.onDeviceRemoved(preference);
assertThat(mPreferenceCategory.isVisible()).isFalse();
}
public static class TestBaseBluetoothDevicePreferenceController extends
BaseBluetoothDevicePreferenceController {
public TestBaseBluetoothDevicePreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey);
}
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2023 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 static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowFlashNotificationsUtils.class)
public class CameraFlashNotificationPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private CameraFlashNotificationPreferenceController mController;
private ContentResolver mContentResolver;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContentResolver = mContext.getContentResolver();
mController = new CameraFlashNotificationPreferenceController(mContext, PREFERENCE_KEY);
}
@After
public void tearDown() {
ShadowFlashNotificationsUtils.reset();
}
@Test
public void getAvailabilityStatus_torchAvailable_assertAvailable() {
ShadowFlashNotificationsUtils.setIsTorchAvailable(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_torchUnavailable_assertUnsupportedOnDevice() {
ShadowFlashNotificationsUtils.setIsTorchAvailable(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void isChecked_setOff_assertFalse() {
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, OFF);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_setOn_assertTrue() {
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked_setTrue_assertNotOff() {
mController.setChecked(true);
assertThat(
Settings.System.getInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION,
OFF)).isNotEqualTo(OFF);
}
@Test
public void setChecked_setFalse_assertNotOn() {
mController.setChecked(false);
assertThat(
Settings.System.getInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION,
OFF)).isNotEqualTo(ON);
}
@Test
public void getSliceHighlightMenuRes() {
mController.getSliceHighlightMenuRes();
assertThat(mController.getSliceHighlightMenuRes())
.isEqualTo(R.string.menu_key_accessibility);
}
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.view.View;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.widget.SubtitleView;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import java.util.Locale;
/** Tests for {@link CaptionHelper}. */
@RunWith(RobolectricTestRunner.class)
public class CaptionHelperTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private CaptioningManager mCaptioningManager;
@Mock
private SubtitleView mSubtitleView;
@Mock
private View mPreviewWindow;
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private ContentResolver mContentResolver;
private CaptionHelper mCaptionHelper;
@Before
public void setUp() {
when(mContext.getSystemService(CaptioningManager.class)).thenReturn(mCaptioningManager);
mCaptionHelper = new CaptionHelper(mContext);
mContentResolver = mContext.getContentResolver();
}
@Test
public void applyCaptionProperties_verifyAction() {
final float fontScale = 1.0f;
when(mCaptioningManager.getFontScale()).thenReturn(fontScale);
final int windowSize = 100;
when(mPreviewWindow.getWidth()).thenReturn(windowSize);
when(mPreviewWindow.getHeight()).thenReturn(windowSize);
final float textSize = CaptionHelper.LINE_HEIGHT_RATIO * windowSize * fontScale;
mCaptionHelper.applyCaptionProperties(mSubtitleView, mPreviewWindow, /* styleId= */ 0);
verify(mSubtitleView).setTextSize(textSize);
verify(mSubtitleView).setText(R.string.captioning_preview_characters);
}
@Test
public void applyCaptionProperties_withoutPreviewWindow_verifyAction() {
final float fontScale = 1.0f;
when(mCaptioningManager.getFontScale()).thenReturn(fontScale);
final float textSize = mContext.getResources().getDimension(
R.dimen.captioning_preview_text_size) * fontScale;
mCaptionHelper.applyCaptionProperties(mSubtitleView, /* PreviewWindow= */ null,
/* styleId= */ 0);
verify(mSubtitleView).setTextSize(textSize);
verify(mSubtitleView).setText(R.string.captioning_preview_characters);
}
@Test
public void applyCaptionProperties_localeUS_verifyAction() {
when(mCaptioningManager.getLocale()).thenReturn(Locale.US);
final String text = mContext.getString(R.string.captioning_preview_characters);
mCaptionHelper.applyCaptionProperties(mSubtitleView, /* PreviewWindow= */ null,
/* styleId= */ 0);
verify(mSubtitleView).setText(text);
}
@Test
public void enableCaptioningManager_shouldSetCaptionEnabled() {
when(mCaptioningManager.isEnabled()).thenReturn(false);
mCaptionHelper.setEnabled(true);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
@Test
public void disableCaptioningManager_shouldSetCaptionDisabled() {
when(mCaptioningManager.isEnabled()).thenReturn(true);
mCaptionHelper.setEnabled(false);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isFalse();
}
@Test
public void setBackgroundColor_shouldReturnSpecificColor() {
mCaptionHelper.setBackgroundColor(0xFFFF0000);
final int backgroundColor = mCaptionHelper.getBackgroundColor();
assertThat(backgroundColor).isEqualTo(0xFFFF0000);
}
@Test
public void setForegroundColor_shouldReturnSpecificColor() {
mCaptionHelper.setForegroundColor(0xFFFF0000);
final int foregroundColor = mCaptionHelper.getForegroundColor();
assertThat(foregroundColor).isEqualTo(0xFFFF0000);
}
@Test
public void setWindowColor_shouldReturnSpecificColor() {
mCaptionHelper.setWindowColor(0xFFFF0000);
final int windowColor = mCaptionHelper.getWindowColor();
assertThat(windowColor).isEqualTo(0xFFFF0000);
}
@Test
public void setEdgeColor_shouldReturnSpecificColor() {
mCaptionHelper.setEdgeColor(0xFFFF0000);
final int edgeColor = mCaptionHelper.getEdgeColor();
assertThat(edgeColor).isEqualTo(0xFFFF0000);
}
@Test
public void setEdgeType_shouldReturnSpecificType() {
mCaptionHelper.setEdgeType(CaptionStyle.EDGE_TYPE_OUTLINE);
final int edgeType = mCaptionHelper.getEdgeType();
assertThat(edgeType).isEqualTo(CaptionStyle.EDGE_TYPE_OUTLINE);
}
@Test
public void setRawUserStyle_shouldReturnSpecificStyle() {
mCaptionHelper.setRawUserStyle(CaptionStyle.PRESET_CUSTOM);
final int style = Settings.Secure.getInt(mContentResolver,
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 0);
assertThat(style).isEqualTo(CaptionStyle.PRESET_CUSTOM);
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2022 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.graphics.Color;
import android.view.accessibility.CaptioningManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link CaptionUtils}. */
@RunWith(RobolectricTestRunner.class)
public class CaptionUtilsTest {
@Test
public void parseColor_defaultPackedColor_shouldReturnUnspecified() {
final int color = CaptionUtils.parseColor(0xFFFF00);
assertThat(color).isEqualTo(CaptioningManager.CaptionStyle.COLOR_UNSPECIFIED);
}
@Test
public void parseColor_unrecognizedColor_shouldReturnTransparent() {
final int color = CaptionUtils.parseColor(0x00);
assertThat(color).isEqualTo(Color.TRANSPARENT);
}
@Test
public void parseColor_redColor_shouldReturnRed() {
final int color = CaptionUtils.parseColor(0xFFFF0000);
assertThat(color).isEqualTo(Color.RED);
}
@Test
public void parseOpacity_defaultPackedColor_shouldReturnUnspecified() {
final int color = CaptionUtils.parseOpacity(0xFFFF00);
assertThat(color).isEqualTo(CaptioningManager.CaptionStyle.COLOR_UNSPECIFIED);
}
@Test
public void parseOpacity_unrecognizedColor_shouldReturnTransparent() {
final int color = CaptionUtils.parseOpacity(0x00);
assertThat(color).isEqualTo(0xFFFFFF);
}
@Test
public void parseOpacity_halfTransparentValue_shouldReturnHalfTransparent() {
final int color = CaptionUtils.parseOpacity(0x80FFFFFF);
assertThat(color).isEqualTo(0x80FFFFFF);
}
@Test
public void mergeColorOpacity_halfTransparentRedValue_shouldReturnMergeColorOpacityValue() {
final int color = CaptionUtils.mergeColorOpacity(0xFFFF0000, 0x80FFFFFF);
assertThat(color).isEqualTo(0x80FF0000);
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2022 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.app.settings.SettingsEnums;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link CaptioningAppearanceFragment}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningAppearanceFragmentTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningAppearanceFragment mFragment;
@Before
public void setUp() {
mFragment = new CaptioningAppearanceFragment();
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_CAPTION_APPEARANCE);
}
@Test
public void getPreferenceScreenResId_returnsCorrectXml() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.captioning_appearance);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo("CaptioningAppearanceFragment");
}
@Test
public void getHelpResource_returnsCorrectHelpResource() {
assertThat(mFragment.getHelpResource()).isEqualTo(R.string.help_url_caption);
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = CaptioningAppearanceFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.captioning_appearance);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,182 @@
/*
* Copyright (C) 2022 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 android.view.accessibility.CaptioningManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningAppearancePreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningAppearancePreferenceControllerTest {
private static final String TEST_KEY = "test_key";
private static final int DEFAULT_PRESET_INDEX = 1;
private static final int DEFAULT_FONT_SCALE_INDEX = 2;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningAppearancePreferenceController mController;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
mController = new CaptioningAppearancePreferenceController(mContext, TEST_KEY);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_noScale_shouldReturnDefaultSummary() {
final String expectedSummary =
getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, DEFAULT_PRESET_INDEX);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_smallestScale_shouldReturnExpectedSummary() {
mShadowCaptioningManager.setFontScale(0.25f);
final String expectedSummary =
getSummaryCombo(/* fontScaleIndex= */ 0, DEFAULT_PRESET_INDEX);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_smallScale_shouldReturnExpectedSummary() {
mShadowCaptioningManager.setFontScale(0.5f);
final String expectedSummary =
getSummaryCombo(/* fontScaleIndex= */ 1, DEFAULT_PRESET_INDEX);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_mediumScale_shouldReturnExpectedSummary() {
mShadowCaptioningManager.setFontScale(1.0f);
final String expectedSummary =
getSummaryCombo(/* fontScaleIndex= */ 2, DEFAULT_PRESET_INDEX);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_largeScale_shouldReturnExpectedSummary() {
mShadowCaptioningManager.setFontScale(1.5f);
final String expectedSummary =
getSummaryCombo(/* fontScaleIndex= */ 3, DEFAULT_PRESET_INDEX);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_largestScale_shouldReturnExpectedSummary() {
mShadowCaptioningManager.setFontScale(2.0f);
final String expectedSummary =
getSummaryCombo(/* fontScaleIndex= */ 4, DEFAULT_PRESET_INDEX);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_setByAppPreset_shouldReturnExpectedSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 4);
final String expectedSummary =
getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 0);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_whiteOnBlackPreset_shouldReturnExpectedSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 0);
final String expectedSummary =
getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 1);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_blackOnWhitePreset_shouldReturnExpectedSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 1);
final String expectedSummary =
getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 2);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_yellowOnBlackPreset_shouldReturnExpectedSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 2);
final String expectedSummary =
getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 3);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_yellowOnBluePreset_shouldReturnExpectedSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 3);
final String expectedSummary =
getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 4);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
@Test
public void getSummary_customPreset_shouldReturnExpectedSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, -1);
final String expectedSummary =
getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 5);
assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
}
private String getSummaryCombo(int fontScaleIndex, int presetIndex) {
final String[] fontScaleArray = mContext.getResources().getStringArray(
R.array.captioning_font_size_selector_titles);
final String[] presetArray = mContext.getResources().getStringArray(
R.array.captioning_preset_selector_titles);
return mContext.getString(R.string.preference_summary_default_combination,
fontScaleArray[fontScaleIndex], presetArray[presetIndex]);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningBackgroundColorController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningBackgroundColorControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningBackgroundColorController mController;
private ColorPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningBackgroundColorController(mContext,
"captioning_background_color");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new ColorPreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnBlack() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("Black");
}
@Test
public void getSummary_redValue_shouldReturnRed() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0xFFFF0000);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("Red");
}
@Test
public void setRedValue_shouldReturnRed() {
mController.displayPreference(mScreen);
mPreference.setValue(0xFFFF0000);
assertThat(mPreference.getSummary().toString()).isEqualTo("Red");
}
@Test
public void setNoneColorValue_shouldNotHaveColor() {
final CaptionHelper captionHelper = new CaptionHelper(mContext);
captionHelper.setBackgroundColor(0xFFFF0000);
mController.displayPreference(mScreen);
mPreference.setValue(0x00FFFFFF);
assertThat(CaptionStyle.hasColor(captionHelper.getBackgroundColor())).isFalse();
}
@Test
public void setRedValueFromNoneValue_halfOpacityRedColor_shouldReturnExpectedColor() {
final CaptionHelper captionHelper = new CaptionHelper(mContext);
captionHelper.setBackgroundColor(0x80FF0000);
mController.displayPreference(mScreen);
mPreference.setValue(0x00FFFFFF);
mPreference.setValue(0xFFFF0000);
assertThat(captionHelper.getBackgroundColor()).isEqualTo(0x80FF0000);
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, 0xFFFF0000);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptionBackgroundOpacityController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningBackgroundOpacityControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningBackgroundOpacityController mController;
private ColorPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningBackgroundOpacityController(mContext,
"captioning_background_opacity");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new ColorPreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnNonTransparent() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("100%");
}
@Test
public void getSummary_halfTransparentValue_shouldReturnHalfTransparent() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, 0x80FFFFFF);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("50%");
}
@Test
public void setHalfTransparentValue_shouldReturnHalfTransparent() {
mController.displayPreference(mScreen);
mPreference.setValue(0x80FFFFFF);
assertThat(mPreference.getSummary().toString()).isEqualTo("50%");
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, 0x80FFFFFF);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) 2022 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.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link CaptioningCustomController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningCustomControllerTest {
private static final String PREF_KEY = "custom";
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
@Mock
private AccessibilitySettingsContentObserver mAccessibilitySettingsContentObserver;
private final Context mContext = ApplicationProvider.getApplicationContext();
private ContentResolver mContentResolver;
private CaptioningCustomController mController;
private Preference mPreference;
@Before
public void setUp() {
mContentResolver = mContext.getContentResolver();
mController = new CaptioningCustomController(mContext, PREF_KEY,
mAccessibilitySettingsContentObserver);
mPreference = new Preference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void displayPreference_byDefault_shouldIsInvisible() {
mController.displayPreference(mScreen);
assertThat(mPreference.isVisible()).isFalse();
}
@Test
public void displayPreference_customValue_shouldIsVisible() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, CaptionStyle.PRESET_CUSTOM);
mController.displayPreference(mScreen);
assertThat(mPreference.isVisible()).isTrue();
}
@Test
public void onStart_registerSpecificContentObserverForSpecificKeys() {
mController.onStart();
verify(mAccessibilitySettingsContentObserver).register(mContentResolver);
}
@Test
public void onStop_unregisterContentObserver() {
mController.onStop();
verify(mAccessibilitySettingsContentObserver).unregister(mContentResolver);
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningEdgeColorController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningEdgeColorControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningEdgeColorController mController;
private ColorPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningEdgeColorController(mContext, "captioning_edge_color");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new ColorPreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnBlack() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("Black");
}
@Test
public void getSummary_redValue_shouldReturnRed() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, 0xFFFF0000);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("Red");
}
@Test
public void setRedValue_shouldReturnRed() {
mController.displayPreference(mScreen);
mPreference.setValue(0xFFFF0000);
assertThat(mPreference.getSummary().toString()).isEqualTo("Red");
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, 0xFFFF0000);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningEdgeTypeController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningEdgeTypeControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningEdgeTypeController mController;
private EdgeTypePreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningEdgeTypeController(mContext, "captioning_edge_type");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new EdgeTypePreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnNone() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("None");
}
@Test
public void getSummary_outlineValue_shouldReturnOutline() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, CaptionStyle.EDGE_TYPE_OUTLINE);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("Outline");
}
@Test
public void setOutlineValue_shouldReturnOutline() {
mController.displayPreference(mScreen);
mPreference.setValue(CaptionStyle.EDGE_TYPE_OUTLINE);
assertThat(mPreference.getSummary().toString()).isEqualTo("Outline");
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, CaptionStyle.EDGE_TYPE_OUTLINE);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.view.accessibility.CaptioningManager;
import androidx.preference.ListPreference;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningFontSizeController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningFontSizeControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningFontSizeController mController;
private ListPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningFontSizeController(mContext, "captioning_font_size");
mPreference = new ListPreference(mContext);
mPreference.setEntries(R.array.captioning_font_size_selector_titles);
mPreference.setEntryValues(R.array.captioning_font_size_selector_values);
mPreference.setSummary("%s");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void updateState_byDefault_shouldReturnDefault() {
mController.updateState(mPreference);
assertThat(mPreference.getSummary().toString()).isEqualTo("Medium");
}
@Test
public void updateState_bySmallValue_shouldReturnSmall() {
mShadowCaptioningManager.setFontScale(0.5f);
mController.updateState(mPreference);
assertThat(mPreference.getSummary().toString()).isEqualTo("Small");
}
@Test
public void onPreferenceChange_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, "0.5");
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningForegroundColorController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningForegroundColorControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningForegroundColorController mController;
private ColorPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningForegroundColorController(mContext,
"captioning_foreground_color");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new ColorPreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnWhite() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("White");
}
@Test
public void getSummary_redValue_shouldReturnRed() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, 0xFFFF0000);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("Red");
}
@Test
public void setRedValue_shouldReturnRed() {
mController.displayPreference(mScreen);
mPreference.setValue(0xFFFF0000);
assertThat(mPreference.getSummary().toString()).isEqualTo("Red");
}
@Test
public void setNoneColorValue_shouldNotHaveColor() {
final CaptionHelper captionHelper = new CaptionHelper(mContext);
captionHelper.setForegroundColor(0xFFFF0000);
mController.displayPreference(mScreen);
mPreference.setValue(0x00FFFFFF);
assertThat(CaptionStyle.hasColor(captionHelper.getForegroundColor())).isFalse();
}
@Test
public void setRedValueFromNoneValue_halfOpacityRedColor_shouldReturnExpectedColor() {
final CaptionHelper captionHelper = new CaptionHelper(mContext);
captionHelper.setForegroundColor(0x80FF0000);
mController.displayPreference(mScreen);
mPreference.setValue(0x00FFFFFF);
mPreference.setValue(0xFFFF0000);
assertThat(captionHelper.getForegroundColor()).isEqualTo(0x80FF0000);
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, 0xFFFF0000);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningForegroundOpacityController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningForegroundOpacityControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningForegroundOpacityController mController;
private ColorPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningForegroundOpacityController(mContext,
"captioning_foreground_opacity");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new ColorPreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnNonTransparent() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("100%");
}
@Test
public void getSummary_halfTransparentValue_shouldReturnHalfTransparent() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, 0x80FFFFFF);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("50%");
}
@Test
public void setHalfTransparentValue_shouldReturnHalfTransparent() {
mController.displayPreference(mScreen);
mPreference.setValue(0x80FFFFFF);
assertThat(mPreference.getSummary().toString()).isEqualTo("50%");
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, 0x80FFFFFF);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2022 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.when;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link CaptioningLocalePreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningLocalePreferenceControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningLocalePreferenceController mController;
private LocalePreference mPreference;
@Before
public void setUp() {
mController = new CaptioningLocalePreferenceController(mContext, "captioning_local_pref");
mPreference = new LocalePreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void displayPreference_byDefault_shouldReturnDefault() {
mController.displayPreference(mScreen);
assertThat(mPreference.getEntry().toString()).isEqualTo(
mContext.getResources().getString(R.string.locale_default));
}
@Test
public void displayPreference_byArabicLocale_shouldReturnArabic() {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE, "af_ZA");
mController.displayPreference(mScreen);
assertThat(mPreference.getEntry().toString()).isEqualTo("Afrikaans");
}
@Test
public void onPreferenceChange_byArabicLocale_shouldReturnArabic() {
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, "af_ZA");
assertThat(mPreference.getEntry().toString()).isEqualTo("Afrikaans");
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2022 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.app.settings.SettingsEnums;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link CaptioningMoreOptionsFragment}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningMoreOptionsFragmentTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningMoreOptionsFragment mFragment;
@Before
public void setUp() {
mFragment = new CaptioningMoreOptionsFragment();
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_CAPTION_MORE_OPTIONS);
}
@Test
public void getPreferenceScreenResId_returnsCorrectXml() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
R.xml.captioning_more_options);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo("CaptioningMoreOptionsFragment");
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = CaptioningMoreOptionsFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.captioning_more_options);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link CaptioningPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningPreferenceControllerTest {
private Context mContext;
private CaptioningPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new CaptioningPreferenceController(mContext, "captioning_pref");
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_enabledCaptions_shouldReturnOnSummary() {
setCaptioningEnabled(true);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.show_captions_enabled));
}
@Test
public void getSummary_disabledCaptions_shouldReturnOffSummary() {
setCaptioningEnabled(false);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.show_captions_disabled));
}
private void setCaptioningEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, enabled ? ON : OFF);
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningPresetController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningPresetControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningPresetController mController;
private PresetPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningPresetController(mContext, "captioning_preset");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new PresetPreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnWhiteOnBlack() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("White on black");
}
@Test
public void getSummary_customValue_shouldReturnCustom() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, CaptionStyle.PRESET_CUSTOM);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("Custom");
}
@Test
public void setCustomValue_shouldReturnCustom() {
mController.displayPreference(mScreen);
mPreference.setValue(CaptionStyle.PRESET_CUSTOM);
assertThat(mPreference.getSummary().toString()).isEqualTo("Custom");
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, CaptionStyle.PRESET_CUSTOM);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2022 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.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.view.View;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.LayoutPreference;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link CaptioningPreviewPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningPreviewPreferenceControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
@Mock
private ContentResolver mContentResolver;
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningPreviewPreferenceController mController;
private LayoutPreference mLayoutPreference;
@Before
public void setUp() {
when(mContext.getContentResolver()).thenReturn(mContentResolver);
mController = new CaptioningPreviewPreferenceController(mContext,
"captioning_preference_switch");
final View view = new View(mContext);
mLayoutPreference = new LayoutPreference(mContext, view);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mLayoutPreference);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void onStart_registerSpecificContentObserverForSpecificKeys() {
mController.onStart();
for (String key : mController.CAPTIONING_FEATURE_KEYS) {
verify(mContentResolver).registerContentObserver(Settings.Secure.getUriFor(key),
/* notifyForDescendants= */ false, mController.mSettingsContentObserver);
}
}
@Test
public void onStop_unregisterContentObserver() {
mController.onStop();
verify(mContentResolver).unregisterContentObserver(mController.mSettingsContentObserver);
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2022 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.app.settings.SettingsEnums;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link CaptioningPropertiesFragment}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningPropertiesFragmentTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningPropertiesFragment mFragment;
@Before
public void setUp() {
mFragment = new CaptioningPropertiesFragment();
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_CAPTION_PROPERTIES);
}
@Test
public void getPreferenceScreenResId_returnsCorrectXml() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
R.xml.captioning_settings);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo("CaptioningPropertiesFragment");
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = CaptioningPropertiesFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.captioning_settings);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.view.accessibility.CaptioningManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.widget.SettingsMainSwitchPreference;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningTogglePreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningTogglePreferenceControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningTogglePreferenceController mController;
private SettingsMainSwitchPreference mSwitchPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningTogglePreferenceController(mContext,
"captioning_preference_switch");
mSwitchPreference = new SettingsMainSwitchPreference(mContext);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mSwitchPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@After
public void tearDown() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void displayPreference_captionEnabled_shouldSetChecked() {
mShadowCaptioningManager.setEnabled(true);
mController.displayPreference(mScreen);
assertThat(mSwitchPreference.isChecked()).isTrue();
}
@Test
public void displayPreference_captionDisabled_shouldSetUnchecked() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
assertThat(mSwitchPreference.isChecked()).isFalse();
}
@Test
public void performClick_captionEnabled_shouldSetCaptionDisabled() {
mShadowCaptioningManager.setEnabled(true);
mController.displayPreference(mScreen);
mSwitchPreference.performClick();
assertThat(mSwitchPreference.isChecked()).isFalse();
assertThat(isCaptionEnabled()).isFalse();
}
@Test
public void performClick_captionDisabled_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mSwitchPreference.performClick();
assertThat(mSwitchPreference.isChecked()).isTrue();
assertThat(isCaptionEnabled()).isTrue();
}
@Test
public void setChecked_switchChecked_shouldSetCaptionEnabled() {
mController.displayPreference(mScreen);
mController.setChecked(/* isChecked= */ true);
assertThat(isCaptionEnabled()).isTrue();
}
@Test
public void setChecked_switchUnchecked_shouldSetCaptionDisabled() {
mController.displayPreference(mScreen);
mController.setChecked(/* isChecked= */ false);
assertThat(isCaptionEnabled()).isFalse();
}
@Test
public void onSwitchChanged_switchChecked_shouldSetCaptionEnabled() {
mController.displayPreference(mScreen);
mController.onCheckedChanged(/* buttonView= */ null, /* isChecked= */ true);
assertThat(isCaptionEnabled()).isTrue();
}
@Test
public void onSwitchChanged_switchUnchecked_shouldSetCaptionDisabled() {
mController.displayPreference(mScreen);
mController.onCheckedChanged(/* buttonView= */ null, /* isChecked= */ false);
assertThat(isCaptionEnabled()).isFalse();
}
private boolean isCaptionEnabled() {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.view.accessibility.CaptioningManager;
import androidx.preference.ListPreference;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningTypefaceController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningTypefaceControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningTypefaceController mController;
private ListPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningTypefaceController(mContext, "captioning_typeface");
mPreference = new ListPreference(mContext);
mPreference.setEntries(R.array.captioning_typeface_selector_titles);
mPreference.setEntryValues(R.array.captioning_typeface_selector_values);
mPreference.setSummary("%s");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void updateState_byDefault_shouldReturnDefault() {
mController.updateState(mPreference);
assertThat(mPreference.getSummary().toString()).isEqualTo("Default");
}
@Test
public void updateState_bySerif_shouldReturnSerif() {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, "serif");
mController.updateState(mPreference);
assertThat(mPreference.getSummary().toString()).isEqualTo("Serif");
}
@Test
public void onPreferenceChange_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onPreferenceChange(mPreference, "serif");
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningWindowColorController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningWindowColorControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningWindowColorController mController;
private ColorPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningWindowColorController(mContext, "captioning_window_color");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new ColorPreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnNone() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo(
mContext.getString(R.string.color_none));
}
@Test
public void getSummary_redValue_shouldReturnRed() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0xFFFF0000);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("Red");
}
@Test
public void setRedValue_shouldReturnRed() {
mController.displayPreference(mScreen);
mPreference.setValue(0xFFFF0000);
assertThat(mPreference.getSummary().toString()).isEqualTo("Red");
}
@Test
public void setNoneColorValue_shouldNotHaveColor() {
final CaptionHelper captionHelper = new CaptionHelper(mContext);
captionHelper.setWindowColor(0xFFFF0000);
mController.displayPreference(mScreen);
mPreference.setValue(0x00FFFFFF);
assertThat(CaptionStyle.hasColor(captionHelper.getWindowColor())).isFalse();
}
@Test
public void setRedValueFromNoneValue_halfOpacityRedColor_shouldReturnExpectedColor() {
final CaptionHelper captionHelper = new CaptionHelper(mContext);
captionHelper.setWindowColor(0x80FF0000);
mController.displayPreference(mScreen);
mPreference.setValue(0x00FFFFFF);
mPreference.setValue(0xFFFF0000);
assertThat(captionHelper.getWindowColor()).isEqualTo(0x80FF0000);
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, 0xFFFF0000);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2022 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 static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowCaptioningManager;
/** Tests for {@link CaptioningWindowOpacityController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptioningWindowOpacityControllerTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private final Context mContext = ApplicationProvider.getApplicationContext();
private CaptioningWindowOpacityController mController;
private ColorPreference mPreference;
private ShadowCaptioningManager mShadowCaptioningManager;
@Before
public void setUp() {
mController = new CaptioningWindowOpacityController(mContext, "captioning_window_opacity");
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mPreference = new ColorPreference(mContext, attributeSet);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
mShadowCaptioningManager = Shadow.extract(captioningManager);
}
@Test
public void getAvailabilityStatus_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_defaultValue_shouldReturnNonTransparent() {
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("100%");
}
@Test
public void getSummary_halfTransparentValue_shouldReturnHalfTransparent() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, 0x80FFFFFF);
mController.displayPreference(mScreen);
assertThat(mPreference.getSummary().toString()).isEqualTo("50%");
}
@Test
public void setHalfTransparentValue_shouldReturnHalfTransparent() {
mController.displayPreference(mScreen);
mPreference.setValue(0x80FFFFFF);
assertThat(mPreference.getSummary().toString()).isEqualTo("50%");
}
@Test
public void onValueChanged_shouldSetCaptionEnabled() {
mShadowCaptioningManager.setEnabled(false);
mController.displayPreference(mScreen);
mController.onValueChanged(mPreference, 0x80FFFFFF);
final boolean isCaptionEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF) == ON;
assertThat(isCaptionEnabled).isTrue();
}
}

View File

@@ -0,0 +1,100 @@
/*
* 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 android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
import static com.google.common.truth.Truth.assertThat;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link ColorAndMotionFragment}. */
@RunWith(RobolectricTestRunner.class)
public class ColorAndMotionFragmentTest {
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
private final Context mContext = ApplicationProvider.getApplicationContext();
private ColorAndMotionFragment mFragment;
@Before
public void setUp() {
mFragment = new ColorAndMotionFragment();
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_COLOR_AND_MOTION);
}
@Test
public void getPreferenceScreenResId_returnsCorrectXml() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
R.xml.accessibility_color_and_motion);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo("ColorAndMotionFragment");
}
@Test
@RequiresFlagsEnabled(FLAG_FORCE_INVERT_COLOR)
public void forceInvertEnabled_getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = ColorAndMotionFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_color_and_motion);
assertThat(niks).doesNotContain(ColorAndMotionFragment.TOGGLE_FORCE_INVERT);
assertThat(keys).containsAtLeastElementsIn(niks);
}
@Test
@RequiresFlagsDisabled(FLAG_FORCE_INVERT_COLOR)
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = ColorAndMotionFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_color_and_motion);
assertThat(niks).contains(ColorAndMotionFragment.TOGGLE_FORCE_INVERT);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2024 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.spy;
import static org.mockito.Mockito.when;
import android.app.UiModeManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
/** Tests for {@link ColorContrastFragment}. */
@RunWith(RobolectricTestRunner.class)
public class ColorContrastFragmentTest {
private ColorContrastFragment mFragment;
private Context mContext;
@Mock
private UiModeManager mUiService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mFragment = spy(new ColorContrastFragment());
mContext = spy(ApplicationProvider.getApplicationContext());
when(mFragment.getContext()).thenReturn(mContext);
when(mContext.getSystemService(UiModeManager.class)).thenReturn(mUiService);
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.ACCESSIBILITY_COLOR_CONTRAST);
}
@Test
public void getPreferenceScreenResId_returnsCorrectXml() {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
R.xml.accessibility_color_contrast);
}
@Test
public void getLogTag_returnsCorrectTag() {
assertThat(mFragment.getLogTag()).isEqualTo("ColorContrastFragment");
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks =
ShortcutsSettingsFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_color_contrast);
assertThat(keys).containsAtLeastElementsIn(niks);
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@RunWith(RobolectricTestRunner.class)
public class ColorInversionPreferenceControllerTest {
private static final String PREF_KEY = "toggle_inversion_preference";
private static final String DISPLAY_INVERSION_ENABLED =
Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED;
private Context mContext;
private ColorInversionPreferenceController mController;
private String mColorInversionSummary;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new ColorInversionPreferenceController(mContext, PREF_KEY);
mColorInversionSummary = mContext.getString(R.string.color_inversion_feature_summary);
}
@Test
public void getSummary_enabledColorInversionShortcutOff_shouldReturnOnSummary() {
setColorInversionEnabled(true);
setColorInversionShortcutEnabled(false);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.color_inversion_state_on));
}
@Test
public void getSummary_enabledColorInversionShortcutOn_shouldReturnOnSummary() {
setColorInversionEnabled(true);
setColorInversionShortcutEnabled(true);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.color_inversion_state_on));
}
@Test
public void getSummary_disabledColorInversionShortcutOff_shouldReturnOffSummary() {
setColorInversionEnabled(false);
setColorInversionShortcutEnabled(false);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.color_inversion_state_off));
}
@Test
public void getSummary_disabledColorInversionShortcutOn_shouldReturnOffSummary() {
setColorInversionEnabled(false);
setColorInversionShortcutEnabled(true);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.color_inversion_state_off));
}
private void setColorInversionShortcutEnabled(boolean enabled) {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
enabled ? COLOR_INVERSION_COMPONENT_NAME.flattenToString() : "");
}
private void setColorInversionEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
DISPLAY_INVERSION_ENABLED, enabled ? State.ON : State.OFF);
}
@Retention(RetentionPolicy.SOURCE)
private @interface State {
int OFF = 0;
int ON = 1;
}
}

View File

@@ -0,0 +1,200 @@
/*
* 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.verify;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link ColorPreference}. */
@RunWith(RobolectricTestRunner.class)
public class ColorPreferenceTest {
private Context mContext;
private static final int COLOR_TRANSPARENT_VALUE = 0;
private static final int COLOR_WHITE_VALUE = 0xFFFFFFFF;
private static final int COLOR_BLACK_VALUE = 0xFF000000;
private static final String COLOR_TRANSPARENT = "TRANSPARENT";
private static final String COLOR_WHITE = "WHITE";
private static final String COLOR_BLACK = "BLACK";
private final int[] mColorValues =
{COLOR_TRANSPARENT_VALUE, COLOR_WHITE_VALUE, COLOR_BLACK_VALUE};
private final String[] mColorTitles = {COLOR_TRANSPARENT, COLOR_WHITE, COLOR_BLACK};
private View mRootView;
private ImageView mImageView;
private TextView mTextView;
private ColorPreference mColorPreference;
private PreferenceViewHolder mViewHolder;
@Before
public void init() {
mContext = ApplicationProvider.getApplicationContext();
mRootView = spy(new View(mContext));
mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(mRootView));
mImageView = spy(new ImageView(mContext));
mTextView = spy(new TextView(mContext));
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mColorPreference = new ColorPreference(mContext, attributeSet);
}
@Test
public void setPreviewEnabled_enabled_shouldSetCustomLayout() {
mColorPreference.setPreviewEnabled(true);
assertThat(mColorPreference.getWidgetLayoutResource()).isEqualTo(R.layout.preference_color);
}
@Test
public void setPreviewEnabled_disabled_shouldSetInvalidId() {
mColorPreference.setPreviewEnabled(false);
assertThat(mColorPreference.getWidgetLayoutResource()).isEqualTo(0);
}
@Test
public void setTitles_titlesExist_returnTitle() {
mColorPreference.setTitles(mColorTitles);
assertThat(mColorPreference.getTitleAt(/* index= */ 0)).isEqualTo(mColorTitles[0]);
assertThat(mColorPreference.getTitleAt(/* index= */ 1)).isEqualTo(mColorTitles[1]);
assertThat(mColorPreference.getTitleAt(/* index= */ 2)).isEqualTo(mColorTitles[2]);
}
@Test
public void setTitles_noTitle_returnRGBText() {
final int testIndex = 0;
mColorPreference.setValues(mColorValues);
final ListDialogPreference listDialogPreference = (ListDialogPreference) mColorPreference;
final int value = listDialogPreference.getValueAt(testIndex);
final int r = Color.red(value);
final int g = Color.green(value);
final int b = Color.blue(value);
final String rgbText = mContext.getString(R.string.color_custom, r, g, b);
mColorPreference.setTitles(null);
final CharSequence title = mColorPreference.getTitleAt(testIndex);
assertThat(title).isEqualTo(rgbText);
}
@Test
public void onBindViewHolder_enabled_transparent_matchBackgroundResource() {
doReturn(mImageView).when(mViewHolder).findViewById(R.id.color_preview);
mColorPreference.setPreviewEnabled(true);
mColorPreference.setEnabled(true);
mColorPreference.setTitles(mColorTitles);
mColorPreference.setValues(mColorValues);
mColorPreference.setValue(COLOR_TRANSPARENT_VALUE);
mColorPreference.onBindViewHolder(mViewHolder);
verify(mImageView).setBackgroundResource(R.drawable.transparency_tileable);
}
@Test
public void onBindViewHolder_enabled_titlesExist_matchDescription() {
doReturn(mImageView).when(mViewHolder).findViewById(R.id.color_preview);
mColorPreference.setPreviewEnabled(true);
mColorPreference.setEnabled(true);
mColorPreference.setTitles(mColorTitles);
mColorPreference.setValues(mColorValues);
mColorPreference.setValue(COLOR_WHITE_VALUE);
mColorPreference.onBindViewHolder(mViewHolder);
verify(mImageView).setContentDescription(COLOR_WHITE);
}
@Test
public void onBindViewHolder_disabled_matchAlpha() {
doReturn(mImageView).when(mViewHolder).findViewById(R.id.color_preview);
mColorPreference.setPreviewEnabled(true);
mColorPreference.setValues(mColorValues);
mColorPreference.setValue(COLOR_WHITE_VALUE);
mColorPreference.setEnabled(false);
mColorPreference.onBindViewHolder(mViewHolder);
verify(mImageView).setAlpha(0.2f);
}
@Test
public void onBindListItem_transparent_matchBackgroundResource() {
final int colorTransparentIndex = 0;
doReturn(mImageView).when(mRootView).findViewById(R.id.color_swatch);
doReturn(mTextView).when(mRootView).findViewById(R.id.summary);
mColorPreference.setTitles(mColorTitles);
mColorPreference.setValues(mColorValues);
mColorPreference.onBindListItem(mRootView, colorTransparentIndex);
verify(mImageView).setBackgroundResource(R.drawable.transparency_tileable);
}
@Test
public void onBindListItem_colorDrawable_matchColor() {
final int testIndex = 0;
final ColorDrawable colorDrawable = spy(new ColorDrawable());
doReturn(mImageView).when(mRootView).findViewById(R.id.color_swatch);
doReturn(colorDrawable).when(mImageView).getDrawable();
doReturn(mTextView).when(mRootView).findViewById(R.id.summary);
mColorPreference.setTitles(mColorTitles);
mColorPreference.setValues(mColorValues);
mColorPreference.onBindListItem(mRootView, testIndex);
final int argb = mColorPreference.getValueAt(testIndex);
final int alpha = Color.alpha(argb);
verify(colorDrawable).setColor(alpha);
}
@Test
public void onBindListItem_colorDrawable_matchSummary() {
final int testIndex = 0;
doReturn(mImageView).when(mRootView).findViewById(R.id.color_swatch);
doReturn(mTextView).when(mRootView).findViewById(R.id.summary);
mColorPreference.setTitles(mColorTitles);
mColorPreference.setValues(mColorValues);
mColorPreference.onBindListItem(mRootView, /* index= */ testIndex);
final CharSequence title = mColorPreference.getTitleAt(testIndex);
verify(mTextView).setText(title);
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2023 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.graphics.Color;
import androidx.annotation.ColorInt;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class ColorSelectorLayoutTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
ColorSelectorLayout mColorSelectorLayout;
@ColorInt
int mCheckedColor = Color.TRANSPARENT;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mColorSelectorLayout = new ColorSelectorLayout(mContext);
mColorSelectorLayout.setOnCheckedChangeListener(
layout -> mCheckedColor = layout.getCheckedColor(Color.TRANSPARENT));
}
@Test
public void setColor_checkColorChanged() {
mColorSelectorLayout.setCheckedColor(ScreenFlashNotificationColor.AZURE.mColorInt);
assertThat(mCheckedColor)
.isEqualTo(ScreenFlashNotificationColor.AZURE.mColorInt);
}
@Test
public void getCheckedColor_defaultValue() {
assertThat(mColorSelectorLayout.getCheckedColor(0xFF000000))
.isEqualTo(0xFF000000);
}
@Test
public void setSelectedColor_checkColorChanged() {
mColorSelectorLayout.setCheckedColor(ScreenFlashNotificationColor.AZURE.mColorInt);
assertThat(mColorSelectorLayout.getCheckedColor(0xFF000000))
.isEqualTo(ScreenFlashNotificationColor.AZURE.mColorInt);
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2024 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.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link ContrastPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class ContrastPreferenceControllerTest {
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PREFERENCE_KEY = "preference_key";
private Context mContext;
private ContrastPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new ContrastPreferenceController(mContext, PREFERENCE_KEY);
}
@Test
public void getAvailabilityStatus_flagsEnabled_shouldReturnAvailable() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_COLOR_CONTRAST_CONTROL);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_flagsDisabled_shouldReturnUnsupported() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_COLOR_CONTRAST_CONTROL);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2024 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.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
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.app.UiModeManager;
import android.content.Context;
import android.widget.FrameLayout;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.LayoutPreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import java.util.concurrent.Executor;
/** Tests for {@link ContrastSelectorPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class ContrastSelectorPreferenceControllerTest {
private static final String PREFERENCE_KEY = "color_contrast_selector";
@Mock
private UiModeManager mUiService;
@Mock
private Executor mExecutor;
@Mock
private PreferenceScreen mScreen;
@Mock
private FrameLayout mFrameLayout;
@Mock
private LayoutPreference mLayoutPreference;
private Context mContext;
private ContrastSelectorPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
when(mContext.getMainExecutor()).thenReturn(mExecutor);
when(mContext.getSystemService(UiModeManager.class)).thenReturn(mUiService);
mController = new ContrastSelectorPreferenceController(mContext, PREFERENCE_KEY);
when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mLayoutPreference);
when(mLayoutPreference.findViewById(anyInt())).thenReturn(mFrameLayout);
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void onStart_shouldAddContrastListener() {
mController.displayPreference(mScreen);
mController.onStart();
verify(mUiService).addContrastChangeListener(mExecutor, mController);
}
@Test
public void onStop_shouldRemoveContrastListener() {
mController.displayPreference(mScreen);
mController.onStart();
mController.onStop();
verify(mUiService).removeContrastChangeListener(mController);
}
@Test
public void displayPreference_shouldAddClickListener() {
mController.displayPreference(mScreen);
verify(mFrameLayout, times(3)).setOnClickListener(any());
}
@Test
public void onContrastChanged_buttonShouldBeSelected() {
mController.displayPreference(mScreen);
mController.onContrastChanged(1);
verify(mFrameLayout, times(2)).setSelected(true);
}
}

View File

@@ -0,0 +1,98 @@
/*
* 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.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class DaltonizerPreferenceControllerTest {
private static final String PREF_KEY = "daltonizer_preference";
private static final int ON = 1;
private static final int OFF = 0;
private Context mContext;
private DaltonizerPreferenceController mController;
private String mDaltonizerSummary;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new DaltonizerPreferenceController(mContext, PREF_KEY);
mDaltonizerSummary = mContext.getString(R.string.daltonizer_feature_summary);
}
@Test
public void getSummary_enabledColorCorrectionShortcutOff_shouldReturnOnSummary() {
setColorCorrectionEnabled(true);
setColorCorrectionShortcutEnabled(false);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.daltonizer_state_on));
}
@Test
public void getSummary_enabledColorCorrectionShortcutOn_shouldReturnOnSummary() {
setColorCorrectionEnabled(true);
setColorCorrectionShortcutEnabled(true);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.daltonizer_state_on));
}
@Test
public void getSummary_disabledColorCorrectionShortcutOff_shouldReturnOffSummary() {
setColorCorrectionEnabled(false);
setColorCorrectionShortcutEnabled(false);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.daltonizer_state_off));
}
@Test
public void getSummary_disabledColorCorrectionShortcutOn_shouldReturnOffSummary() {
setColorCorrectionEnabled(false);
setColorCorrectionShortcutEnabled(true);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.daltonizer_state_off));
}
private void setColorCorrectionEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, enabled ? ON : OFF);
}
private void setColorCorrectionShortcutEnabled(boolean enabled) {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
enabled ? DALTONIZER_COMPONENT_NAME.flattenToString() : "");
}
}

View File

@@ -0,0 +1,116 @@
/*
* 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.SelectorWithWidgetPreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class DaltonizerRadioButtonPreferenceControllerTest implements
DaltonizerRadioButtonPreferenceController.OnChangeListener {
private static final String PREF_KEY = "daltonizer_mode_protanomaly";
private static final String PREF_VALUE = "11";
private static final String PREF_FAKE_VALUE = "-1";
private DaltonizerRadioButtonPreferenceController mController;
@Mock
private SelectorWithWidgetPreference mMockPref;
private Context mContext;
@Mock
private PreferenceScreen mScreen;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new DaltonizerRadioButtonPreferenceController(mContext, mock(Lifecycle.class),
PREF_KEY);
mController.setOnChangeListener(this);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
when(mMockPref.getKey()).thenReturn(PREF_KEY);
mController.displayPreference(mScreen);
}
@Override
public void onCheckedChanged(Preference preference) {
mController.updateState(preference);
}
@Test
public void isAvailable() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void updateState_notChecked() {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, PREF_FAKE_VALUE);
mController.updateState(mMockPref);
// the first checked state is set to false by control
verify(mMockPref, atLeastOnce()).setChecked(false);
verify(mMockPref, never()).setChecked(true);
}
@Test
public void updateState_checked() {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, PREF_VALUE);
mController.updateState(mMockPref);
// the first checked state is set to false by control
verify(mMockPref, atLeastOnce()).setChecked(false);
verify(mMockPref, atLeastOnce()).setChecked(true);
}
@Test
public void onRadioButtonClick_shouldReturnDaltonizerValue() {
mController.onRadioButtonClicked(mMockPref);
final String accessibilityDaltonizerValue = Settings.Secure.getString(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
assertThat(accessibilityDaltonizerValue).isEqualTo(PREF_VALUE);
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.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.verify;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import android.widget.TextView;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.widget.SubtitleView;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link EdgeTypePreference}. */
@RunWith(RobolectricTestRunner.class)
public class EdgeTypePreferenceTest {
private Context mContext;
private View mRootView;
private TextView mSummaryView;
private SubtitleView mSubtitleView;
private EdgeTypePreference mEdgeTypePreference;
@Before
public void init() {
mContext = ApplicationProvider.getApplicationContext();
mRootView = spy(new View(mContext));
mSummaryView = spy(new TextView(mContext));
mSubtitleView = spy(new SubtitleView(mContext));
final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
mEdgeTypePreference = spy(new EdgeTypePreference(mContext, attributeSet));
doReturn(mSubtitleView).when(mRootView).findViewById(R.id.preview);
doReturn(mSummaryView).when(mRootView).findViewById(R.id.summary);
}
@Test
public void shouldDisableDependents_edgeTypeNone_returnTrue() {
mEdgeTypePreference.setValue(CaptionStyle.EDGE_TYPE_NONE);
final boolean shouldDisableDependents =
mEdgeTypePreference.shouldDisableDependents();
assertThat(shouldDisableDependents).isTrue();
}
@Test
public void onBindListItem_initSubtitleView() {
final int testIndex = 0;
mEdgeTypePreference.onBindListItem(mRootView, testIndex);
final float density = mContext.getResources().getDisplayMetrics().density;
final int value = mEdgeTypePreference.getValueAt(testIndex);
verify(mSubtitleView).setForegroundColor(Color.WHITE);
verify(mSubtitleView).setBackgroundColor(Color.TRANSPARENT);
verify(mSubtitleView).setTextSize(32f * density);
verify(mSubtitleView).setEdgeType(value);
verify(mSubtitleView).setEdgeColor(Color.BLACK);
}
@Test
public void onBindListItem_setSummary() {
final int testIndex = 0;
mEdgeTypePreference.onBindListItem(mRootView, testIndex);
final CharSequence title = mEdgeTypePreference.getTitleAt(testIndex);
verify(mSummaryView).setText(title);
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (C) 2023 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.ShadowFlashNotificationsUtils.setFlashNotificationsState;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowFlashNotificationsUtils.class)
public class FlashNotificationsPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private FlashNotificationsPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new FlashNotificationsPreferenceController(mContext, PREFERENCE_KEY);
}
@After
public void tearDown() {
ShadowFlashNotificationsUtils.reset();
}
@Test
public void getAvailabilityStatus() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getSummary_stateOff_assertOff() {
setFlashNotificationsState(FlashNotificationsUtil.State.OFF);
assertThat(mController.getSummary().toString()).isEqualTo(mContext.getString(
R.string.flash_notifications_summary_off));
}
@Test
public void getSummary_stateCamera_assertCamera() {
setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA);
assertThat(mController.getSummary().toString()).isEqualTo(mContext.getString(
R.string.flash_notifications_summary_on_camera));
}
@Test
public void getSummary_stateScreen_assertScreen() {
setFlashNotificationsState(FlashNotificationsUtil.State.SCREEN);
assertThat(mController.getSummary().toString()).isEqualTo(mContext.getString(
R.string.flash_notifications_summary_on_screen));
}
@Test
public void getSummary_stateCameraScreen_assertCameraScreen() {
setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA_SCREEN);
assertThat(mController.getSummary().toString()).isEqualTo(mContext.getString(
R.string.flash_notifications_summary_on_camera_and_screen));
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2023 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.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.app.settings.SettingsEnums;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class FlashNotificationsPreferenceFragmentTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private FlashNotificationsPreferenceFragment mFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mFragment = new FlashNotificationsPreferenceFragment();
}
@Test
public void getPreferenceScreenResId_isFlashNotificationsSettings() {
assertThat(mFragment.getPreferenceScreenResId())
.isEqualTo(R.xml.flash_notifications_settings);
}
@Test
public void getLogTag_isSpecifyTag() {
assertThat(mFragment.getLogTag()).isEqualTo("FlashNotificationsPreferenceFragment");
}
@Test
public void getMetricsCategory_returnsCorrectCategory() {
assertThat(mFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.FLASH_NOTIFICATION_SETTINGS);
}
@Test
public void onAttach_attachedTheTestFragment() {
ScreenFlashNotificationPreferenceController controller = mock(
ScreenFlashNotificationPreferenceController.class);
TestFlashNotificationsPreferenceFragment testFragment =
new TestFlashNotificationsPreferenceFragment(controller);
testFragment.onAttach(mContext);
verify(controller).setParentFragment(eq(testFragment));
}
@Test
public void getHelpResource_isExpectedResource() {
assertThat(mFragment.getHelpResource())
.isEqualTo(R.string.help_url_flash_notifications);
}
static class TestFlashNotificationsPreferenceFragment extends
FlashNotificationsPreferenceFragment {
final AbstractPreferenceController mController;
TestFlashNotificationsPreferenceFragment(AbstractPreferenceController controller) {
mController = controller;
}
@Override
protected <T extends AbstractPreferenceController> T use(Class<T> clazz) {
return (T) mController;
}
}
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (C) 2023 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.FlashNotificationsUtil.ACTION_FLASH_NOTIFICATION_START_PREVIEW;
import static com.android.settings.accessibility.FlashNotificationsUtil.EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE;
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_LONG_PREVIEW;
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_SHORT_PREVIEW;
import static com.android.settings.accessibility.ShadowFlashNotificationsUtils.setFlashNotificationsState;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
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.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowFlashNotificationsUtils.class)
public class FlashNotificationsPreviewPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Mock
private PreferenceScreen mPreferenceScreen;
@Mock
private Preference mPreference;
@Spy
private ContentResolver mContentResolver = mContext.getContentResolver();
private FlashNotificationsPreviewPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mPreferenceScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
when(mPreference.getKey()).thenReturn(PREFERENCE_KEY);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
mController = new FlashNotificationsPreviewPreferenceController(mContext, PREFERENCE_KEY);
}
@After
public void tearDown() {
ShadowFlashNotificationsUtils.reset();
}
@Test
public void testGetAvailabilityStatus() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void testDisplayPreference_torchPresent_cameraOff_screenOff_verifyDisabled() {
setFlashNotificationsState(FlashNotificationsUtil.State.OFF);
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setEnabled(eq(false));
}
@Test
public void testDisplayPreference_torchPresent_cameraOn_screenOff_verifyEnabled() {
setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA);
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setEnabled(eq(true));
}
@Test
public void testDisplayPreference_torchPresent_cameraOff_screenOn_verifyEnabled() {
setFlashNotificationsState(FlashNotificationsUtil.State.SCREEN);
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setEnabled(eq(true));
}
@Test
public void testDisplayPreference_torchPresent_cameraOn_screenOn_verifyEnabled() {
setFlashNotificationsState(FlashNotificationsUtil.State.CAMERA_SCREEN);
mController.displayPreference(mPreferenceScreen);
verify(mPreference).setEnabled(eq(true));
}
@Test
public void testHandlePreferenceTreeClick_invalidPreference() {
mController.handlePreferenceTreeClick(mock(Preference.class));
verify(mContext, never()).sendBroadcastAsUser(any(), any());
}
@Test
public void handlePreferenceTreeClick_assertAction() {
mController.handlePreferenceTreeClick(mPreference);
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).sendBroadcastAsUser(captor.capture(), any());
Intent captured = captor.getValue();
assertThat(captured.getAction()).isEqualTo(ACTION_FLASH_NOTIFICATION_START_PREVIEW);
}
@Test
public void handlePreferenceTreeClick_assertExtra() {
mController.handlePreferenceTreeClick(mPreference);
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).sendBroadcastAsUser(captor.capture(), any());
Intent captured = captor.getValue();
assertThat(captured.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE, TYPE_LONG_PREVIEW))
.isEqualTo(TYPE_SHORT_PREVIEW);
}
@Test
public void onStateChanged_onResume_cameraUri_verifyRegister() {
mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_RESUME);
verify(mContentResolver).registerContentObserver(
eq(Settings.System.getUriFor(Settings.System.CAMERA_FLASH_NOTIFICATION)),
anyBoolean(), eq(mController.mContentObserver));
}
@Test
public void onStateChanged_onResume_screenUri_verifyRegister() {
mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_RESUME);
verify(mContentResolver).registerContentObserver(
eq(Settings.System.getUriFor(Settings.System.SCREEN_FLASH_NOTIFICATION)),
anyBoolean(), eq(mController.mContentObserver));
}
@Test
public void onStateChanged_onPause_verifyUnregister() {
mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_PAUSE);
verify(mContentResolver).unregisterContentObserver(eq(mController.mContentObserver));
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2023 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.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.Utils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
@RunWith(RobolectricTestRunner.class)
public class FlashNotificationsPreviewPreferenceTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
private FlashNotificationsPreviewPreference mFlashNotificationsPreviewPreference;
private PreferenceViewHolder mPreferenceViewHolder;
@Before
public void setUp() {
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(
LayoutInflater.from(mContext).inflate(
R.layout.flash_notification_preview_preference, null));
mFlashNotificationsPreviewPreference = new FlashNotificationsPreviewPreference(mContext);
}
@Test
public void setEnabled_true_verifyEnabledUi() {
@ColorInt final int textColorEnabled = ((TextView) mPreferenceViewHolder.findViewById(
android.R.id.title)).getCurrentTextColor();
mFlashNotificationsPreviewPreference.setEnabled(true);
mFlashNotificationsPreviewPreference.onBindViewHolder(mPreferenceViewHolder);
final View frame = mPreferenceViewHolder.findViewById(R.id.frame);
final int backgroundResId = Shadows.shadowOf(frame.getBackground()).getCreatedFromResId();
assertThat(backgroundResId).isEqualTo(
com.android.settingslib.widget.mainswitch.R.drawable.settingslib_switch_bar_bg_on);
final TextView title = (TextView) mPreferenceViewHolder.findViewById(android.R.id.title);
assertThat(title.getAlpha()).isEqualTo(1f);
assertThat(title.getCurrentTextColor()).isEqualTo(textColorEnabled);
}
@Test
public void setEnabled_false_verifyDisabledUi() {
@ColorInt final int textColorDisabled = Utils.getColorAttrDefaultColor(mContext,
android.R.attr.textColorPrimary);
mFlashNotificationsPreviewPreference.setEnabled(false);
mFlashNotificationsPreviewPreference.onBindViewHolder(mPreferenceViewHolder);
final View frame = mPreferenceViewHolder.findViewById(R.id.frame);
final int backgroundResId = Shadows.shadowOf(frame.getBackground()).getCreatedFromResId();
assertThat(backgroundResId).isEqualTo(R.drawable.switch_bar_bg_disabled);
final TextView title = (TextView) mPreferenceViewHolder.findViewById(android.R.id.title);
assertThat(title.getAlpha()).isEqualTo(0.38f);
assertThat(title.getCurrentTextColor()).isEqualTo(textColorDisabled);
}
}

View File

@@ -0,0 +1,220 @@
/*
* Copyright (C) 2023 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 android.hardware.camera2.CameraCharacteristics.FLASH_INFO_AVAILABLE;
import static android.hardware.camera2.CameraCharacteristics.LENS_FACING;
import static android.hardware.camera2.CameraCharacteristics.LENS_FACING_BACK;
import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.accessibility.FlashNotificationsUtil.getColorDescriptionText;
import static com.android.settings.accessibility.FlashNotificationsUtil.getFlashNotificationsState;
import static com.android.settings.accessibility.FlashNotificationsUtil.getScreenColor;
import static com.android.settings.accessibility.FlashNotificationsUtil.isTorchAvailable;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.when;
import static org.robolectric.shadow.api.Shadow.extract;
import static org.robolectric.shadows.ShadowCameraCharacteristics.newCameraCharacteristics;
import android.content.ContentResolver;
import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowCameraCharacteristics;
import org.robolectric.shadows.ShadowCameraManager;
@RunWith(RobolectricTestRunner.class)
public class FlashNotificationsUtilTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
@Spy
private Context mContext = ApplicationProvider.getApplicationContext();
@Spy
private CameraManager mCameraManager = mContext.getSystemService(CameraManager.class);
private ShadowCameraManager mShadowCameraManager;
private ContentResolver mContentResolver;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mShadowCameraManager = Shadows.shadowOf(mCameraManager);
mContentResolver = mContext.getContentResolver();
}
@Test
public void isTorchAvailable_nullCameraManager_assertFalse() {
when(mContext.getSystemService(CameraManager.class)).thenReturn(null);
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_noCamera_assertFalse() {
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_getCameraIdListThrowException_assertFalse()
throws CameraAccessException {
when(mCameraManager.getCameraIdList()).thenThrow(CameraAccessException.class);
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_getCameraCharacteristicsThrowException_assertFalse()
throws CameraAccessException {
CameraCharacteristics cameraCharacteristics = newCameraCharacteristics();
mShadowCameraManager.addCamera("0", cameraCharacteristics);
when(mCameraManager.getCameraCharacteristics("0")).thenThrow(CameraAccessException.class);
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_torchNotPresent_assertFalse() {
setTorchNotPresent();
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void isTorchAvailable_torchPresent_assertTrue() {
setTorchPresent();
assertThat(isTorchAvailable(mContext)).isTrue();
}
@Test
public void isTorchAvailable_lensFacingFront_assertFalse() {
CameraCharacteristics cameraCharacteristics = newCameraCharacteristics();
ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics);
shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, true);
shadowCameraCharacteristics.set(LENS_FACING, LENS_FACING_FRONT);
mShadowCameraManager.addCamera("0", cameraCharacteristics);
assertThat(isTorchAvailable(mContext)).isFalse();
}
@Test
public void getScreenColor_undefinedColor_throwException() {
assertThrows(FlashNotificationsUtil.ScreenColorNotFoundException.class, () ->
getScreenColor(0x4D0000FF));
}
@Test
public void getScreenColor_azureColor_returnAzure() throws Exception {
assertThat(getScreenColor(0x660080FF)).isEqualTo(ScreenFlashNotificationColor.AZURE);
}
@Test
public void getColorDescriptionText_undefinedColor_returnEmpty() {
assertThat(getColorDescriptionText(mContext, 0x4D0000FF)).isEqualTo("");
}
@Test
public void getColorDescriptionText_azureColor_returnAzureName() {
assertThat(getColorDescriptionText(mContext, ScreenFlashNotificationColor.AZURE.mColorInt))
.isEqualTo(mContext.getString(ScreenFlashNotificationColor.AZURE.mStringRes));
}
@Test
public void getFlashNotificationsState_torchPresent_cameraOff_screenOff_assertOff() {
setTorchPresent();
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, OFF);
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.OFF);
}
@Test
public void getFlashNotificationsState_torchNotPresent_cameraOn_screenOff_assertOff() {
setTorchNotPresent();
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON);
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.OFF);
}
@Test
public void getFlashNotificationsState_torchPresent_cameraOn_screenOff_assertCamera() {
setTorchPresent();
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON);
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.CAMERA);
}
@Test
public void getFlashNotificationsState_torchPresent_cameraOff_screenOn_assertScreen() {
setTorchPresent();
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, OFF);
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, ON);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.SCREEN);
}
@Test
public void testGetFlashNotificationsState_torchPresent_cameraOn_screenOn_assertCameraScreen() {
setTorchPresent();
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON);
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, ON);
assertThat(getFlashNotificationsState(mContext))
.isEqualTo(FlashNotificationsUtil.State.CAMERA_SCREEN);
}
private void setTorchPresent() {
CameraCharacteristics cameraCharacteristics = newCameraCharacteristics();
ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics);
shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, true);
shadowCameraCharacteristics.set(LENS_FACING, LENS_FACING_BACK);
mShadowCameraManager.addCamera("0", cameraCharacteristics);
}
private void setTorchNotPresent() {
CameraCharacteristics cameraCharacteristics = newCameraCharacteristics();
ShadowCameraCharacteristics shadowCameraCharacteristics = extract(cameraCharacteristics);
shadowCameraCharacteristics.set(FLASH_INFO_AVAILABLE, false);
mShadowCameraManager.addCamera("0", cameraCharacteristics);
}
}

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