[Settings] Remove failure JUnit test cases
This change removes all the files which have any failure JUnit test case. Bug: 168429329 Test: atest --test-mapping tests/unit:postsubmit Change-Id: I1665565760f9dfc185bf9b8dd871ee106eba5dd5
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
@@ -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.
|
||||
}
|
@@ -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.
|
||||
}
|
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.biometrics.fingerprint;
|
||||
|
||||
import static androidx.test.InstrumentationRegistry.getTargetContext;
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.intent.Intents.intended;
|
||||
import static androidx.test.espresso.intent.Intents.intending;
|
||||
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Instrumentation.ActivityResult;
|
||||
import android.content.ComponentName;
|
||||
|
||||
import androidx.test.espresso.intent.rule.IntentsTestRule;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.google.android.setupcompat.PartnerCustomizationLayout;
|
||||
import com.google.android.setupcompat.template.FooterBarMixin;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class FingerprintEnrollFinishTest {
|
||||
|
||||
@Rule
|
||||
public IntentsTestRule<FingerprintEnrollFinish> mActivityRule =
|
||||
new IntentsTestRule<>(FingerprintEnrollFinish.class);
|
||||
|
||||
@Test
|
||||
public void clickAddAnother_shouldLaunchEnrolling() {
|
||||
final ComponentName enrollingComponent = new ComponentName(
|
||||
getTargetContext(),
|
||||
FingerprintEnrollEnrolling.class);
|
||||
|
||||
intending(hasComponent(enrollingComponent))
|
||||
.respondWith(new ActivityResult(Activity.RESULT_CANCELED, null));
|
||||
|
||||
PartnerCustomizationLayout layout =
|
||||
mActivityRule.getActivity().findViewById(R.id.setup_wizard_layout);
|
||||
layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick();
|
||||
|
||||
intended(hasComponent(enrollingComponent));
|
||||
assertFalse(mActivityRule.getActivity().isFinishing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickAddAnother_shouldPropagateResults() {
|
||||
final ComponentName enrollingComponent = new ComponentName(
|
||||
getTargetContext(),
|
||||
FingerprintEnrollEnrolling.class);
|
||||
|
||||
intending(hasComponent(enrollingComponent))
|
||||
.respondWith(new ActivityResult(Activity.RESULT_OK, null));
|
||||
|
||||
PartnerCustomizationLayout layout =
|
||||
mActivityRule.getActivity().findViewById(R.id.setup_wizard_layout);
|
||||
layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick();
|
||||
|
||||
intended(hasComponent(enrollingComponent));
|
||||
assertTrue(mActivityRule.getActivity().isFinishing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickNext_shouldFinish() {
|
||||
onView(withId(R.id.next_button)).perform(click());
|
||||
assertTrue(mActivityRule.getActivity().isFinishing());
|
||||
}
|
||||
}
|
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics.fingerprint;
|
||||
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.test.ActivityUnitTestCase;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.google.android.setupcompat.PartnerCustomizationLayout;
|
||||
import com.google.android.setupcompat.template.FooterBarMixin;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FingerprintEnrollIntroductionTest
|
||||
extends ActivityUnitTestCase<FingerprintEnrollIntroduction> {
|
||||
|
||||
private TestContext mContext;
|
||||
|
||||
@Mock
|
||||
private FingerprintManager mFingerprintManager;
|
||||
|
||||
private FingerprintEnrollIntroduction mActivity;
|
||||
|
||||
public FingerprintEnrollIntroductionTest() {
|
||||
super(FingerprintEnrollIntroduction.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = new TestContext(getInstrumentation().getTargetContext());
|
||||
setActivityContext(mContext);
|
||||
|
||||
getInstrumentation().runOnMainSync(() -> {
|
||||
final Intent intent = new Intent();
|
||||
mActivity = startActivity(intent,
|
||||
null /* savedInstanceState */, null /* lastNonConfigurationInstance */);
|
||||
});
|
||||
}
|
||||
|
||||
public void testMaxFingerprint_shouldShowErrorMessage() {
|
||||
final int max = mContext.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
|
||||
doReturn(generateFingerprintList(max)).when(mFingerprintManager)
|
||||
.getEnrolledFingerprints(anyInt());
|
||||
|
||||
getInstrumentation().runOnMainSync(() -> {
|
||||
getInstrumentation().callActivityOnCreate(mActivity, null);
|
||||
getInstrumentation().callActivityOnResume(mActivity);
|
||||
});
|
||||
|
||||
final TextView errorTextView = (TextView) mActivity.findViewById(R.id.error_text);
|
||||
assertNotNull(errorTextView.getText().toString());
|
||||
|
||||
PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout);
|
||||
final Button nextButton = layout.getMixin(FooterBarMixin.class).getPrimaryButtonView();
|
||||
assertEquals(View.GONE, nextButton.getVisibility());
|
||||
}
|
||||
|
||||
private List<Fingerprint> generateFingerprintList(int num) {
|
||||
ArrayList<Fingerprint> list = new ArrayList<>();
|
||||
for (int i = 0; i < num; i++) {
|
||||
list.add(new Fingerprint("Fingerprint " + i, 0, i, 0));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public class TestContext extends ContextWrapper {
|
||||
|
||||
public TestContext(Context base) {
|
||||
super(base);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSystemService(String name) {
|
||||
if (Context.FINGERPRINT_SERVICE.equals(name)) {
|
||||
return mFingerprintManager;
|
||||
}
|
||||
return super.getSystemService(name);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.core;
|
||||
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.MediumTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.search.SearchIndexableData;
|
||||
import com.android.settingslib.search.SearchIndexableResources;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@MediumTest
|
||||
public class PreferenceControllerContractTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Presubmit
|
||||
public void controllersInSearchShouldImplementPreferenceControllerMixin() {
|
||||
Looper.prepare(); // Required by AutofillLoggingLevelPreferenceController
|
||||
final Set<String> errorClasses = new ArraySet<>();
|
||||
|
||||
final SearchIndexableResources resources =
|
||||
FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
|
||||
.getSearchIndexableResources();
|
||||
for (SearchIndexableData bundle : resources.getProviderValues()) {
|
||||
|
||||
final BaseSearchIndexProvider provider =
|
||||
(BaseSearchIndexProvider) bundle.getSearchIndexProvider();
|
||||
if (provider == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final List<AbstractPreferenceController> controllers =
|
||||
provider.getPreferenceControllers(mContext);
|
||||
if (controllers == null) {
|
||||
continue;
|
||||
}
|
||||
for (AbstractPreferenceController controller : controllers) {
|
||||
if (!(controller instanceof PreferenceControllerMixin)
|
||||
&& !(controller instanceof BasePreferenceController)) {
|
||||
errorClasses.add(controller.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!errorClasses.isEmpty()) {
|
||||
final StringBuilder errorMessage = new StringBuilder()
|
||||
.append("Each preference must implement PreferenceControllerMixin ")
|
||||
.append("or extend BasePreferenceController, ")
|
||||
.append("the following classes don't:\n");
|
||||
for (String c : errorClasses) {
|
||||
errorMessage.append(c).append("\n");
|
||||
}
|
||||
fail(errorMessage.toString());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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));
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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)));
|
||||
}
|
||||
}
|
@@ -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];
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -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()));
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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()));
|
||||
}
|
||||
}
|
@@ -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));
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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("Wi‑Fi hotspot")).perform();
|
||||
UiObject2 item = mDevice.wait(Until.findObject(By.text("Wi‑Fi hotspot")), TIMEOUT);
|
||||
item.click();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user