Merge "[Settings] Remove failure JUnit test cases"

This commit is contained in:
Arc Wang
2020-10-08 06:57:35 +00:00
committed by Android (Google) Code Review
32 changed files with 0 additions and 4299 deletions

View File

@@ -1,211 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.MODE_ERRORED;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.widget.Switch;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.InstrumentationRegistry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
/**
* An abstract parent for testing settings activities that manage an AppOps permission.
*/
abstract public class AppOpsSettingsTest {
private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
private static final long START_ACTIVITY_TIMEOUT = 5000;
private Context mContext;
private UiDevice mUiDevice;
private PackageManager mPackageManager;
private AppOpsManager mAppOpsManager;
private List<UserInfo> mProfiles;
private String mPackageName;
// These depend on which app op's settings UI is being tested.
private final String mActivityAction;
private final int mAppOpCode;
protected AppOpsSettingsTest(String activityAction, int appOpCode) {
mActivityAction = activityAction;
mAppOpCode = appOpCode;
}
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mPackageName = InstrumentationRegistry.getContext().getPackageName();
mPackageManager = mContext.getPackageManager();
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
mProfiles = mContext.getSystemService(UserManager.class).getProfiles(UserHandle.myUserId());
resetAppOpModeForAllProfiles();
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mUiDevice.wakeUp();
mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
}
private void resetAppOpModeForAllProfiles() throws Exception {
for (UserInfo user : mProfiles) {
final int uid = mPackageManager.getPackageUidAsUser(mPackageName, user.id);
mAppOpsManager.setMode(mAppOpCode, uid, mPackageName, MODE_DEFAULT);
}
}
/**
* Creates an intent for showing the permission settings for all apps.
*/
private Intent createManageAllAppsIntent() {
final Intent intent = new Intent(mActivityAction);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
return intent;
}
/**
* Creates an intent for showing the permission setting for a single app.
*/
private Intent createManageSingleAppIntent(String packageName) {
final Intent intent = createManageAllAppsIntent();
intent.setData(Uri.parse("package:" + packageName));
return intent;
}
private String getApplicationLabel(String packageName) throws Exception {
final ApplicationInfo info = mPackageManager.getApplicationInfo(packageName, 0);
return mPackageManager.getApplicationLabel(info).toString();
}
private UiObject2 findAndVerifySwitchState(boolean checked) {
final BySelector switchSelector = By.clazz(Switch.class).res("android:id/switch_widget");
final UiObject2 switchPref = mUiDevice.wait(Until.findObject(switchSelector),
START_ACTIVITY_TIMEOUT);
assertNotNull("Switch not shown", switchPref);
assertTrue("Switch in invalid state", switchPref.isChecked() == checked);
return switchPref;
}
@Test
public void testAppList() throws Exception {
final String testAppLabel = getApplicationLabel(mPackageName);
mContext.startActivity(createManageAllAppsIntent());
final BySelector preferenceListSelector =
By.clazz(RecyclerView.class).res("com.android.settings:id/apps_list");
final UiObject2 preferenceList = mUiDevice.wait(Until.findObject(preferenceListSelector),
START_ACTIVITY_TIMEOUT);
assertNotNull("App list not shown", preferenceList);
final BySelector appLabelTextViewSelector = By.clazz(TextView.class)
.res("android:id/title")
.text(testAppLabel);
List<UiObject2> listOfMatchingTextViews;
do {
listOfMatchingTextViews = preferenceList.findObjects(appLabelTextViewSelector);
// assuming the number of profiles will be sufficiently small so that all the entries
// for the same package will fit in one screen at some time during the scroll.
} while (listOfMatchingTextViews.size() != mProfiles.size() &&
preferenceList.scroll(Direction.DOWN, 0.2f));
assertEquals("Test app not listed for each profile", mProfiles.size(),
listOfMatchingTextViews.size());
for (UiObject2 matchingObject : listOfMatchingTextViews) {
matchingObject.click();
findAndVerifySwitchState(true);
mUiDevice.pressBack();
}
}
private void testAppDetailScreenForAppOp(int appOpMode, int userId) throws Exception {
final String testAppLabel = getApplicationLabel(mPackageName);
final BySelector appDetailTitleSelector = By.clazz(TextView.class)
.res("com.android.settings:id/app_detail_title")
.text(testAppLabel);
mAppOpsManager.setMode(mAppOpCode,
mPackageManager.getPackageUidAsUser(mPackageName, userId), mPackageName, appOpMode);
mContext.startActivityAsUser(createManageSingleAppIntent(mPackageName),
UserHandle.of(userId));
mUiDevice.wait(Until.findObject(appDetailTitleSelector), START_ACTIVITY_TIMEOUT);
findAndVerifySwitchState(appOpMode == MODE_ALLOWED || appOpMode == MODE_DEFAULT);
mUiDevice.pressBack();
}
@Test
public void testSingleApp() throws Exception {
// App op MODE_DEFAULT is already tested in #testAppList
for (UserInfo user : mProfiles) {
testAppDetailScreenForAppOp(MODE_ALLOWED, user.id);
testAppDetailScreenForAppOp(MODE_ERRORED, user.id);
}
}
private void testSwitchToggle(int fromAppOp, int toAppOp) throws Exception {
final int packageUid = mPackageManager.getPackageUid(mPackageName, 0);
final boolean initialState = (fromAppOp == MODE_ALLOWED || fromAppOp == MODE_DEFAULT);
mAppOpsManager.setMode(mAppOpCode, packageUid, mPackageName, fromAppOp);
mContext.startActivity(createManageSingleAppIntent(mPackageName));
final UiObject2 switchPref = findAndVerifySwitchState(initialState);
switchPref.click();
Thread.sleep(1000);
assertEquals("Toggling switch did not change app op", toAppOp,
mAppOpsManager.checkOpNoThrow(mAppOpCode, packageUid,
mPackageName));
mUiDevice.pressBack();
}
@Test
public void testIfSwitchTogglesAppOp() throws Exception {
testSwitchToggle(MODE_ALLOWED, MODE_ERRORED);
testSwitchToggle(MODE_ERRORED, MODE_ALLOWED);
}
@After
public void tearDown() throws Exception {
mUiDevice.pressHome();
resetAppOpModeForAllProfiles();
}
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications;
import android.app.AppOpsManager;
import android.provider.Settings;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class DrawOverlaySettingsTest extends AppOpsSettingsTest {
public DrawOverlaySettingsTest() {
super(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, AppOpsManager.OP_SYSTEM_ALERT_WINDOW);
}
// Test cases are in the superclass.
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications;
import android.app.AppOpsManager;
import android.provider.Settings;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ExternalSourcesSettingsTest extends AppOpsSettingsTest {
public ExternalSourcesSettingsTest() {
super(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
AppOpsManager.OP_REQUEST_INSTALL_PACKAGES);
}
// Test cases are in the superclass.
}

View File

@@ -1,93 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.biometrics.fingerprint;
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.intent.Intents.intended;
import static androidx.test.espresso.intent.Intents.intending;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.app.Activity;
import android.app.Instrumentation.ActivityResult;
import android.content.ComponentName;
import androidx.test.espresso.intent.rule.IntentsTestRule;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.R;
import com.google.android.setupcompat.PartnerCustomizationLayout;
import com.google.android.setupcompat.template.FooterBarMixin;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class FingerprintEnrollFinishTest {
@Rule
public IntentsTestRule<FingerprintEnrollFinish> mActivityRule =
new IntentsTestRule<>(FingerprintEnrollFinish.class);
@Test
public void clickAddAnother_shouldLaunchEnrolling() {
final ComponentName enrollingComponent = new ComponentName(
getTargetContext(),
FingerprintEnrollEnrolling.class);
intending(hasComponent(enrollingComponent))
.respondWith(new ActivityResult(Activity.RESULT_CANCELED, null));
PartnerCustomizationLayout layout =
mActivityRule.getActivity().findViewById(R.id.setup_wizard_layout);
layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick();
intended(hasComponent(enrollingComponent));
assertFalse(mActivityRule.getActivity().isFinishing());
}
@Test
public void clickAddAnother_shouldPropagateResults() {
final ComponentName enrollingComponent = new ComponentName(
getTargetContext(),
FingerprintEnrollEnrolling.class);
intending(hasComponent(enrollingComponent))
.respondWith(new ActivityResult(Activity.RESULT_OK, null));
PartnerCustomizationLayout layout =
mActivityRule.getActivity().findViewById(R.id.setup_wizard_layout);
layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick();
intended(hasComponent(enrollingComponent));
assertTrue(mActivityRule.getActivity().isFinishing());
}
@Test
public void clickNext_shouldFinish() {
onView(withId(R.id.next_button)).perform(click());
assertTrue(mActivityRule.getActivity().isFinishing());
}
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.biometrics.fingerprint;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.test.ActivityUnitTestCase;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.android.settings.R;
import com.google.android.setupcompat.PartnerCustomizationLayout;
import com.google.android.setupcompat.template.FooterBarMixin;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
public class FingerprintEnrollIntroductionTest
extends ActivityUnitTestCase<FingerprintEnrollIntroduction> {
private TestContext mContext;
@Mock
private FingerprintManager mFingerprintManager;
private FingerprintEnrollIntroduction mActivity;
public FingerprintEnrollIntroductionTest() {
super(FingerprintEnrollIntroduction.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
mContext = new TestContext(getInstrumentation().getTargetContext());
setActivityContext(mContext);
getInstrumentation().runOnMainSync(() -> {
final Intent intent = new Intent();
mActivity = startActivity(intent,
null /* savedInstanceState */, null /* lastNonConfigurationInstance */);
});
}
public void testMaxFingerprint_shouldShowErrorMessage() {
final int max = mContext.getResources().getInteger(
com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
doReturn(generateFingerprintList(max)).when(mFingerprintManager)
.getEnrolledFingerprints(anyInt());
getInstrumentation().runOnMainSync(() -> {
getInstrumentation().callActivityOnCreate(mActivity, null);
getInstrumentation().callActivityOnResume(mActivity);
});
final TextView errorTextView = (TextView) mActivity.findViewById(R.id.error_text);
assertNotNull(errorTextView.getText().toString());
PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout);
final Button nextButton = layout.getMixin(FooterBarMixin.class).getPrimaryButtonView();
assertEquals(View.GONE, nextButton.getVisibility());
}
private List<Fingerprint> generateFingerprintList(int num) {
ArrayList<Fingerprint> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add(new Fingerprint("Fingerprint " + i, 0, i, 0));
}
return list;
}
public class TestContext extends ContextWrapper {
public TestContext(Context base) {
super(base);
}
@Override
public Object getSystemService(String name) {
if (Context.FINGERPRINT_SERVICE.equals(name)) {
return mFingerprintManager;
}
return super.getSystemService(name);
}
}
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.core;
import static junit.framework.Assert.fail;
import android.content.Context;
import android.os.Looper;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexableData;
import com.android.settingslib.search.SearchIndexableResources;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import java.util.Set;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class PreferenceControllerContractTest {
private Context mContext;
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
}
@Test
@Presubmit
public void controllersInSearchShouldImplementPreferenceControllerMixin() {
Looper.prepare(); // Required by AutofillLoggingLevelPreferenceController
final Set<String> errorClasses = new ArraySet<>();
final SearchIndexableResources resources =
FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
.getSearchIndexableResources();
for (SearchIndexableData bundle : resources.getProviderValues()) {
final BaseSearchIndexProvider provider =
(BaseSearchIndexProvider) bundle.getSearchIndexProvider();
if (provider == null) {
continue;
}
final List<AbstractPreferenceController> controllers =
provider.getPreferenceControllers(mContext);
if (controllers == null) {
continue;
}
for (AbstractPreferenceController controller : controllers) {
if (!(controller instanceof PreferenceControllerMixin)
&& !(controller instanceof BasePreferenceController)) {
errorClasses.add(controller.getClass().getName());
}
}
}
if (!errorClasses.isEmpty()) {
final StringBuilder errorMessage = new StringBuilder()
.append("Each preference must implement PreferenceControllerMixin ")
.append("or extend BasePreferenceController, ")
.append("the following classes don't:\n");
for (String c : errorClasses) {
errorMessage.append(c).append("\n");
}
fail(errorMessage.toString());
}
}
}

View File

@@ -1,121 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.core;
import static android.content.pm.PackageManager.GET_ACTIVITIES;
import static android.content.pm.PackageManager.GET_META_DATA;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static com.android.settings.SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.fail;
import static org.junit.Assert.assertFalse;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
import android.text.TextUtils;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.core.gateway.SettingsGateway;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class SettingsGatewayTest {
private static final String TAG = "SettingsGatewayTest";
private Context mContext;
private PackageManager mPackageManager;
private String mPackageName;
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
mPackageManager = mContext.getPackageManager();
mPackageName = mContext.getPackageName();
}
@Test
@Presubmit
public void allRestrictedActivityMustBeDefinedInManifest() {
for (String className : SettingsGateway.SETTINGS_FOR_RESTRICTED) {
final Intent intent = new Intent();
intent.setComponent(new ComponentName(mPackageName, className));
List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent,
MATCH_DISABLED_COMPONENTS);
Log.d(TAG, mPackageName + "/" + className + "; resolveInfo size: "
+ resolveInfos.size());
assertFalse(className + " is not-defined in manifest", resolveInfos.isEmpty());
}
}
@Test
@Presubmit
public void publicFragmentMustAppearInSettingsGateway()
throws PackageManager.NameNotFoundException {
final List<String> allowlistedFragment = new ArrayList<>();
final StringBuilder error = new StringBuilder();
for (String fragment : SettingsGateway.ENTRY_FRAGMENTS) {
allowlistedFragment.add(fragment);
}
final PackageInfo pi = mPackageManager.getPackageInfo(mPackageName,
GET_META_DATA | MATCH_DISABLED_COMPONENTS | GET_ACTIVITIES);
final List<ActivityInfo> activities = Arrays.asList(pi.activities);
for (ActivityInfo activity : activities) {
final Bundle metaData = activity.metaData;
if (metaData == null || !metaData.containsKey(META_DATA_KEY_FRAGMENT_CLASS)) {
continue;
}
final String fragmentName = metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
assertThat(fragmentName).isNotNull();
if (!allowlistedFragment.contains(fragmentName)) {
error.append("SettingsGateway.ENTRY_FRAGMENTS must contain " + fragmentName
+ " because this fragment is used in manifest for " + activity.name)
.append("\n");
}
}
final String message = error.toString();
if (!TextUtils.isEmpty(message)) {
fail(message);
}
}
}

View File

@@ -1,219 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.core;
import static junit.framework.Assert.fail;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
import android.provider.SearchIndexableResource;
import android.text.TextUtils;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexableData;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.search.SearchIndexableResources;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class UniquePreferenceTest {
private static final String TAG = "UniquePreferenceTest";
private static final List<String> IGNORE_PREF_TYPES = Arrays.asList(
"com.android.settingslib.widget.FooterPreference");
private static final List<String> ALLOWLISTED_DUPLICATE_KEYS = Arrays.asList(
"owner_info_settings", // Lock screen message in security - multiple xml files
// contain this because security page is constructed by
// combining small xml chunks. Eventually the page
// should be formed as one single xml and this entry
// should be removed.
"dashboard_tile_placeholder", // This is the placeholder pref for injecting dynamic
// tiles.
// Dup keys from About Phone v2 experiment.
"ims_reg_state",
"bt_address",
"device_model",
"firmware_version",
"regulatory_info",
"manual",
"legal_container",
"device_feedback",
"fcc_equipment_id",
"sim_status",
"build_number",
"phone_number",
"imei_info",
"wifi_ip_address",
"wifi_mac_address",
"safety_info",
// Dupe keys from data usage v2.
"data_usage_screen",
"cellular_data_usage",
"data_usage_wifi_screen",
"status_header",
"billing_preference",
"data_usage_cellular_screen",
"wifi_data_usage",
"data_usage_enable"
);
private Context mContext;
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
}
/**
* All preferences should have their unique key. It's especially important for many parts of
* Settings to work properly: we assume pref keys are unique in displaying, search ranking,\
* search result suppression, and many other areas.
* <p/>
* So in this test we are checking preferences participating in search.
* <p/>
* Note: Preference is not limited to just <Preference/> object. Everything in preference xml
* should have a key.
*/
@Test
@Presubmit
public void allPreferencesShouldHaveUniqueKey()
throws IOException, XmlPullParserException, Resources.NotFoundException {
final Set<String> uniqueKeys = new HashSet<>();
final Set<String> nullKeyClasses = new HashSet<>();
final Set<String> duplicatedKeys = new HashSet<>();
final SearchIndexableResources resources =
FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
.getSearchIndexableResources();
for (SearchIndexableData SearchIndexableData : resources.getProviderValues()) {
verifyPreferenceKeys(uniqueKeys, duplicatedKeys, nullKeyClasses, SearchIndexableData);
}
if (!nullKeyClasses.isEmpty()) {
final StringBuilder nullKeyErrors = new StringBuilder()
.append("Each preference/SearchIndexableData must have a key, ")
.append("the following classes have null keys:\n");
for (String c : nullKeyClasses) {
nullKeyErrors.append(c).append("\n");
}
fail(nullKeyErrors.toString());
}
if (!duplicatedKeys.isEmpty()) {
final StringBuilder dupeKeysError = new StringBuilder(
"The following keys are not unique\n");
for (String c : duplicatedKeys) {
dupeKeysError.append(c).append("\n");
}
fail(dupeKeysError.toString());
}
}
private void verifyPreferenceKeys(Set<String> uniqueKeys, Set<String> duplicatedKeys,
Set<String> nullKeyClasses, SearchIndexableData searchIndexableData)
throws IOException, XmlPullParserException, Resources.NotFoundException {
final String className = searchIndexableData.getTargetClass().getName();
final Indexable.SearchIndexProvider provider =
searchIndexableData.getSearchIndexProvider();
final List<SearchIndexableRaw> rawsToIndex = provider.getRawDataToIndex(mContext, true);
final List<SearchIndexableResource> resourcesToIndex =
provider.getXmlResourcesToIndex(mContext, true);
verifyResources(className, resourcesToIndex, uniqueKeys, duplicatedKeys, nullKeyClasses);
verifyRaws(className, rawsToIndex, uniqueKeys, duplicatedKeys, nullKeyClasses);
}
private void verifyResources(String className, List<SearchIndexableResource> resourcesToIndex,
Set<String> uniqueKeys, Set<String> duplicatedKeys, Set<String> nullKeyClasses)
throws IOException, XmlPullParserException, Resources.NotFoundException {
if (resourcesToIndex == null) {
Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
return;
}
for (SearchIndexableResource sir : resourcesToIndex) {
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
sir.xmlResId,
MetadataFlag.FLAG_INCLUDE_PREF_SCREEN
| MetadataFlag.FLAG_NEED_KEY
| MetadataFlag.FLAG_NEED_PREF_TYPE);
for (Bundle bundle : metadata) {
final String type = bundle.getString(PreferenceXmlParserUtils.METADATA_PREF_TYPE);
if (IGNORE_PREF_TYPES.contains(type)) {
continue;
}
final String key = bundle.getString(PreferenceXmlParserUtils.METADATA_KEY);
if (TextUtils.isEmpty(key)) {
Log.e(TAG, "Every preference must have an key; found null key"
+ " in " + className);
nullKeyClasses.add(className);
continue;
}
if (uniqueKeys.contains(key) && !ALLOWLISTED_DUPLICATE_KEYS.contains(key)) {
Log.e(TAG, "Every preference key must unique; found "
+ " in " + className
+ " / " + key);
duplicatedKeys.add(key);
}
uniqueKeys.add(key);
}
}
}
private void verifyRaws(String className, List<SearchIndexableRaw> rawsToIndex,
Set<String> uniqueKeys, Set<String> duplicatedKeys, Set<String> nullKeyClasses) {
if (rawsToIndex == null) {
Log.d(TAG, className + "is not providing SearchIndexableRaw, skipping");
return;
}
for (SearchIndexableRaw raw : rawsToIndex) {
if (TextUtils.isEmpty(raw.key)) {
Log.e(TAG, "Every SearchIndexableRaw must have an key; found null key"
+ " in " + className);
nullKeyClasses.add(className);
continue;
}
if (uniqueKeys.contains(raw.key) && !ALLOWLISTED_DUPLICATE_KEYS.contains(raw.key)) {
Log.e(TAG, "Every SearchIndexableRaw key must unique; found " + raw.key
+ " in " + className);
duplicatedKeys.add(raw.key);
}
}
}
}

View File

@@ -1,157 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.core;
import static junit.framework.Assert.fail;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.UserManager;
import android.provider.SearchIndexableResource;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexableData;
import com.android.settingslib.search.SearchIndexableResources;
import com.google.android.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.List;
import java.util.Set;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class UserRestrictionTest {
private static final String TAG = "UserRestrictionTest";
private Context mContext;
private static final Set<String> USER_RESTRICTIONS = Sets.newHashSet(
UserManager.DISALLOW_CONFIG_DATE_TIME,
UserManager.DISALLOW_CONFIG_CREDENTIALS,
UserManager.DISALLOW_NETWORK_RESET,
UserManager.DISALLOW_FACTORY_RESET,
UserManager.DISALLOW_CONFIG_TETHERING,
UserManager.DISALLOW_CONFIG_VPN,
UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
UserManager.DISALLOW_AIRPLANE_MODE,
UserManager.DISALLOW_CONFIG_BRIGHTNESS,
UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT
);
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
}
/**
* Verity that userRestriction attributes are entered and parsed successfully.
*/
@Test
public void userRestrictionAttributeShouldBeValid()
throws IOException, XmlPullParserException, Resources.NotFoundException {
final SearchIndexableResources resources =
FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
.getSearchIndexableResources();
for (SearchIndexableData bundle : resources.getProviderValues()) {
verifyUserRestriction(bundle);
}
}
private void verifyUserRestriction(SearchIndexableData searchIndexableData)
throws IOException, XmlPullParserException, Resources.NotFoundException {
final Indexable.SearchIndexProvider provider =
searchIndexableData.getSearchIndexProvider();
final List<SearchIndexableResource> resourcesToIndex =
provider.getXmlResourcesToIndex(mContext, true);
final String className = searchIndexableData.getTargetClass().getName();
if (resourcesToIndex == null) {
Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
return;
}
for (SearchIndexableResource sir : resourcesToIndex) {
if (sir.xmlResId <= 0) {
Log.d(TAG, className + " doesn't have a valid xml to index.");
continue;
}
final XmlResourceParser parser = mContext.getResources().getXml(sir.xmlResId);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
// Parse next until start tag is found
}
final int outerDepth = parser.getDepth();
do {
if (type != XmlPullParser.START_TAG) {
continue;
}
final String nodeName = parser.getName();
if (!nodeName.endsWith("Preference")) {
continue;
}
final AttributeSet attrs = Xml.asAttributeSet(parser);
final String userRestriction = getDataUserRestrictions(mContext, attrs);
if (userRestriction != null) {
if(!isValidRestriction(userRestriction)) {
fail("userRestriction in " + className + " not valid.");
}
}
} while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth));
}
}
boolean isValidRestriction(String userRestriction) {
return USER_RESTRICTIONS.contains(userRestriction);
}
private String getDataUserRestrictions(Context context, AttributeSet attrs) {
return getData(context, attrs,
com.android.settingslib.R.styleable.RestrictedPreference,
com.android.settingslib.R.styleable.RestrictedPreference_userRestriction);
}
private String getData(Context context, AttributeSet set, int[] attrs, int resId) {
final TypedArray ta = context.obtainStyledAttributes(set, attrs);
String data = ta.getString(resId);
ta.recycle();
return data;
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.development;
import android.content.Context;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.R;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class BluetoothMaxConnectedAudioDevicesPreferenceControllerInstrumentationTest {
private Context mTargetContext;
private String[] mListValues;
private String[] mListEntries;
private String mDefaultMaxConnectedAudioDevices;
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
// Get XML values without mock
mListValues = mTargetContext.getResources()
.getStringArray(R.array.bluetooth_max_connected_audio_devices_values);
mListEntries = mTargetContext.getResources()
.getStringArray(R.array.bluetooth_max_connected_audio_devices);
mDefaultMaxConnectedAudioDevices = String.valueOf(mTargetContext.getResources()
.getInteger(
com.android.internal.R.integer
.config_bluetooth_max_connected_audio_devices));
}
@Test
public void verifyResource() {
// Verify normal list entries and default preference entries have the same size
Assert.assertEquals(mListEntries.length, mListValues.length);
Assert.assertThat(Arrays.asList(mListValues),
CoreMatchers.hasItem(mDefaultMaxConnectedAudioDevices));
}
}

View File

@@ -1,126 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge.batterytip;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.test.uiautomator.UiDevice;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class RestrictAppTest {
private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
private static final String BATTERY_INTENT = "android.intent.action.POWER_USAGE_SUMMARY";
private static final String PACKAGE_SETTINGS = "com.android.settings";
private static final String PACKAGE_SYSTEM_UI = "com.android.systemui";
private static final int ANOMALY_TYPE =
StatsManagerConfig.AnomalyType.EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF;
private BatteryDatabaseManager mBatteryDatabaseManager;
private PackageManager mPackageManager;
private UiDevice mUiDevice;
@Before
public void setUp() throws Exception {
final Context context = InstrumentationRegistry.getTargetContext();
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mUiDevice.wakeUp();
mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
mPackageManager = context.getPackageManager();
mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context);
mBatteryDatabaseManager.deleteAllAnomaliesBeforeTimeStamp(System.currentTimeMillis() +
TimeUnit.DAYS.toMillis(1));
}
@Test
public void batterySettings_hasOneAnomaly_showAnomaly() throws
PackageManager.NameNotFoundException {
mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0),
PACKAGE_SETTINGS, ANOMALY_TYPE,
AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis());
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
instrumentation.startActivitySync(createBatteryIntent());
onView(withText("Restrict 1 app")).check(matches(isDisplayed()));
}
@Test
public void batterySettings_hasTwoAnomalies_showAnomalies() throws
PackageManager.NameNotFoundException {
mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0),
PACKAGE_SETTINGS, ANOMALY_TYPE,
AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis());
mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SYSTEM_UI, 0),
PACKAGE_SYSTEM_UI, ANOMALY_TYPE,
AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis());
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
instrumentation.startActivitySync(createBatteryIntent());
onView(withText("Restrict 2 apps")).check(matches(isDisplayed()));
}
@Test
public void insertDuplicateAnomalies_onlyInsertOnce() throws
PackageManager.NameNotFoundException {
final int uid = mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0);
final long now = System.currentTimeMillis();
// Insert same anomaly twice, it fails at the second time.
assertThat(mBatteryDatabaseManager.insertAnomaly(uid, PACKAGE_SETTINGS, ANOMALY_TYPE,
AnomalyDatabaseHelper.State.NEW, now)).isTrue();
assertThat(mBatteryDatabaseManager.insertAnomaly(uid, PACKAGE_SETTINGS, ANOMALY_TYPE,
AnomalyDatabaseHelper.State.NEW, now)).isFalse();
// In database, only contains one row
List<AppInfo> newAppInfos = mBatteryDatabaseManager.queryAllAnomalies(0,
AnomalyDatabaseHelper.State.NEW);
assertThat(newAppInfos).containsExactly(new AppInfo.Builder()
.setUid(uid)
.setPackageName(PACKAGE_SETTINGS)
.addAnomalyType(ANOMALY_TYPE)
.build());
}
private Intent createBatteryIntent() {
final Intent intent = new Intent(BATTERY_INTENT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.network;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.net.Uri;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class MobileDataEnabledListenerTest {
private static final int SUB_ID_ONE = 111;
private static final int SUB_ID_TWO = 222;
@Mock
private MobileDataEnabledListener.Client mClient;
private Context mContext;
private MobileDataEnabledListener mListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = ApplicationProvider.getApplicationContext();
mListener = new MobileDataEnabledListener(mContext, mClient);
}
@Test
public void onMobileDataEnabledChange_firesCorrectly() {
mListener.start(SUB_ID_ONE);
final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_ONE);
mContext.getContentResolver().notifyChange(uri, null);
verify(mClient).onMobileDataEnabledChange();
}
@Test
public void onMobileDataEnabledChange_doesNotFireAfterStop() {
mListener.start(SUB_ID_ONE);
mListener.stop();
final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_ONE);
mContext.getContentResolver().notifyChange(uri, null);
verify(mClient, never()).onMobileDataEnabledChange();
}
@Test
public void onMobileDataEnabledChange_changedToDifferentId_firesCorrectly() {
mListener.start(SUB_ID_ONE);
mListener.stop();
mListener.start(SUB_ID_TWO);
final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_TWO);
mContext.getContentResolver().notifyChange(uri, null);
verify(mClient).onMobileDataEnabledChange();
}
}

View File

@@ -1,126 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.network;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringManager.TETHERING_WIFI;
import static com.android.settings.network.TetherProvisioningActivity.EXTRA_TETHER_SUBID;
import static com.android.settings.network.TetherProvisioningActivity.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
import static com.android.settings.network.TetherProvisioningActivity.PROVISION_REQUEST;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.app.Activity;
import android.content.Intent;
import android.net.TetheringManager;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import androidx.lifecycle.Lifecycle;
import androidx.test.core.app.ActivityScenario;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
public class TetherProvisioningActivityTest {
private static class WrappedReceiver extends ResultReceiver {
private final CompletableFuture<Integer> mFuture = new CompletableFuture<>();
WrappedReceiver() {
super(null /* handler */);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
mFuture.complete(resultCode);
}
public int get() throws Exception {
return mFuture.get(10_000L, TimeUnit.MILLISECONDS);
}
}
@Test
public void testOnCreate_FinishWithNonActiveDataSubId() throws Exception {
final WrappedReceiver receiver = new WrappedReceiver();
try (ActivityScenario<TetherProvisioningActivity> scenario = ActivityScenario.launch(
new Intent(Settings.ACTION_TETHER_PROVISIONING_UI)
.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI)
.putExtra(EXTRA_PROVISION_CALLBACK, receiver)
.putExtra(TetherProvisioningActivity.EXTRA_TETHER_SUBID, 10000))) {
assertEquals(TetheringManager.TETHER_ERROR_PROVISIONING_FAILED, receiver.get());
assertEquals(Lifecycle.State.DESTROYED, scenario.getState());
}
}
@Test
public void testOnCreate_FinishWithUnavailableProvisioningApp() throws Exception {
final WrappedReceiver receiver = new WrappedReceiver();
final int subId = SubscriptionManager.getActiveDataSubscriptionId();
final String[] emptyProvisioningApp = { "", "" };
try (ActivityScenario<TetherProvisioningActivity> scenario = ActivityScenario.launch(
new Intent(Settings.ACTION_TETHER_PROVISIONING_UI)
.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI)
.putExtra(EXTRA_PROVISION_CALLBACK, receiver)
.putExtra(EXTRA_TETHER_SUBID, subId)
.putExtra(EXTRA_TETHER_UI_PROVISIONING_APP_NAME, emptyProvisioningApp))) {
assertEquals(TetheringManager.TETHER_ERROR_PROVISIONING_FAILED, receiver.get());
assertEquals(Lifecycle.State.DESTROYED, scenario.getState());
}
}
@Test
public void testOnCreate_startActivityForResult() {
final WrappedReceiver receiver = new WrappedReceiver();
final int subId = SubscriptionManager.getActiveDataSubscriptionId();
final String[] provisionApp = new String[] {
"android.test.entitlement",
"android.test.entitlement.InstrumentedEntitlementActivity"
};
try (ActivityScenario<TetherProvisioningActivity> scenario = ActivityScenario.launch(
new Intent(Settings.ACTION_TETHER_PROVISIONING_UI)
.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI)
.putExtra(EXTRA_PROVISION_CALLBACK, receiver)
.putExtra(EXTRA_TETHER_SUBID, subId)
.putExtra(EXTRA_TETHER_UI_PROVISIONING_APP_NAME, provisionApp))) {
scenario.onActivity(activity -> {
assertFalse(activity.isFinishing());
activity.onActivityResult(PROVISION_REQUEST, Activity.RESULT_OK, null /* intent */);
try {
assertEquals(TetheringManager.TETHER_ERROR_NO_ERROR, receiver.get());
} catch (Exception e) {
// ActivityAction#perform() doesn't throw the exception. Just catch the
// exception and call fail() here.
fail("Can not get result after 10s.");
}
assertTrue(activity.isFinishing());
});
}
}
}

View File

@@ -1,122 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.network.telephony;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.SharedPreferences;
import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Arrays;
@RunWith(AndroidJUnit4.class)
public class NetworkSelectSettingsTest {
private static final int SUB_ID = 2;
private static final String CARRIER_NAME1 = "CarrierName1";
private static final String CARRIER_NAME2 = "CarrierName2";
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionManager mSubscriptionManager;
@Mock
private PreferenceManager mPreferenceManager;
@Mock
private SharedPreferences mSharedPreferences;
private CellInfoWcdma mCellInfo1 = new CellInfoWcdma();
private CellIdentityWcdma mCellId1 = new CellIdentityWcdma();
private CellInfoLte mCellInfo2 = new CellInfoLte();
private CellIdentityLte mCellId2 = new CellIdentityLte();
private Context mContext;
private PreferenceCategory mPreferenceCategory;
private NetworkSelectSettings mNetworkSelectSettings;
@Before
@UiThreadTest
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
mCellInfo1.setRegistered(true);
mCellInfo1.setCellIdentity(mCellId1);
mCellId1.setOperatorAlphaLong(CARRIER_NAME1);
mCellInfo2.setRegistered(false);
mCellInfo2.setCellIdentity(mCellId2);
mCellId2.setOperatorAlphaLong(CARRIER_NAME2);
doReturn(mSharedPreferences).when(mPreferenceManager).getSharedPreferences();
mPreferenceCategory = spy(new PreferenceCategory(mContext));
doReturn(mPreferenceManager).when(mPreferenceCategory).getPreferenceManager();
mNetworkSelectSettings = spy(new NetworkSelectSettings());
doReturn(mContext).when(mNetworkSelectSettings).getContext();
doReturn(mPreferenceManager).when(mNetworkSelectSettings).getPreferenceManager();
doReturn(mContext).when(mPreferenceManager).getContext();
mNetworkSelectSettings.mTelephonyManager = mTelephonyManager;
mNetworkSelectSettings.mPreferenceCategory = mPreferenceCategory;
mNetworkSelectSettings.mCellInfoList = Arrays.asList(mCellInfo1, mCellInfo2);
}
@Test
public void updateAllPreferenceCategory_correctOrderingPreference() {
mNetworkSelectSettings.updateAllPreferenceCategory();
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
final NetworkOperatorPreference preference =
(NetworkOperatorPreference) mPreferenceCategory.getPreference(1);
assertThat(preference.getOperatorName()).isEqualTo(mCellId2.getOperatorAlphaLong());
}
@Test
public void updateForbiddenPlmns_forbiddenPlmnsNull_shouldNotCrash() {
when(mTelephonyManager.getForbiddenPlmns()).thenReturn(null);
// Should not Crash
mNetworkSelectSettings.updateForbiddenPlmns();
}
}

View File

@@ -1,154 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.notification;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.intent.Intents.intended;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT;
import static org.hamcrest.Matchers.allOf;
import static org.junit.Assert.fail;
import android.app.Instrumentation;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import androidx.test.InstrumentationRegistry;
import androidx.test.espresso.intent.Intents;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class AppNotificationSettingsTest {
private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
private UiDevice mUiDevice;
private Context mTargetContext;
private Instrumentation mInstrumentation;
NotificationManager mNm;
private NotificationChannelGroup mGroup1;
private NotificationChannel mGroup1Channel1;
private NotificationChannel mGroup1Channel2;
private NotificationChannelGroup mGroup2;
private NotificationChannel mGroup2Channel1;
private NotificationChannel mUngroupedChannel;
@Before
public void setUp() throws Exception {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mTargetContext = mInstrumentation.getTargetContext();
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mUiDevice.wakeUp();
mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
mNm = (NotificationManager) mTargetContext.getSystemService(Context.NOTIFICATION_SERVICE);
mGroup1 = new NotificationChannelGroup(this.getClass().getName() + "1", "group1");
mGroup2 = new NotificationChannelGroup(this.getClass().getName() + "2", "group2");
mNm.createNotificationChannelGroup(mGroup1);
mNm.createNotificationChannelGroup(mGroup2);
mGroup1Channel1 = createChannel(mGroup1, this.getClass().getName()+ "c1-1");
mGroup1Channel2 = createChannel(mGroup1, this.getClass().getName()+ "c1-2");
mGroup2Channel1 = createChannel(mGroup2, this.getClass().getName()+ "c2-1");
mUngroupedChannel = createChannel(null, this.getClass().getName()+ "c");
}
@Test
public void launchNotificationSetting_shouldNotHaveAppInfoLink() {
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mInstrumentation.startActivitySync(intent);
onView(allOf(withId(android.R.id.button1),
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(doesNotExist());
}
@Test
public void launchNotificationSetting_showGroupsWithMultipleChannels() {
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mInstrumentation.startActivitySync(intent);
onView(allOf(withText(mGroup1.getName().toString()))).check(
matches(isDisplayed()));
onView(allOf(withText(mGroup1Channel1.getName().toString()))).check(
matches(isDisplayed()));
onView(allOf(withText(mGroup1Channel2.getName().toString()))).check(
matches(isDisplayed()));
}
@Test
public void launchNotificationSetting_showUngroupedChannels() {
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mInstrumentation.startActivitySync(intent);
onView(allOf(withText(mUngroupedChannel.getName().toString())))
.check(matches(isDisplayed()));
}
@Test
public void launchNotificationSetting_showGroupsWithOneChannel() {
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mInstrumentation.startActivitySync(intent);
onView(allOf(withText(mGroup2.getName().toString())))
.check(matches(isDisplayed()));
onView(allOf(withText(mGroup2Channel1.getName().toString())))
.check(matches(isDisplayed()));
}
private NotificationChannel createChannel(NotificationChannelGroup group,
String id) {
NotificationChannel channel = new NotificationChannel(id, id, IMPORTANCE_DEFAULT);
if (group != null) {
channel.setGroup(group.getId());
}
mNm.createNotificationChannel(channel);
return channel;
}
}

View File

@@ -1,85 +0,0 @@
package com.android.settings;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ZenModeSettingsIntegrationTest {
private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
private Context mContext;
private UiDevice mUiDevice;
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mUiDevice.wakeUp();
mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
}
@Test
public void testZenModeSettingsPreferences() {
launchZenSettings();
onView(withText("Calls")).check(matches(isDisplayed()));
onView(withText("SMS, MMS, and messaging apps")).check(matches(isDisplayed()));
onView(withText("Restrict notifications")).check(matches(isDisplayed()));
onView(withText("Duration")).check(matches(isDisplayed()));
onView(withText("Schedules")).check(matches(isDisplayed()));
}
@Test
public void testZenModeBehaviorPreferences() {
launchZenBehaviorSettings();
onView(withText("Calls")).check(matches(isDisplayed()));
onView(withText("SMS, MMS, and messaging apps")).check(matches(isDisplayed()));
onView(withText("Restrict notifications")).check(matches(isDisplayed()));
onView(withText("Duration")).check(matches(isDisplayed()));
onView(withText("Schedules")).check(matches(isDisplayed()));
}
@Test
public void testZenModeAutomationPreferences() {
launchZenAutomationSettings();
onView(withText("Sleeping")).check(matches(isDisplayed()));
onView(withText("Event")).check(matches(isDisplayed()));
onView(withText("Add more")).check(matches(isDisplayed()));
}
private void launchZenSettings() {
Intent settingsIntent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS)
.setPackage(mContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(settingsIntent);
}
private void launchZenAutomationSettings() {
Intent settingsIntent = new Intent(Settings.ACTION_ZEN_MODE_AUTOMATION_SETTINGS)
.setPackage(mContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(settingsIntent);
}
private void launchZenBehaviorSettings() {
Intent settingsIntent = new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS)
.setPackage(mContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(settingsIntent);
}
}

View File

@@ -1,240 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.password;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertTrue;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.AppTask;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiSelector;
import android.text.format.DateUtils;
import android.view.WindowManager;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import androidx.test.runner.lifecycle.Stage;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Collection;
import java.util.List;
/**
* Tests for {@link ChooseLockGenericTest}
*
* m SettingsTests &&
* adb install \
* -r -g ${ANDROID_PRODUCT_OUT}/data/app/SettingsTests/SettingsTests.apk &&
* adb shell am instrument -e class com.android.settings.password.ChooseLockGenericTest \
* -w com.android.settings.tests/androidx.test.runner.AndroidJUnitRunner
*/
@RunWith(AndroidJUnit4.class)
@MediumTest
public class ChooseLockGenericTest {
private static final long TIMEOUT = 5 * DateUtils.SECOND_IN_MILLIS;
private static final Intent PHISHING_ATTACK_INTENT = new Intent()
.putExtra("confirm_credentials", false)
.putExtra("password_confirmed", true);
private UiDevice mDevice;
private Context mTargetContext;
private String mSettingPackage;
@Rule
public ActivityTestRule<ChooseLockGeneric> mChooseLockGenericActivityRule =
new ActivityTestRule<>(
ChooseLockGeneric.class,
true /* enable touch at launch */,
false /* don't launch at every test */);
@Before
public void setUp() throws Exception {
mDevice = UiDevice.getInstance(getInstrumentation());
mTargetContext = getInstrumentation().getTargetContext();
mSettingPackage = mTargetContext.getPackageName();
}
@Test
public void testConfirmLockPasswordShown_deviceWithPassword() throws Throwable {
setPassword();
try {
// GIVEN a PIN password is set on this device at set up.
// WHEN ChooseLockGeneric is launched with no extras.
mChooseLockGenericActivityRule.launchActivity(null /* No extras */);
// THEN ConfirmLockPassword.InternalActivity is shown.
final Activity activity = getCurrentActivity();
assertThat(isSecureWindow(activity)).isTrue();
assertThat(activity)
.isInstanceOf(ConfirmLockPassword.InternalActivity.class);
} finally {
finishAllAppTasks();
mDevice.waitForIdle();
clearPassword();
}
}
@Test
public void testConfirmLockPasswordShown_deviceWithPassword_phishingAttack() throws Throwable {
setPassword();
try {
// GIVEN a PIN password is set on this device at set up.
// WHEN ChooseLockGeneric is launched with extras to by-pass lock password confirmation.
mChooseLockGenericActivityRule.launchActivity(PHISHING_ATTACK_INTENT);
// THEN ConfirmLockPassword.InternalActivity is still shown.
final Activity activity = getCurrentActivity();
assertThat(isSecureWindow(activity)).isTrue();
assertThat(activity)
.isInstanceOf(ConfirmLockPassword.InternalActivity.class);
} finally {
finishAllAppTasks();
mDevice.waitForIdle();
clearPassword();
}
}
@Test
public void testForFingerprint_inflateLayout() {
mChooseLockGenericActivityRule.launchActivity(new Intent()
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true));
assertThat(mChooseLockGenericActivityRule.getActivity().isResumed()).isTrue();
}
private Activity getCurrentActivity() throws Throwable {
getInstrumentation().waitForIdleSync();
final Activity[] activity = new Activity[1];
getInstrumentation().runOnMainSync(() -> {
Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance()
.getActivitiesInStage(Stage.RESUMED);
activity[0] = activities.iterator().next();
});
return activity[0];
}
/** Sets a PIN password, 12345, for testing. */
private void setPassword() throws Exception {
Intent newPasswordIntent = new Intent(getTargetContext(), ChooseLockGeneric.class)
.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
LockscreenCredential.createPin("12345"))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getInstrumentation().getContext().startActivity(newPasswordIntent);
mDevice.waitForIdle();
// Ignore any interstitial options
UiObject view = new UiObject(new UiSelector()
.resourceId(mSettingPackage + ":id/encrypt_dont_require_password"));
if (view.waitForExists(TIMEOUT)) {
view.click();
mDevice.waitForIdle();
}
// Set our PIN
view = new UiObject(new UiSelector()
.resourceId(mSettingPackage + ":id/password_entry"));
assertTrue("password_entry", view.waitForExists(TIMEOUT));
// Enter it twice to confirm
enterTestPin(view);
enterTestPin(view);
// Dismiss notifications setting
view = new UiObject(new UiSelector()
.resourceId(mSettingPackage + ":id/redaction_done_button"));
if (view.waitForExists(TIMEOUT)) {
view.click();
mDevice.waitForIdle();
}
mDevice.pressBack();
assertThat(getTargetContext().getSystemService(KeyguardManager.class).isDeviceSecure())
.isTrue();
}
/** Clears the previous set PIN password. */
private void clearPassword() throws Exception {
Intent newPasswordIntent = new Intent(getTargetContext(), ChooseLockGeneric.class)
.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
getInstrumentation().getContext().startActivity(newPasswordIntent);
mDevice.waitForIdle();
// Enter current PIN
UiObject view = new UiObject(
new UiSelector().resourceId(mSettingPackage + ":id/password_entry"));
if (!view.waitForExists(TIMEOUT)) {
// Odd, maybe there is a crash dialog showing; try dismissing it
mDevice.pressBack();
mDevice.waitForIdle();
assertTrue("password_entry", view.waitForExists(TIMEOUT));
}
enterTestPin(view);
mDevice.pressBack();
assertThat(getTargetContext().getSystemService(KeyguardManager.class).isDeviceSecure())
.isFalse();
}
private void finishAllAppTasks() {
final ActivityManager activityManager =
getTargetContext().getSystemService(ActivityManager.class);
final List<AppTask> appTasks = activityManager.getAppTasks();
for (ActivityManager.AppTask task : appTasks) {
task.finishAndRemoveTask();
}
}
private void enterTestPin(UiObject view) throws Exception {
mDevice.waitForIdle();
view.setText("12345");
mDevice.pressEnter();
mDevice.waitForIdle();
}
private boolean isSecureWindow(Activity activity) {
return (activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_SECURE)
!= 0;
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (C) 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.password;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.pressKey;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static com.google.common.truth.Truth.assertThat;
import static org.hamcrest.CoreMatchers.not;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.view.KeyEvent;
import android.view.View;
import androidx.test.InstrumentationRegistry;
import androidx.test.espresso.action.ViewActions;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.R;
import com.google.android.setupcompat.PartnerCustomizationLayout;
import com.google.android.setupcompat.template.FooterBarMixin;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ChooseLockPasswordTest {
private Instrumentation mInstrumentation;
private Context mContext;
@Before
public void setUp() {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mContext = mInstrumentation.getTargetContext();
}
@Test
public void clearIsNotShown_when_activityLaunchedInitially() {
final Activity activity =
mInstrumentation.startActivitySync(new Intent(mContext, ChooseLockPassword.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout);
assertThat(
layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void clearIsNotShown_when_nothingEntered() {
final Activity activity =
mInstrumentation.startActivitySync(new Intent(mContext, ChooseLockPassword.class));
final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout);
onView(withId(R.id.password_entry)).perform(ViewActions.typeText("1234"))
.perform(pressKey(KeyEvent.KEYCODE_ENTER));
assertThat(
layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void clearIsShown_when_somethingEnteredToConfirm() {
final Activity activity =
mInstrumentation.startActivitySync(new Intent(mContext, ChooseLockPassword.class));
final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout);
onView(withId(R.id.password_entry)).perform(ViewActions.typeText("1234"))
.perform(pressKey(KeyEvent.KEYCODE_ENTER))
.perform(ViewActions.typeText("1"));
// clear should be present if text field contains content
assertThat(layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().getText())
.isEqualTo(mContext.getString(R.string.lockpassword_clear_label));
assertThat(
layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().getVisibility())
.isEqualTo(View.VISIBLE);
}
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.password;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.pressKey;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.view.KeyEvent;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ConfirmLockPasswordTest {
private Instrumentation mInstrumentation;
private Context mContext;
@Before
public void setUp() {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mContext = mInstrumentation.getTargetContext();
}
@Test
public void enterWrongPin_shouldShowErrorMessage() {
mInstrumentation.startActivitySync(
new Intent(mContext, ConfirmLockPassword.class));
onView(withId(R.id.password_entry)).perform(typeText("1234"))
.perform(pressKey(KeyEvent.KEYCODE_ENTER));
onView(withId(R.id.errorText)).check(matches(withText(R.string.lockpassword_invalid_pin)));
}
@Test
public void enterWrongPin_darkTheme_shouldShowErrorMessage() {
mInstrumentation.startActivitySync(
new Intent(mContext, ConfirmLockPassword.class)
.putExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, true));
onView(withId(R.id.password_entry)).perform(typeText("1234"))
.perform(pressKey(KeyEvent.KEYCODE_ENTER));
onView(withId(R.id.errorText)).check(matches(withText(R.string.lockpassword_invalid_pin)));
}
}

View File

@@ -1,98 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.password;
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiSelector;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import androidx.test.runner.lifecycle.Stage;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Collection;
/**
* Tests for {@link SetupChooseLockGenericTest}
*
*/
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SetupChooseLockGenericTest {
private UiDevice mDevice;
private Context mContext;
@Before
public void setUp() throws Exception {
mDevice = UiDevice.getInstance(getInstrumentation());
mContext = getInstrumentation().getTargetContext();
Settings.Global.putInt(
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
}
@After
public void tearDown() {
Settings.Global.putInt(
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
}
@Test
public void clickSkipFigerprintPreference_deviceNotProvisioned_shouldBeAbleToProceed()
throws Throwable {
final Intent newPasswordIntent =
new Intent(getTargetContext(), SetupChooseLockGeneric.class)
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true)
.setAction(ACTION_SET_NEW_PASSWORD)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
getInstrumentation().getContext().startActivity(newPasswordIntent);
mDevice.waitForIdle();
mDevice.findObject(new UiSelector().textContains("Continue without ")).click();
final Activity activity = getCurrentActivity();
assertThat(activity).isInstanceOf(SetupChooseLockGeneric.InternalActivity.class);
}
private Activity getCurrentActivity() throws Throwable {
getInstrumentation().waitForIdleSync();
final Activity[] activity = new Activity[1];
getInstrumentation().runOnMainSync(() -> {
Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance()
.getActivitiesInStage(Stage.RESUMED);
activity[0] = activities.iterator().next();
});
return activity[0];
}
}

View File

@@ -1,122 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.slices;
import static junit.framework.Assert.fail;
import android.content.Context;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
import android.provider.SearchIndexableResource;
import android.text.TextUtils;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.core.PreferenceXmlParserUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexableData;
import com.android.settingslib.search.SearchIndexableResources;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class SliceDataContractTest {
private static final String TAG = "SliceDataContractTest";
private Context mContext;
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
}
@Test
@Presubmit
public void preferenceWithControllerMustHaveNonEmptyTitle()
throws IOException, XmlPullParserException {
final Set<String> nullTitleFragments = new HashSet<>();
final SearchIndexableResources resources =
FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
.getSearchIndexableResources();
for (SearchIndexableData SearchIndexableData : resources.getProviderValues()) {
verifyPreferenceTitle(nullTitleFragments, SearchIndexableData);
}
if (!nullTitleFragments.isEmpty()) {
final StringBuilder error = new StringBuilder(
"All preferences with a controller must have a non-empty title by default, "
+ "found empty title in the following fragments\n");
for (String c : nullTitleFragments) {
error.append(c).append("\n");
}
fail(error.toString());
}
}
private void verifyPreferenceTitle(Set<String> nullTitleFragments,
SearchIndexableData searchIndexableData)
throws IOException, XmlPullParserException {
final String className = searchIndexableData.getTargetClass().getName();
final Indexable.SearchIndexProvider provider =
searchIndexableData.getSearchIndexProvider();
final List<SearchIndexableResource> resourcesToIndex =
provider.getXmlResourcesToIndex(mContext, true);
if (resourcesToIndex == null) {
Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
return;
}
for (SearchIndexableResource sir : resourcesToIndex) {
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
sir.xmlResId,
PreferenceXmlParserUtils.MetadataFlag.FLAG_INCLUDE_PREF_SCREEN
| PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_PREF_TITLE
| PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_PREF_CONTROLLER);
for (Bundle bundle : metadata) {
final String controller = bundle.getString(
PreferenceXmlParserUtils.METADATA_CONTROLLER);
if (TextUtils.isEmpty(controller)) {
continue;
}
final String title = bundle.getString(PreferenceXmlParserUtils.METADATA_TITLE);
if (TextUtils.isEmpty(title)) {
nullTitleFragments.add(className);
}
}
}
}
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import android.content.Context;
import android.content.Intent;
import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.Settings;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SavedNetworkSettingsTest {
// Keys used to lookup resources by name (see the resourceId helper method).
private static final String STRING = "string";
private static final String WIFI_ADD_NETWORK = "wifi_add_network";
private static final String WIFI_NETWORK_LABEL = "wifi_ssid";
private Context mContext;
@Rule
public ActivityTestRule<Settings.SavedAccessPointsSettingsActivity> mActivityRule =
new ActivityTestRule<>(Settings.SavedAccessPointsSettingsActivity.class, true);
private int resourceId(String type, String name) {
return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
}
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
}
private void launchSavedNetworksSettings() {
Intent intent = new Intent()
.setClassName(mContext.getPackageName(),
Settings.SavedAccessPointsSettingsActivity.class.getName())
.setPackage(mContext.getPackageName());
mActivityRule.launchActivity(intent);
}
@Test
public void launchSavedNetworkSettings_shouldHaveAddNetworkField() {
launchSavedNetworksSettings();
onView(withText(resourceId(STRING, WIFI_ADD_NETWORK))).check(matches(isDisplayed()))
.perform(click());
onView(withText(resourceId(STRING, WIFI_NETWORK_LABEL))).check(matches(isDisplayed()));
}
}

View File

@@ -1,306 +0,0 @@
/**
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isSelected;
import static androidx.test.espresso.matcher.ViewMatchers.withResourceName;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anything;
import static org.junit.Assert.assertEquals;
import static org.junit.matchers.JUnitMatchers.containsString;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.support.test.uiautomator.UiDevice;
import android.telephony.SubscriptionInfo;
import android.telephony.ims.ImsMmTelManager;
import androidx.test.InstrumentationRegistry;
import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.ViewInteraction;
import androidx.test.runner.AndroidJUnit4;
import com.android.ims.ImsManager;
import com.android.internal.telephony.SubscriptionController;
import com.android.settings.testutils.MockedServiceManager;
import junit.framework.Assert;
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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class WifiCallingSettingUiTest {
private static final String SUBSCRIPTION0_NAME = "SUB0";
private static final String SUBSCRIPTION1_NAME = "SUB1";
private static final String WFC_MODE_TITLE = "Calling preference";
private static final String WFC_MODE_WIFI_ONLY = "Wi-Fi only";
private static final String WFC_MODE_WIFI_PREFERRED = "Wi-Fi preferred";
private static final String WFC_MODE_CELLULAR_PREFERRED = "Mobile preferred";
private Instrumentation mInstrumentation;
private Context mContext;
private UiDevice mDevice;
@Mock
SubscriptionController mSubscriptionController;
MockedServiceManager mMockedServiceManager;
protected HashMap<Integer, ImsManager> mImsManagerInstances = new HashMap<>();
List<SubscriptionInfo> mSils = new ArrayList();
@Mock
SubscriptionInfo mSubscriptionInfo0;
@Mock
SubscriptionInfo mSubscriptionInfo1;
@Mock
ImsManager mImsManager0;
@Mock
ImsManager mImsManager1;
@Mock
ImsMmTelManager mImsMmTelManager0;
@Mock
ImsMmTelManager mImsMmTelManager1;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mContext = mInstrumentation.getTargetContext();
mDevice = UiDevice.getInstance(mInstrumentation);
mMockedServiceManager = new MockedServiceManager();
mMockedServiceManager.replaceService("isub", mSubscriptionController);
mMockedServiceManager.replaceInstance(
ImsManager.class, "sImsManagerInstances", null, mImsManagerInstances);
mMockedServiceManager.replaceInstance(
SubscriptionController.class, "sInstance", null, mSubscriptionController);
doReturn(mSubscriptionController)
.when(mSubscriptionController).queryLocalInterface(anyString());
mImsManagerInstances.put(0, mImsManager0);
mImsManagerInstances.put(1, mImsManager1);
doReturn(mSils).when(mSubscriptionController).getActiveSubscriptionInfoList(anyString(),
nullable(String.class));
doReturn(0).when(mSubscriptionController).getPhoneId(0);
doReturn(1).when(mSubscriptionController).getPhoneId(1);
doReturn(0).when(mSubscriptionInfo0).getSubscriptionId();
doReturn(1).when(mSubscriptionInfo1).getSubscriptionId();
doReturn(0).when(mSubscriptionInfo0).getSimSlotIndex();
doReturn(1).when(mSubscriptionInfo1).getSimSlotIndex();
doReturn(SUBSCRIPTION0_NAME).when(mSubscriptionInfo0).getDisplayName();
doReturn(SUBSCRIPTION1_NAME).when(mSubscriptionInfo1).getDisplayName();
doReturn(true).when(mImsManager0).isWfcEnabledByPlatform();
doReturn(true).when(mImsManager0).isNonTtyOrTtyOnVolteEnabled();
doReturn(true).when(mImsManager1).isWfcEnabledByPlatform();
doReturn(true).when(mImsManager1).isNonTtyOrTtyOnVolteEnabled();
mDevice.wakeUp();
mDevice.pressMenu();
}
@After
public void tearDown() throws Exception {
mMockedServiceManager.restoreAllServices();
}
@Test
public void testSingleSimUi() throws InterruptedException {
configureSingleSim();
doReturn(true).when(mImsManager0).isWfcEnabledByUser();
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
.when(mImsMmTelManager0).getVoWiFiModeSetting();
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
.when(mImsMmTelManager0).getVoWiFiRoamingModeSetting();
mInstrumentation.startActivitySync(createActivityIntent());
checkSingleSimUi();
try {
mDevice.setOrientationLeft();
} catch (Exception e) {
Assert.fail("Exception " + e);
}
// Re-check after rotation. Fragment should be recreated properly.
checkSingleSimUi();
try {
mDevice.setOrientationNatural();
} catch (Exception e) {
Assert.fail("Exception " + e);
}
// Re-check after rotation. Fragment should be resumed properly.
checkSingleSimUi();
}
private void checkSingleSimUi() {
assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
assertEquals(true, checkExists(onView(withText(WFC_MODE_TITLE))));
assertEquals(true, checkExists(onView(withText(WFC_MODE_WIFI_PREFERRED))));
checkSwitchBarStatus(true, true);
checkEmptyViewStatus(false);
}
@Test
public void testNoValidSub() throws InterruptedException {
configureDualSim();
doReturn(false).when(mImsManager0).isWfcEnabledByPlatform();
doReturn(false).when(mImsManager0).isNonTtyOrTtyOnVolteEnabled();
doReturn(false).when(mImsManager1).isWfcEnabledByPlatform();
doReturn(false).when(mImsManager1).isNonTtyOrTtyOnVolteEnabled();
doReturn(false).when(mImsManager0).isWfcEnabledByUser();
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
.when(mImsMmTelManager0).getVoWiFiModeSetting();
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
.when(mImsMmTelManager0).getVoWiFiRoamingModeSetting();
Activity activity = mInstrumentation.startActivitySync(createActivityIntent());
assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
assertEquals(false, checkExists(onView(withText(WFC_MODE_TITLE))));
checkSwitchBarStatus(false, false);
checkEmptyViewStatus(false);
}
@Test
public void testWfcDisabled() throws InterruptedException {
configureSingleSim();
doReturn(false).when(mImsManager0).isWfcEnabledByUser();
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
.when(mImsMmTelManager0).getVoWiFiModeSetting();
doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
.when(mImsMmTelManager0).getVoWiFiRoamingModeSetting();
Activity activity = mInstrumentation.startActivitySync(createActivityIntent());
assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
assertEquals(false, checkExists(onView(withText(WFC_MODE_TITLE))));
checkSwitchBarStatus(true, false);
checkEmptyViewStatus(true);
}
@Test
public void testDualSimUi() throws InterruptedException {
configureDualSim();
doReturn(true).when(mImsManager0).isWfcEnabledByUser();
doReturn(false).when(mImsManager1).isWfcEnabledByUser();
doReturn(ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED)
.when(mImsMmTelManager0).getVoWiFiModeSetting();
doReturn(ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED)
.when(mImsMmTelManager0).getVoWiFiRoamingModeSetting();
mInstrumentation.startActivitySync(createActivityIntent());
assertEquals(true, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
assertEquals(true, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
assertEquals(true, checkExists(onView(withText(WFC_MODE_TITLE))));
assertEquals(true, checkExists(onView(withText(WFC_MODE_CELLULAR_PREFERRED))));
onView(withText(SUBSCRIPTION0_NAME)).check(matches(isSelected()));
checkSwitchBarStatus(true, true);
checkEmptyViewStatus(false);
// Switch to SUB1.
onView(withText(SUBSCRIPTION1_NAME)).perform(click());
checkSwitchBarStatus(true, false);
checkEmptyViewStatus(true);
onView(withText(SUBSCRIPTION1_NAME)).check(matches(isSelected()));
}
private boolean checkExists(ViewInteraction v) {
try {
v.check(matches(isCompletelyDisplayed()));
return true;
} catch (NoMatchingViewException e) {
return false;
}
}
private Intent createActivityIntent() {
Intent intent = new Intent(mContext,
com.android.settings.Settings.WifiCallingSettingsActivity.class);
intent.setPackage("com.android.settings");
intent.setAction("android.intent.action.MAIN");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}
private void configureSingleSim() {
mSils.clear();
mSils.add(mSubscriptionInfo0);
}
private void configureDualSim() {
mSils.clear();
mSils.add(mSubscriptionInfo0);
mSils.add(mSubscriptionInfo1);
}
private void checkSwitchBarStatus(boolean shouldDisplay, boolean statusOn) {
if (shouldDisplay) {
try {
onView(allOf(withResourceName("switch_text"), isCompletelyDisplayed()))
.check(matches(withText(containsString(statusOn ? "On" : "Off"))));
} catch (Exception e) {
Assert.fail("Exception " + e);
}
} else {
onView(allOf(withResourceName("switch_text"), isCompletelyDisplayed()))
.check(doesNotExist());
}
}
private void checkEmptyViewStatus(boolean shouldDisplay) {
try {
if (!shouldDisplay) {
onView(allOf(withResourceName("empty"), isCompletelyDisplayed()))
.check(doesNotExist());
} else {
onView(allOf(withResourceName("empty"), isCompletelyDisplayed()))
.check(matches(anything()));
}
} catch (Exception e) {
Assert.fail("Exception " + e);
}
}
}

View File

@@ -1,248 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.google.common.truth.Truth.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.startsWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import androidx.fragment.app.Fragment;
import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.Settings.WifiSettingsActivity;
import com.android.settingslib.utils.ThreadUtils;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
import com.google.common.collect.Lists;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class WifiSettingsUiTest {
private static final String TEST_SSID = "Test Ssid";
private static final String TEST_KEY = "Test Key";
// Keys used to lookup resources by name (see the resourceId/resourceString helper methods).
private static final String STRING = "string";
private static final String WIFI_CONFIGURE_SETTINGS_PREFERENCE_TITLE =
"wifi_configure_settings_preference_title";
private static final String WIFI_SAVED_ACCESS_POINTS_LABEL = "wifi_saved_access_points_label";
private static final String WIFI_EMPTY_LIST_WIFI_OFF = "wifi_empty_list_wifi_off";
private static final String WIFI_DISPLAY_STATUS_CONNECTED = "wifi_display_status_connected";
@Mock
private WifiPickerTracker mWifiTracker;
@Mock
private WifiPickerTracker.WifiPickerTrackerCallback mWifiListener;
private Context mContext;
private UiDevice mDevice;
@Rule
public ActivityTestRule<WifiSettingsActivity> mActivityRule =
new ActivityTestRule<>(WifiSettingsActivity.class, true);
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getTargetContext();
mDevice = UiDevice.getInstance(getInstrumentation());
}
/**
* Helper to get around the problem that directly accessing settings resource id's from
* com.android.settings.R via R.(type).(name) (eg R.id.password or
* R.string.wifi_configure_settings_preference_title) may not work due to mismatched resource
* ids. See b/37714546 and b/63546650.
*/
private int resourceId(String type, String name) {
return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
}
/** Similar to {@link #resourceId}, but for accessing R.string.<name> values. */
private String resourceString(String name) {
return mContext.getResources().getString(resourceId(STRING, name));
}
/** Launch the activity via an Intent with a String extra. */
private void launchActivity(String extraName, String extraValue) {
Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
if (extraName != null && extraValue != null) {
intent.putExtra(extraName, extraValue);
}
mActivityRule.launchActivity(intent);
List<Fragment> fragments =
mActivityRule.getActivity().getSupportFragmentManager().getFragments();
assertThat(fragments.size()).isEqualTo(1);
((WifiSettings) fragments.get(0)).mWifiPickerTracker = mWifiTracker;
mWifiListener = (WifiSettings) fragments.get(0);
assertThat(mWifiListener).isNotNull();
}
/** Helper to launch the activity with no extra. */
private void launchActivity() {
launchActivity(null, null);
}
private void setWifiState(int wifiState) {
when(mWifiTracker.getWifiState()).thenReturn(wifiState);
}
@Test
public void launchActivityShouldSucceed() {
launchActivity();
}
@Test
public void shouldShowWifiPreferences() {
launchActivity();
onView(withText(resourceId(STRING, WIFI_CONFIGURE_SETTINGS_PREFERENCE_TITLE))).check(
matches(isDisplayed()));
}
@Test
public void noSavedNetworks_wifiDisabled_shouldNotShowSavedNetworksButton() {
setWifiState(WifiManager.WIFI_STATE_DISABLED);
when(mWifiTracker.getNumSavedNetworks()).thenReturn(0);
launchActivity();
onView(withText(resourceId(STRING, WIFI_SAVED_ACCESS_POINTS_LABEL))).check(
doesNotExist());
}
@Test
public void savedNetworksExist_shouldShowSavedNetworksButton() {
setWifiState(WifiManager.WIFI_STATE_ENABLED);
when(mWifiTracker.getNumSavedNetworks()).thenReturn(1);
launchActivity();
mActivityRule.getActivity().getMainThreadHandler()
.post(() -> mWifiListener.onNumSavedNetworksChanged());
onView(allOf(withText(resourceId(STRING, WIFI_SAVED_ACCESS_POINTS_LABEL)),
withEffectiveVisibility(VISIBLE))).check(matches(isDisplayed()));
}
@Test
public void onWifiStateChanged_wifiDisabled_seeOffMessage() {
setWifiState(WifiManager.WIFI_STATE_DISABLED);
launchActivity();
mActivityRule.getActivity().getMainThreadHandler()
.post(() -> mWifiListener.onWifiStateChanged());
onView(withText(startsWith(resourceString(WIFI_EMPTY_LIST_WIFI_OFF)))).check(
matches(isDisplayed()));
}
@Test
public void onWifiStateChanged_wifiEnabled_shouldNotSeeOffMessage() {
setWifiState(WifiManager.WIFI_STATE_ENABLED);
launchActivity();
mActivityRule.getActivity().getMainThreadHandler()
.post(() -> mWifiListener.onWifiStateChanged());
onView(withText(startsWith(resourceString(WIFI_EMPTY_LIST_WIFI_OFF)))).check(
doesNotExist());
}
@Test
public void onConnected_shouldSeeConnectedMessage() {
setWifiState(WifiManager.WIFI_STATE_ENABLED);
final WifiEntry wifiEntry = mock(WifiEntry.class);
when(wifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
when(wifiEntry.getSummary(false /* concise */))
.thenReturn(resourceString(WIFI_DISPLAY_STATUS_CONNECTED));
when(wifiEntry.getKey()).thenReturn(TEST_KEY);
when(mWifiTracker.getConnectedWifiEntry()).thenReturn(wifiEntry);
launchActivity();
ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged());
mDevice.waitForIdle();
onView(withText(resourceString(WIFI_DISPLAY_STATUS_CONNECTED))).check(
matches(isDisplayed()));
}
@Test
public void changingSecurityStateOnAp_ShouldNotCauseMultipleListItems() {
setWifiState(WifiManager.WIFI_STATE_ENABLED);
final WifiEntry openWifiEntry = mock(WifiEntry.class);
when(openWifiEntry.getTitle()).thenReturn(TEST_SSID);
when(openWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_NONE);
final WifiEntry eapWifiEntry = mock(WifiEntry.class);
when(eapWifiEntry.getTitle()).thenReturn(TEST_SSID);
when(eapWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP);
final WifiEntry wepWifiEntry = mock(WifiEntry.class);
when(wepWifiEntry.getTitle()).thenReturn(TEST_SSID);
when(wepWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_WEP);
// Return a different security state each time getWifiEntries is invoked
when(mWifiTracker.getWifiEntries())
.thenReturn(Lists.newArrayList(openWifiEntry))
.thenReturn(Lists.newArrayList(eapWifiEntry))
.thenReturn(Lists.newArrayList(wepWifiEntry));
launchActivity();
ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged());
mDevice.waitForIdle();
onView(withText(TEST_SSID)).check(matches(isDisplayed()));
ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged());
mDevice.waitForIdle();
onView(withText(TEST_SSID)).check(matches(isDisplayed()));
ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged());
mDevice.waitForIdle();
onView(withText(TEST_SSID)).check(matches(isDisplayed()));
}
}

View File

@@ -1,110 +0,0 @@
/*
* 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.wifi.dpp;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE;
import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK;
import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import androidx.fragment.app.FragmentManager;
import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class WifiDppChooseSavedWifiNetworkFragmentTest {
// Valid Wi-Fi DPP QR code
private static final String VALID_WIFI_DPP_QR_CODE = "DPP:I:SN=4774LH2b4044;M:010203040506;K:"
+ "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;";
// Keys used to lookup resources by name (see the resourceId/resourceString helper methods).
private static final String STRING = "string";
private static final String WIFI_DPP_CHOOSE_DIFFERENT_NETWORK =
"wifi_dpp_choose_different_network";
private static final String CANCEL = "cancel";
@Rule
public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
new ActivityTestRule<>(WifiDppConfiguratorActivity.class, /* initialTouchMode */true,
/* launchActivity */ false);
private Context mContext;
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
}
@Test
public void clickCancelButton_configuratorQrCodeScannerIntent_shouldPopBackStack() {
final Intent intent =
new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
final WifiDppConfiguratorActivity hostActivity = mActivityRule.launchActivity(intent);
// Go to WifiDppChooseSavedWifiNetworkFragment and click the cancel button
final FragmentManager fragmentManager = hostActivity.getSupportFragmentManager();
final WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
hostActivity.runOnUiThread(() ->
((WifiDppConfiguratorActivity)hostActivity).onScanWifiDppSuccess(wifiQrCode)
);
onView(withText(resourceString(WIFI_DPP_CHOOSE_DIFFERENT_NETWORK))).perform(click());
onView(withText(resourceString(CANCEL))).perform(click());
assertThat(fragmentManager.findFragmentByTag(TAG_FRAGMENT_ADD_DEVICE)).isNotNull();
assertThat(fragmentManager.findFragmentByTag(TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK))
.isNull();
}
@Test
public void clickCancelButton_processWifiDppQrCodeIntent_shouldFinish() {
final Intent intent = new Intent(Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_URI);
intent.setData(Uri.parse(VALID_WIFI_DPP_QR_CODE));
final WifiDppConfiguratorActivity hostActivity = mActivityRule.launchActivity(intent);
onView(withText(resourceString(CANCEL))).perform(click());
assertThat(hostActivity.isFinishing()).isEqualTo(true);
}
private int resourceId(String type, String name) {
return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
}
/** Similar to {@link #resourceId}, but for accessing R.string.<name> values. */
private String resourceString(String name) {
return mContext.getResources().getString(resourceId(STRING, name));
}
}

View File

@@ -1,183 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi.dpp;
import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import androidx.fragment.app.FragmentManager;
import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.google.android.setupdesign.GlifLayout;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class WifiDppConfiguratorActivityTest {
// Valid Wi-Fi DPP QR code & it's parameters
private static final String VALID_WIFI_DPP_QR_CODE = "DPP:I:SN=4774LH2b4044;M:010203040506;K:"
+ "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;";
@Rule
public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
new ActivityTestRule<>(WifiDppConfiguratorActivity.class);
private UiDevice mDevice;
@Before
public void setUp() {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
}
@Test
public void launchActivity_qrCodeScanner_shouldNotAutoFinish() {
Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
mActivityRule.launchActivity(intent);
FragmentManager fragmentManager = mActivityRule.getActivity().getSupportFragmentManager();
WifiDppQrCodeScannerFragment fragment =
(WifiDppQrCodeScannerFragment) fragmentManager.findFragmentByTag(
WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
assertThat(fragment.getView() instanceof GlifLayout).isTrue();
assertThat(mActivityRule.getActivity().isFinishing()).isFalse();
}
@Test
public void launchActivity_qrCodeGenerator_shouldNotAutoFinish() {
Intent intent = new Intent(
WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
mActivityRule.launchActivity(intent);
FragmentManager fragmentManager = mActivityRule.getActivity().getSupportFragmentManager();
WifiDppQrCodeGeneratorFragment fragment =
(WifiDppQrCodeGeneratorFragment) fragmentManager.findFragmentByTag(
WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
assertThat(fragment.getView() instanceof GlifLayout).isTrue();
assertThat(mActivityRule.getActivity().isFinishing()).isFalse();
}
@Test
public void launchActivity_chooseSavedWifiNetwork_shouldNotAutoFinish() {
final Intent intent = new Intent(Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_URI);
intent.setData(Uri.parse(VALID_WIFI_DPP_QR_CODE));
mActivityRule.launchActivity(intent);
assertThat(mActivityRule.getActivity().isFinishing()).isFalse();
}
@Test
public void testActivity_shouldImplementsWifiNetworkConfigRetriever() {
WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
assertThat(activity instanceof WifiNetworkConfig.Retriever).isTrue();
}
@Test
public void testActivity_shouldImplementsOnScanWifiDppSuccessCallback() {
WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
assertThat(activity instanceof WifiDppQrCodeScannerFragment
.OnScanWifiDppSuccessListener).isTrue();
}
@Test
public void testActivity_shouldImplementsOnClickChooseDifferentNetworkCallback() {
WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
assertThat(activity instanceof WifiDppAddDeviceFragment
.OnClickChooseDifferentNetworkListener).isTrue();
}
@Test
public void rotateScreen_shouldGetCorrectWifiDppQrCode() {
WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
// setWifiDppQrCode and check if getWifiDppQrCode correctly after rotation
mActivityRule.launchActivity(intent);
mActivityRule.getActivity().setWifiDppQrCode(wifiQrCode);
try {
mDevice.setOrientationLeft();
mDevice.setOrientationNatural();
mDevice.setOrientationRight();
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
WifiQrCode restoredWifiDppQrCode = mActivityRule.getActivity().getWifiDppQrCode();
assertThat(restoredWifiDppQrCode).isNotNull();
assertThat(restoredWifiDppQrCode.getQrCode()).isEqualTo(VALID_WIFI_DPP_QR_CODE);
}
@Test
public void rotateScreen_shouldGetCorrectWifiNetworkConfig() {
final WifiNetworkConfig wifiNetworkConfig = new WifiNetworkConfig("WPA", "WifiSsid",
"password", /* hiddenSsid */ false, /* networkId */ 0, /* isHotspot */ true);
final Intent intent = new Intent(Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_URI);
intent.setData(Uri.parse(VALID_WIFI_DPP_QR_CODE));
// setWifiNetworkConfig and check if getWifiNetworkConfig correctly after rotation
mActivityRule.launchActivity(intent);
mActivityRule.getActivity().setWifiNetworkConfig(wifiNetworkConfig);
try {
mDevice.setOrientationLeft();
mDevice.setOrientationNatural();
mDevice.setOrientationRight();
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
WifiNetworkConfig restoredWifiNetworkConfig =
mActivityRule.getActivity().getWifiNetworkConfig();
assertThat(restoredWifiNetworkConfig).isNotNull();
assertThat(restoredWifiNetworkConfig.getSecurity()).isEqualTo("WPA");
assertThat(restoredWifiNetworkConfig.getSsid()).isEqualTo("WifiSsid");
assertThat(restoredWifiNetworkConfig.getPreSharedKey()).isEqualTo("password");
assertThat(restoredWifiNetworkConfig.getHiddenSsid()).isFalse();
assertThat(restoredWifiNetworkConfig.getNetworkId()).isEqualTo(0);
assertThat(restoredWifiNetworkConfig.isHotspot()).isTrue();
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi.dpp;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class WifiDppEnrolleeActivityTest {
@Rule
public final ActivityTestRule<WifiDppEnrolleeActivity> mActivityRule =
new ActivityTestRule<>(WifiDppEnrolleeActivity.class);
@Test
public void testActivity_shouldImplementsOnScanWifiDppSuccessCallback() {
WifiDppEnrolleeActivity activity = mActivityRule.getActivity();
assertThat(activity instanceof WifiDppQrCodeScannerFragment
.OnScanWifiDppSuccessListener).isEqualTo(true);
}
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi.dpp;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class WifiDppQrCodeGeneratorFragmentTest {
@Rule
public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
new ActivityTestRule<>(WifiDppConfiguratorActivity.class, true);
@Before
public void setUp() {
Intent intent =
new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
mActivityRule.launchActivity(intent);
}
@Test
public void rotateScreen_shouldNotCrash() {
mActivityRule.getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mActivityRule.getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi.dpp;
import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER;
import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import androidx.fragment.app.FragmentManager;
import androidx.test.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class WifiDppQrCodeScannerFragmentTest {
@Rule
public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
new ActivityTestRule<>(WifiDppConfiguratorActivity.class, true);
@Before
public void setUp() {
Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
mActivityRule.launchActivity(intent);
}
@Test
public void rotateScreen_shouldNotCrash() {
mActivityRule.getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mActivityRule.getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
@Test
public void onPause_shouldNotDecodeQrCode() {
final WifiDppConfiguratorActivity hostActivity =
(WifiDppConfiguratorActivity) mActivityRule.getActivity();
final FragmentManager fragmentManager = hostActivity.getSupportFragmentManager();
final WifiDppQrCodeScannerFragment scannerFragment =
(WifiDppQrCodeScannerFragment) fragmentManager
.findFragmentByTag(TAG_FRAGMENT_QR_CODE_SCANNER);
final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
instrumentation.runOnMainSync(() -> {
instrumentation.callActivityOnPause(hostActivity);
assertThat(scannerFragment.isDecodeTaskAlive()).isEqualTo(false);
});
}
}

View File

@@ -1,254 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi.dpp;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class WifiQrCodeTest {
// Valid Wi-Fi DPP QR code & it's parameters
private static final String VALID_WIFI_DPP_QR_CODE = "DPP:I:SN=4774LH2b4044;M:010203040506;K:"
+ "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;";
private static final String PUBLIC_KEY_OF_VALID_WIFI_DPP_QR_CODE =
"MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=";
private static final String INFORMATION_OF_VALID_WIFI_DPP_QR_CODE =
"SN=4774LH2b4044";
// Valid ZXing reader library's Wi-Fi Network config format & it's parameters
private static final String VALID_ZXING_WIFI_QR_CODE_WPA =
"WIFI:T:WPA;S:mynetwork;P:mypass;H:true;;";
// Valid ZXing reader library's Wi-Fi Network config format - security type SAE
private static final String VALID_ZXING_WIFI_QR_CODE_SAE =
"WIFI:T:SAE;S:mynetwork;P:mypass;H:true;;";
// Valid ZXing reader library's Wi-Fi Network config format - security type nopass and no password
private static final String VALID_ZXING_WIFI_QR_CODE_NOPASS_AND_NO_PASSWORD =
"WIFI:T:nopass;S:mynetwork;;";
// Valid ZXing reader library's Wi-Fi Network config format - no security and no password
private static final String VALID_ZXING_WIFI_QR_CODE_NO_SECURITY_AND_NO_PASSWORD =
"WIFI:T:;S:mynetwork;P:;H:false;;";
private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA = "WPA";
private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_SAE = "SAE";
private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_NOPASS = "nopass";
private static final String SSID_OF_VALID_ZXING_WIFI_QR_CODE = "mynetwork";
private static final String PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE = "mypass";
// Valid ZXing reader library's Wi-Fi Network config format - escaped characters
private static final String VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS =
"WIFI:T:WPA;S:mynetwork;P:m\\;y\\:p\\\\a\\,ss;H:true;;";
private static final String PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS =
"m;y:p\\a,ss";
// Invalid scheme QR code
private static final String INVALID_SCHEME_QR_CODE = "BT:T:WPA;S:mynetwork;P:mypass;H:true;;";
// Invalid Wi-Fi DPP QR code - no public key - case 1
private static final String INVALID_WIFI_DPP_QR_CODE_NO_PUBLIC_KEY_1 =
"DPP:I:SN=4774LH2b4044;M:010203040506;K:;;";
// Invalid Wi-Fi DPP QR code - no public key - case 2
private static final String INVALID_WIFI_DPP_QR_CODE_NO_PUBLIC_KEY_2 =
"DPP:I:SN=4774LH2b4044;M:010203040506;;";
// Invalid ZXing reader library's Wi-Fi Network config format - no password
private static final String INVALID_ZXING_WIFI_QR_CODE_NO_PASSWORD =
"WIFI:T:WPA;S:mynetwork;P:;;";
// Invalid ZXing reader library's Wi-Fi Network config format - no SSID
private static final String INVALID_ZXING_WIFI_QR_CODE_NO_SSID =
"WIFI:T:WPA;P:mypass;;";
@Test
public void parseValidWifiDppQrCode() {
WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
assertEquals(WifiQrCode.SCHEME_DPP, wifiQrCode.getScheme());
assertEquals(PUBLIC_KEY_OF_VALID_WIFI_DPP_QR_CODE, wifiQrCode.getPublicKey());
assertEquals(INFORMATION_OF_VALID_WIFI_DPP_QR_CODE, wifiQrCode.getInformation());
}
@Test
public void parseValidZxingWifiQrCode() {
WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_WPA);
WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
assertNotNull(config);
assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA, config.getSecurity());
assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE, config.getPreSharedKey());
assertEquals(true, config.getHiddenSsid());
}
@Test
public void parseValidZxingWifiQrCodeSae() {
WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_SAE);
WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
assertNotNull(config);
assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_SAE, config.getSecurity());
assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE, config.getPreSharedKey());
assertEquals(true, config.getHiddenSsid());
}
@Test
public void parseValidZxingWifiQrCode_noPass_and_no_password() {
WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_NOPASS_AND_NO_PASSWORD);
WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
assertNotNull(config);
assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_NOPASS, config.getSecurity());
assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
assertNull(config.getPreSharedKey());
assertEquals(false, config.getHiddenSsid());
}
@Test
public void parseValidZxingWifiQrCode_no_security_and_no_password() {
WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_NO_SECURITY_AND_NO_PASSWORD);
WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
assertNotNull(config);
assertEquals("", config.getSecurity());
assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
assertEquals("", config.getPreSharedKey());
assertEquals(false, config.getHiddenSsid());
}
@Test
public void parseValidZxingWifiQrCode_specialCharacters() {
WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS);
WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
assertNotNull(config);
assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA, config.getSecurity());
assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS,
config.getPreSharedKey());
assertEquals(true, config.getHiddenSsid());
}
@Test
public void testRemoveBackSlash() {
WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
assertEquals("\\", wifiQrCode.removeBackSlash("\\\\"));
assertEquals("ab", wifiQrCode.removeBackSlash("a\\b"));
assertEquals("a", wifiQrCode.removeBackSlash("\\a"));
assertEquals("\\b", wifiQrCode.removeBackSlash("\\\\b"));
assertEquals("c\\", wifiQrCode.removeBackSlash("c\\\\"));
}
@Test
public void parseEmptyQrCode_shouldThrowIllegalArgumentException() {
try {
new WifiQrCode(null);
fail("Null QR code");
} catch (IllegalArgumentException e) {
// Do nothing
}
try {
new WifiQrCode("");
fail("Empty string QR code");
} catch (IllegalArgumentException e) {
// Do nothing
}
try {
new WifiQrCode("DPP:;");
fail("Empty content WIFI DPP QR code");
} catch (IllegalArgumentException e) {
// Do nothing
}
try {
new WifiQrCode("WIFI:;");
fail("Empty content ZXing WIFI QR code");
} catch (IllegalArgumentException e) {
// Do nothing
}
}
@Test
public void parseInvalidSchemeQrCode_shouldThrowIllegalArgumentException() {
try {
new WifiQrCode(INVALID_SCHEME_QR_CODE);
fail("Invalid scheme");
} catch (IllegalArgumentException e) {
// Do nothing
}
}
@Test
public void parseInvalidWifiDppQrCode_noPublicKey_shouldThrowIllegalArgumentException() {
try {
new WifiQrCode(INVALID_WIFI_DPP_QR_CODE_NO_PUBLIC_KEY_1);
fail("No public key case 1");
} catch (IllegalArgumentException e) {
// Do nothing
}
try {
new WifiQrCode(INVALID_WIFI_DPP_QR_CODE_NO_PUBLIC_KEY_2);
fail("No public key case 2");
} catch (IllegalArgumentException e) {
// Do nothing
}
}
@Test
public void parseInvalidZxingWifiQrCode_noPassword_shouldThrowIllegalArgumentException() {
try {
new WifiQrCode(INVALID_ZXING_WIFI_QR_CODE_NO_PASSWORD);
fail("No password");
} catch (IllegalArgumentException e) {
// Do nothing
}
}
@Test
public void parseInvalidZxingWifiQrCode_noSsid_shouldThrowIllegalArgumentException() {
try {
new WifiQrCode(INVALID_ZXING_WIFI_QR_CODE_NO_SSID);
fail("No SSID");
} catch (IllegalArgumentException e) {
// Do nothing
}
}
}

View File

@@ -1,396 +0,0 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi.tether;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_INVALID;
import static android.net.TetheringManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static com.android.settings.wifi.tether.TetherService.EXTRA_TETHER_PROVISIONING_RESPONSE;
import static com.android.settings.wifi.tether.TetherService.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
import static com.android.settings.wifi.tether.TetherService.EXTRA_TETHER_SUBID;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
import android.app.PendingIntent;
import android.app.usage.UsageStatsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.TetheringManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.test.ServiceTestCase;
import android.util.Log;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class TetherServiceTest extends ServiceTestCase<TetherService> {
private static final String TAG = "TetherServiceTest";
private static final String FAKE_PACKAGE_NAME = "com.some.package.name";
private static final String ENTITLEMENT_PACKAGE_NAME = "com.some.entitlement.name";
private static final String TEST_RESPONSE_ACTION = "testProvisioningResponseAction";
private static final String TEST_NO_UI_ACTION = "testNoUiProvisioningRequestAction";
private static final int BOGUS_RECEIVER_RESULT = -5;
private static final int MS_PER_HOUR = 60 * 60 * 1000;
private static final int SHORT_TIMEOUT = 100;
private static final int PROVISION_TIMEOUT = 1000;
private TetherService mService;
private MockTetherServiceWrapper mWrapper;
int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
private int mLastTetherRequestType = TETHERING_INVALID;
private int mProvisionResponse = BOGUS_RECEIVER_RESULT;
private ProvisionReceiver mProvisionReceiver;
private Receiver mResultReceiver;
@Mock private TetheringManager mTetheringManager;
@Mock private PackageManager mPackageManager;
@Mock private WifiManager mWifiManager;
@Mock private SharedPreferences mPrefs;
@Mock private Editor mPrefEditor;
@Captor private ArgumentCaptor<PendingIntent> mPiCaptor;
@Captor private ArgumentCaptor<String> mStoredTypes;
public TetherServiceTest() {
super(TetherService.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
mContext = new TestContextWrapper(getContext());
setContext(mContext);
mResultReceiver = new Receiver(this);
mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
mProvisionResponse = Activity.RESULT_OK;
mProvisionReceiver = new ProvisionReceiver();
IntentFilter filter = new IntentFilter(TEST_NO_UI_ACTION);
filter.addCategory(Intent.CATEGORY_DEFAULT);
mContext.registerReceiver(mProvisionReceiver, filter);
final String CURRENT_TYPES = "currentTethers";
when(mPrefs.getString(CURRENT_TYPES, "")).thenReturn("");
when(mPrefs.edit()).thenReturn(mPrefEditor);
when(mPrefEditor.putString(eq(CURRENT_TYPES), mStoredTypes.capture())).thenReturn(
mPrefEditor);
mWrapper = new MockTetherServiceWrapper(mContext);
ResolveInfo systemAppResolveInfo = new ResolveInfo();
ActivityInfo systemActivityInfo = new ActivityInfo();
systemActivityInfo.packageName = ENTITLEMENT_PACKAGE_NAME;
ApplicationInfo systemAppInfo = new ApplicationInfo();
systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
systemActivityInfo.applicationInfo = systemAppInfo;
systemAppResolveInfo.activityInfo = systemActivityInfo;
ResolveInfo nonSystemResolveInfo = new ResolveInfo();
ActivityInfo nonSystemActivityInfo = new ActivityInfo();
nonSystemActivityInfo.packageName = FAKE_PACKAGE_NAME;
nonSystemActivityInfo.applicationInfo = new ApplicationInfo();
nonSystemResolveInfo.activityInfo = nonSystemActivityInfo;
List<ResolveInfo> resolvers = new ArrayList();
resolvers.add(nonSystemResolveInfo);
resolvers.add(systemAppResolveInfo);
when(mPackageManager.queryBroadcastReceivers(
any(Intent.class), eq(PackageManager.MATCH_ALL))).thenReturn(resolvers);
setupService();
getService().setTetherServiceWrapper(mWrapper);
}
@Override
protected void tearDown() throws Exception {
mContext.unregisterReceiver(mProvisionReceiver);
super.tearDown();
}
public void testStartForProvision() {
runProvisioningForType(TETHERING_WIFI);
assertTrue(waitForProvisionRequest(TETHERING_WIFI));
assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
}
public void testStartKeepsProvisionAppActive() {
runProvisioningForType(TETHERING_WIFI);
assertTrue(waitForProvisionRequest(TETHERING_WIFI));
assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
assertFalse(mWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME));
// Non-system handler of the intent action should stay idle.
assertTrue(mWrapper.isAppInactive(FAKE_PACKAGE_NAME));
}
public void testStartMultiple() {
runProvisioningForType(TETHERING_WIFI);
assertTrue(waitForProvisionRequest(TETHERING_WIFI));
assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
runProvisioningForType(TETHERING_USB);
assertTrue(waitForProvisionRequest(TETHERING_USB));
assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
runProvisioningForType(TETHERING_BLUETOOTH);
assertTrue(waitForProvisionRequest(TETHERING_BLUETOOTH));
assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
}
public void testPersistTypes() {
runProvisioningForType(TETHERING_WIFI);
waitForProvisionRequest(TETHERING_WIFI);
waitForProvisionResponse(TETHER_ERROR_NO_ERROR);
runProvisioningForType(TETHERING_BLUETOOTH);
waitForProvisionRequest(TETHERING_BLUETOOTH);
waitForProvisionResponse(TETHER_ERROR_NO_ERROR);
shutdownService();
assertEquals(TETHERING_WIFI + "," + TETHERING_BLUETOOTH, mStoredTypes.getValue());
}
public void testFailureStopsTethering_Wifi() {
mProvisionResponse = Activity.RESULT_CANCELED;
runProvisioningForType(TETHERING_WIFI);
assertTrue(waitForProvisionRequest(TETHERING_WIFI));
assertTrue(waitForProvisionResponse(TETHER_ERROR_PROVISIONING_FAILED));
verify(mTetheringManager).stopTethering(TETHERING_WIFI);
}
public void testFailureStopsTethering_Usb() {
mProvisionResponse = Activity.RESULT_CANCELED;
runProvisioningForType(TETHERING_USB);
assertTrue(waitForProvisionRequest(TETHERING_USB));
assertTrue(waitForProvisionResponse(TETHER_ERROR_PROVISIONING_FAILED));
verify(mTetheringManager).stopTethering(TETHERING_USB);
}
public void testIgnoreOutdatedRequest() {
Intent intent = new Intent();
intent.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI);
intent.putExtra(EXTRA_RUN_PROVISION, true);
intent.putExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION, TEST_NO_UI_ACTION);
intent.putExtra(EXTRA_PROVISION_CALLBACK, mResultReceiver);
intent.putExtra(EXTRA_TETHER_SUBID, 1 /* Tested subId number */);
intent.putExtra(EXTRA_TETHER_PROVISIONING_RESPONSE, TEST_RESPONSE_ACTION);
startService(intent);
SystemClock.sleep(PROVISION_TIMEOUT);
assertEquals(TETHERING_INVALID, mLastTetherRequestType);
assertTrue(mWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME));
assertTrue(mWrapper.isAppInactive(FAKE_PACKAGE_NAME));
}
private void runProvisioningForType(int type) {
Intent intent = new Intent();
intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
intent.putExtra(EXTRA_RUN_PROVISION, true);
intent.putExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION, TEST_NO_UI_ACTION);
intent.putExtra(EXTRA_PROVISION_CALLBACK, mResultReceiver);
intent.putExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID);
intent.putExtra(EXTRA_TETHER_PROVISIONING_RESPONSE, TEST_RESPONSE_ACTION);
startService(intent);
}
private boolean waitForAppInactive(UsageStatsManager usageStatsManager, String packageName) {
long startTime = SystemClock.uptimeMillis();
while (true) {
if (usageStatsManager.isAppInactive(packageName)) {
return true;
}
if ((SystemClock.uptimeMillis() - startTime) > PROVISION_TIMEOUT) {
return false;
}
SystemClock.sleep(SHORT_TIMEOUT);
}
}
private boolean waitForProvisionRequest(int expectedType) {
long startTime = SystemClock.uptimeMillis();
while (true) {
if (mLastTetherRequestType == expectedType) {
mLastTetherRequestType = TETHERING_INVALID;
return true;
}
if ((SystemClock.uptimeMillis() - startTime) > PROVISION_TIMEOUT) {
Log.v(TAG, String.format(
"waitForProvisionRequest timeout: expected=%d, actual=%d",
expectedType, mLastTetherRequestType));
return false;
}
SystemClock.sleep(SHORT_TIMEOUT);
}
}
private boolean waitForProvisionResponse(int expectedValue) {
long startTime = SystemClock.uptimeMillis();
while (true) {
if (mLastReceiverResultCode == expectedValue) {
mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
return true;
}
if ((SystemClock.uptimeMillis() - startTime) > PROVISION_TIMEOUT) {
Log.v(TAG, String.format(
"waitForProvisionResponse timeout: expected=%d, actual=%d",
expectedValue, mLastReceiverResultCode));
return false;
}
SystemClock.sleep(SHORT_TIMEOUT);
}
}
private class TestContextWrapper extends ContextWrapper {
public TestContextWrapper(Context base) {
super(base);
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
// Stub out prefs to control the persisted tether type list.
if (name == "tetherPrefs") {
return mPrefs;
}
return super.getSharedPreferences(name, mode);
}
@Override
public PackageManager getPackageManager() {
return mPackageManager;
}
@Override
public Object getSystemService(String name) {
if (TETHERING_SERVICE.equals(name)) {
return mTetheringManager;
} else if (WIFI_SERVICE.equals(name)) {
return mWifiManager;
}
return super.getSystemService(name);
}
}
private static final class Receiver extends ResultReceiver {
final WeakReference<TetherServiceTest> mTest;
Receiver(TetherServiceTest test) {
super(null);
mTest = new WeakReference<TetherServiceTest>(test);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
TetherServiceTest test = mTest.get();
if (test != null) {
test.mLastReceiverResultCode = resultCode;
}
}
};
/**
* Stubs out the provisioning app receiver.
*/
private class ProvisionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
mLastTetherRequestType = intent.getIntExtra("TETHER_TYPE", TETHERING_INVALID);
sendResponse(mProvisionResponse, context);
}
private void sendResponse(int response, Context context) {
Intent responseIntent = new Intent(TEST_RESPONSE_ACTION);
responseIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
responseIntent.putExtra(TetherService.EXTRA_RESULT, response);
context.sendBroadcast(
responseIntent, android.Manifest.permission.TETHER_PRIVILEGED);
}
}
private static class MockTetherServiceWrapper
extends TetherService.TetherServiceWrapper {
private final Set<String> mActivePackages;
MockTetherServiceWrapper(Context context) {
super(context);
mActivePackages = new HashSet<>();
}
@Override
void setAppInactive(String packageName, boolean isInactive) {
if (!isInactive) {
mActivePackages.add(packageName);
} else {
mActivePackages.remove(packageName);
}
}
boolean isAppInactive(String packageName) {
return !mActivePackages.contains(packageName);
}
@Override
int getActiveDataSubscriptionId() {
return INVALID_SUBSCRIPTION_ID;
}
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.wifi.tether;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import android.app.Instrumentation;
import android.content.Intent;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.Settings;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class WifiTetherSettingsTest {
private static final long TIMEOUT = 2000L;
private Instrumentation mInstrumentation;
private Intent mTetherActivityIntent;
private UiDevice mDevice;
@Before
public void setUp() {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mDevice = UiDevice.getInstance(mInstrumentation);
mTetherActivityIntent = new Intent()
.setClassName(mInstrumentation.getTargetContext().getPackageName(),
Settings.TetherSettingsActivity.class.getName())
.setPackage(mInstrumentation.getTargetContext().getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
@After
public void tearDown() {
mDevice.pressHome();
}
@Test
public void launchTetherSettings_shouldHaveAllFields() {
launchWifiTetherActivity();
onView(withText("Hotspot name")).check(matches(isDisplayed()));
onView(withText("Hotspot password")).check(matches(isDisplayed()));
}
private void launchWifiTetherActivity() {
mInstrumentation.startActivitySync(mTetherActivityIntent);
onView(withText("WiFi hotspot")).perform();
UiObject2 item = mDevice.wait(Until.findObject(By.text("WiFi hotspot")), TIMEOUT);
item.click();
}
}