feat: SettingsLib验证通过-使用App module启用
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import static com.android.car.ui.core.CarUi.requireToolbar;
|
||||
|
||||
import android.car.drivingstate.CarUxRestrictions;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.car.settings.R;
|
||||
import com.android.car.settings.common.FragmentHost;
|
||||
import com.android.car.settings.common.UxRestrictionsProvider;
|
||||
import com.android.car.ui.toolbar.ToolbarController;
|
||||
|
||||
/**
|
||||
* Test activity used for testing {@code BaseFragment} instances.
|
||||
*/
|
||||
public class BaseTestActivity extends FragmentActivity implements FragmentHost,
|
||||
UxRestrictionsProvider {
|
||||
|
||||
private boolean mOnBackPressedFlag;
|
||||
private CarUxRestrictions mRestrictionInfo = new CarUxRestrictions.Builder(/* reqOpt= */ true,
|
||||
CarUxRestrictions.UX_RESTRICTIONS_BASELINE, /* timestamp= */ 0).build();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.car_setting_activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places fragment in place of fragment container.
|
||||
*
|
||||
* @param fragment Fragment to add to activity.
|
||||
*/
|
||||
@Override
|
||||
public void launchFragment(Fragment fragment) {
|
||||
if (fragment instanceof DialogFragment) {
|
||||
throw new IllegalArgumentException(
|
||||
"cannot launch dialogs with launchFragment() - use showDialog() instead");
|
||||
}
|
||||
String tag = Integer.toString(getSupportFragmentManager().getBackStackEntryCount());
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, fragment, tag)
|
||||
.addToBackStack(null)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showBlockingMessage() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToolbarController getToolbar() {
|
||||
return requireToolbar(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarUxRestrictions getCarUxRestrictions() {
|
||||
return mRestrictionInfo;
|
||||
}
|
||||
|
||||
public void setCarUxRestrictions(CarUxRestrictions restrictionInfo) {
|
||||
mRestrictionInfo = restrictionInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to catch onBackPressed invocations on the activity.
|
||||
*/
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
mOnBackPressedFlag = true;
|
||||
getSupportFragmentManager().popBackStackImmediate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a boolean flag indicating whether onBackPressed has been called.
|
||||
*
|
||||
* @return {@code true} if onBackPressed called, {@code false} otherwise.
|
||||
*/
|
||||
public boolean getOnBackPressedFlag() {
|
||||
return mOnBackPressedFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the boolean flag for onBackPressed by setting it to false.
|
||||
*/
|
||||
public void clearOnBackPressedFlag() {
|
||||
mOnBackPressedFlag = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goBack() {
|
||||
onBackPressed();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
/**
|
||||
* Helper methods for DialogFragment testing.
|
||||
*/
|
||||
public class DialogTestUtils {
|
||||
private DialogTestUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes onClick on the dialog's positive button.
|
||||
*/
|
||||
public static void clickPositiveButton(DialogFragment dialogFragment) {
|
||||
Button positiveButton = dialogFragment.getDialog().getWindow().findViewById(
|
||||
com.android.internal.R.id.button1);
|
||||
positiveButton.callOnClick();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes onClick on the dialog's negative button.
|
||||
*/
|
||||
public static void clickNegativeButton(DialogFragment dialogFragment) {
|
||||
Button negativeButton = dialogFragment.getDialog().getWindow().findViewById(
|
||||
com.android.internal.R.id.button2);
|
||||
negativeButton.callOnClick();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets dialog's title.
|
||||
*/
|
||||
public static String getTitle(DialogFragment dialogFragment) {
|
||||
TextView titleView = dialogFragment.getDialog().getWindow().findViewById(
|
||||
com.android.internal.R.id.alertTitle);
|
||||
return titleView.getText().toString();
|
||||
}
|
||||
|
||||
public static String getMessage(DialogFragment dialogFragment) {
|
||||
TextView messageView = dialogFragment.getDialog().getWindow().findViewById(
|
||||
com.android.internal.R.id.message);
|
||||
return messageView.getText().toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.car.settings.testutils;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.car.settings.R;
|
||||
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.android.controller.ComponentController;
|
||||
|
||||
/**
|
||||
* Version of FragmentController that can be used for {@link androidx.fragment.app.Fragment} until
|
||||
* upstream support is ready.
|
||||
*/
|
||||
public class FragmentController<F extends Fragment> extends
|
||||
ComponentController<FragmentController<F>, F> {
|
||||
|
||||
private final F mFragment;
|
||||
private final ActivityController<BaseTestActivity> mActivityController;
|
||||
|
||||
private FragmentController(F fragment) {
|
||||
super(fragment);
|
||||
mFragment = fragment;
|
||||
mActivityController = ActivityController.of(new BaseTestActivity());
|
||||
}
|
||||
|
||||
public static <F extends Fragment> FragmentController<F> of(F fragment) {
|
||||
return new FragmentController<>(fragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fragment after attaching it to an activity, calling its onCreate() through
|
||||
* onResume() lifecycle methods and making it visible.
|
||||
*/
|
||||
public F setup() {
|
||||
return create().start().resume().visible().get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the activity with {@link Bundle} and adds the fragment to it.
|
||||
*/
|
||||
public FragmentController<F> create(final Bundle bundle) {
|
||||
shadowMainLooper.runPaused(
|
||||
() -> mActivityController
|
||||
.create(bundle)
|
||||
.get()
|
||||
.getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.add(R.id.fragment_container, mFragment)
|
||||
.commitNow());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FragmentController<F> create() {
|
||||
return create(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FragmentController<F> destroy() {
|
||||
shadowMainLooper.runPaused(mActivityController::destroy);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentController<F> start() {
|
||||
shadowMainLooper.runPaused(mActivityController::start);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentController<F> resume() {
|
||||
shadowMainLooper.runPaused(mActivityController::resume);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentController<F> pause() {
|
||||
shadowMainLooper.runPaused(mActivityController::pause);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentController<F> stop() {
|
||||
shadowMainLooper.runPaused(mActivityController::stop);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FragmentController<F> visible() {
|
||||
shadowMainLooper.runPaused(mActivityController::visible);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AuthenticatorDescription;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(AccountManager.class)
|
||||
public class ShadowAccountManager extends org.robolectric.shadows.ShadowAccountManager {
|
||||
|
||||
private final Map<Integer, List<Account>> mAccountsAsUserMap = new ArrayMap<>();
|
||||
private final Map<Integer, List<AuthenticatorDescription>> mAuthenticatorAsUserMap =
|
||||
new ArrayMap<>();
|
||||
|
||||
@Implementation
|
||||
protected Account[] getAccountsAsUser(int userId) {
|
||||
if (mAccountsAsUserMap.containsKey(userId)) {
|
||||
return mAccountsAsUserMap.get(userId).toArray(new Account[]{});
|
||||
}
|
||||
return getAccounts();
|
||||
}
|
||||
|
||||
public void addAccountAsUser(int userId, Account account) {
|
||||
mAccountsAsUserMap.putIfAbsent(userId, new ArrayList<>());
|
||||
mAccountsAsUserMap.get(userId).add(account);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Account[] getAccountsByTypeAsUser(String type, UserHandle userHandle) {
|
||||
return getAccountsByType(type);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected AuthenticatorDescription[] getAuthenticatorTypesAsUser(int userId) {
|
||||
if (mAuthenticatorAsUserMap.containsKey(userId)) {
|
||||
return mAuthenticatorAsUserMap.get(userId).toArray(new AuthenticatorDescription[]{});
|
||||
}
|
||||
return getAuthenticatorTypes();
|
||||
}
|
||||
|
||||
public void addAuthenticatorAsUser(int userId, AuthenticatorDescription authenticator) {
|
||||
mAuthenticatorAsUserMap.putIfAbsent(userId, new ArrayList<>());
|
||||
mAuthenticatorAsUserMap.get(userId).add(authenticator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllAccounts() {
|
||||
super.removeAllAccounts();
|
||||
mAccountsAsUserMap.clear();
|
||||
mAuthenticatorAsUserMap.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 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.car.settings.testutils;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.pm.IPackageDataObserver;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(value = ActivityManager.class)
|
||||
public class ShadowActivityManager extends org.robolectric.shadows.ShadowActivityManager {
|
||||
private static final int DEFAULT_CURRENT_USER_ID = UserHandle.USER_SYSTEM;
|
||||
|
||||
private static boolean sIsApplicationUserDataCleared;
|
||||
private static int sCurrentUserId = DEFAULT_CURRENT_USER_ID;
|
||||
|
||||
private String mMostRecentlyStoppedPackage;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sIsApplicationUserDataCleared = false;
|
||||
sCurrentUserId = DEFAULT_CURRENT_USER_ID;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void forceStopPackage(String packageName) {
|
||||
mMostRecentlyStoppedPackage = packageName;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) {
|
||||
return sIsApplicationUserDataCleared;
|
||||
}
|
||||
|
||||
public String getMostRecentlyStoppedPackage() {
|
||||
return mMostRecentlyStoppedPackage;
|
||||
}
|
||||
|
||||
public static void setApplicationUserDataCleared(boolean applicationUserDataCleared) {
|
||||
sIsApplicationUserDataCleared = applicationUserDataCleared;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static int getCurrentUser() {
|
||||
return sCurrentUserId;
|
||||
}
|
||||
|
||||
public static void setCurrentUser(int userId) {
|
||||
sCurrentUserId = userId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 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.car.settings.testutils;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.AppOpsManager.OpEntry;
|
||||
import android.app.AppOpsManager.PackageOps;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Table;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Implements(value = AppOpsManager.class)
|
||||
public class ShadowAppOpsManager {
|
||||
|
||||
private Table<Integer, InternalKey, Integer> mOpToKeyToMode = HashBasedTable.create();
|
||||
|
||||
@Implementation
|
||||
protected void setMode(int code, int uid, String packageName, int mode) {
|
||||
InternalKey key = new InternalKey(uid, packageName);
|
||||
mOpToKeyToMode.put(code, key, mode);
|
||||
}
|
||||
|
||||
/** Convenience method to get the mode directly instead of wrapped in an op list. */
|
||||
public int getMode(int code, int uid, String packageName) {
|
||||
Integer mode = mOpToKeyToMode.get(code, new InternalKey(uid, packageName));
|
||||
return mode == null ? AppOpsManager.opToDefaultMode(code) : mode;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<PackageOps> getPackagesForOps(int[] ops) {
|
||||
if (ops == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
ImmutableList.Builder<PackageOps> result = new ImmutableList.Builder<>();
|
||||
for (int i = 0; i < ops.length; i++) {
|
||||
int op = ops[i];
|
||||
Map<InternalKey, Integer> keyToModeMap = mOpToKeyToMode.rowMap().get(op);
|
||||
if (keyToModeMap == null) {
|
||||
continue;
|
||||
}
|
||||
for (InternalKey key : keyToModeMap.keySet()) {
|
||||
Integer mode = keyToModeMap.get(key);
|
||||
if (mode == null) {
|
||||
mode = AppOpsManager.opToDefaultMode(op);
|
||||
}
|
||||
OpEntry opEntry = new OpEntry(op, mode, Collections.emptyMap());
|
||||
PackageOps packageOp = new PackageOps(key.mPackageName, key.mUid,
|
||||
Collections.singletonList(opEntry));
|
||||
result.add(packageOp);
|
||||
}
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
|
||||
private static class InternalKey {
|
||||
private int mUid;
|
||||
private String mPackageName;
|
||||
|
||||
InternalKey(int uid, String packageName) {
|
||||
mUid = uid;
|
||||
mPackageName = packageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof InternalKey) {
|
||||
InternalKey that = (InternalKey) obj;
|
||||
return mUid == that.mUid && mPackageName.equals(that.mPackageName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mUid, mPackageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.ApplicationPackageManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageDataObserver;
|
||||
import android.content.pm.ModuleInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** Shadow of ApplicationPackageManager that allows the getting of content providers per user. */
|
||||
@Implements(value = ApplicationPackageManager.class)
|
||||
public class ShadowApplicationPackageManager extends
|
||||
org.robolectric.shadows.ShadowApplicationPackageManager {
|
||||
|
||||
private static Resources sResources = null;
|
||||
private static PackageManager sPackageManager;
|
||||
|
||||
private final Map<Integer, String> mUserIdToDefaultBrowserMap = new HashMap<>();
|
||||
private final Map<String, ComponentName> mPkgToDefaultActivityMap = new HashMap<>();
|
||||
private final Map<String, IntentFilter> mPkgToDefaultActivityIntentFilterMap = new HashMap<>();
|
||||
private final Map<IntentFilter, ComponentName> mPreferredActivities = new LinkedHashMap<>();
|
||||
private final Map<Pair<String, Integer>, Integer> mPkgAndUserIdToIntentVerificationStatusMap =
|
||||
new HashMap<>();
|
||||
private List<ResolveInfo> mHomeActivities = Collections.emptyList();
|
||||
private ComponentName mDefaultHomeActivity;
|
||||
private String mPermissionControllerPackageName;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sResources = null;
|
||||
sPackageManager = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@NonNull
|
||||
protected List<ModuleInfo> getInstalledModules(@PackageManager.ModuleInfoFlags int flags) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Implementation
|
||||
protected ProviderInfo resolveContentProviderAsUser(String name, int flags,
|
||||
@UserIdInt int userId) {
|
||||
return resolveContentProvider(name, flags);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getPackageUidAsUser(String packageName, int flags, int userId)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer) {
|
||||
sPackageManager.deleteApplicationCacheFiles(packageName, observer);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Resources getResourcesForApplication(String appPackageName)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
return sResources;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
|
||||
return getInstalledApplications(flags);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
return getApplicationInfo(packageName, flags);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
|
||||
outActivities.addAll(mHomeActivities);
|
||||
return mDefaultHomeActivity;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected void clearPackagePreferredActivities(String packageName) {
|
||||
mPreferredActivities.clear();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
public int getPreferredActivities(List<IntentFilter> outFilters,
|
||||
List<ComponentName> outActivities, String packageName) {
|
||||
for (IntentFilter filter : mPreferredActivities.keySet()) {
|
||||
ComponentName name = mPreferredActivities.get(filter);
|
||||
// If packageName is null, match everything, else filter by packageName.
|
||||
if (packageName == null) {
|
||||
outFilters.add(filter);
|
||||
outActivities.add(name);
|
||||
} else if (name.getPackageName().equals(packageName)) {
|
||||
outFilters.add(filter);
|
||||
outActivities.add(name);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set,
|
||||
ComponentName activity) {
|
||||
mPreferredActivities.put(filter, activity);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected String getDefaultBrowserPackageNameAsUser(int userId) {
|
||||
return mUserIdToDefaultBrowserMap.getOrDefault(userId, null);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
|
||||
mUserIdToDefaultBrowserMap.put(userId, packageName);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected int getIntentVerificationStatusAsUser(String packageName, int userId) {
|
||||
Pair<String, Integer> key = new Pair<>(packageName, userId);
|
||||
return mPkgAndUserIdToIntentVerificationStatusMap.getOrDefault(key,
|
||||
INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected boolean updateIntentVerificationStatusAsUser(String packageName, int status,
|
||||
int userId) {
|
||||
Pair<String, Integer> key = new Pair<>(packageName, userId);
|
||||
mPkgAndUserIdToIntentVerificationStatusMap.put(key, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getPermissionControllerPackageName() {
|
||||
return mPermissionControllerPackageName;
|
||||
}
|
||||
|
||||
public void setPermissionControllerPackageName(String packageName) {
|
||||
mPermissionControllerPackageName = packageName;
|
||||
}
|
||||
|
||||
public void setHomeActivities(List<ResolveInfo> homeActivities) {
|
||||
mHomeActivities = homeActivities;
|
||||
}
|
||||
|
||||
public void setDefaultHomeActivity(ComponentName defaultHomeActivity) {
|
||||
mDefaultHomeActivity = defaultHomeActivity;
|
||||
}
|
||||
|
||||
public static void setResources(Resources resources) {
|
||||
sResources = resources;
|
||||
}
|
||||
|
||||
public static void setPackageManager(PackageManager packageManager) {
|
||||
sPackageManager = packageManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(ApplicationsState.class)
|
||||
public class ShadowApplicationsState {
|
||||
|
||||
private static ApplicationsState sApplicationsState;
|
||||
|
||||
public static void setInstance(ApplicationsState applicationsState) {
|
||||
sApplicationsState = applicationsState;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sApplicationsState = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static ApplicationsState getInstance(Application app) {
|
||||
return sApplicationsState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.service.autofill.AutofillServiceInfo;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(AutofillServiceInfo.class)
|
||||
public class ShadowAutofillServiceInfo {
|
||||
|
||||
private static String sSettingsActivity;
|
||||
|
||||
public void __constructor__(Context context, ServiceInfo si) {
|
||||
// Do nothing when constructed in code.
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sSettingsActivity = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getSettingsActivity() {
|
||||
return sSettingsActivity;
|
||||
}
|
||||
|
||||
public static void setSettingsActivity(String settingsActivity) {
|
||||
sSettingsActivity = settingsActivity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
|
||||
import static android.bluetooth.BluetoothAdapter.STATE_ON;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothStatusCodes;
|
||||
import android.os.ParcelUuid;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Implements(BluetoothAdapter.class)
|
||||
public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBluetoothAdapter {
|
||||
|
||||
private static int sResetCalledCount = 0;
|
||||
private String mName;
|
||||
private int mScanMode;
|
||||
|
||||
public static boolean verifyFactoryResetCalled(int numTimes) {
|
||||
return sResetCalledCount == numTimes;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean factoryReset() {
|
||||
sResetCalledCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static synchronized BluetoothAdapter getDefaultAdapter() {
|
||||
return (BluetoothAdapter) ShadowApplication.getInstance().getBluetoothAdapter();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected ParcelUuid[] getUuids() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean setName(String name) {
|
||||
if (getState() != STATE_ON) {
|
||||
return false;
|
||||
}
|
||||
mName = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getScanMode() {
|
||||
if (getState() != STATE_ON) {
|
||||
return SCAN_MODE_NONE;
|
||||
}
|
||||
return mScanMode;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Object setScanMode(int scanMode) {
|
||||
if (getState() != STATE_ON) {
|
||||
return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
|
||||
}
|
||||
mScanMode = scanMode;
|
||||
return BluetoothStatusCodes.SUCCESS;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<Integer> getSupportedProfiles() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sResetCalledCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.car.settings.testutils;
|
||||
|
||||
import android.bluetooth.BluetoothPan;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(BluetoothPan.class)
|
||||
public class ShadowBluetoothPan {
|
||||
@Implementation
|
||||
public void __constructor__(Context context, BluetoothProfile.ServiceListener l) {
|
||||
// Do nothing. Implemented to avoid NullPointerException in BluetoothPan.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import android.car.Car;
|
||||
import android.car.CarNotConnectedException;
|
||||
import android.content.Context;
|
||||
import android.content.ServiceConnection;
|
||||
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
/**
|
||||
* Shadow class for {@link Car}. Components in car support library expects
|
||||
* this class to be available at run time.
|
||||
*/
|
||||
@Implements(Car.class)
|
||||
public class ShadowCar {
|
||||
|
||||
private static Car sMockCar = mock(Car.class);
|
||||
private static boolean sIsConnected;
|
||||
private static String sServiceName;
|
||||
private static Object sCarManager;
|
||||
|
||||
/**
|
||||
* Returns a mocked version of a {@link Car} object.
|
||||
*/
|
||||
@Implementation
|
||||
protected static Car createCar(Context context, ServiceConnection serviceConnection) {
|
||||
if (serviceConnection != null) {
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
serviceConnection.onServiceConnected(null, null);
|
||||
return null;
|
||||
}).when(sMockCar).connect();
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
serviceConnection.onServiceDisconnected(null);
|
||||
return null;
|
||||
}).when(sMockCar).disconnect();
|
||||
}
|
||||
doReturn(sIsConnected).when(sMockCar).isConnected();
|
||||
if (sServiceName != null) {
|
||||
try {
|
||||
doReturn(sCarManager).when(sMockCar).getCarManager(sServiceName);
|
||||
} catch (CarNotConnectedException e) {
|
||||
// do nothing, have to do this because compiler doesn't understand mock can't throw
|
||||
// exception.
|
||||
}
|
||||
}
|
||||
return sMockCar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mocked version of a {@link Car} object.
|
||||
*/
|
||||
@Implementation
|
||||
protected static Car createCar(Context context) {
|
||||
doReturn(sIsConnected).when(sMockCar).isConnected();
|
||||
if (sServiceName != null) {
|
||||
try {
|
||||
doReturn(sCarManager).when(sMockCar).getCarManager(sServiceName);
|
||||
} catch (CarNotConnectedException e) {
|
||||
// do nothing, have to do this because compiler doesn't understand mock can't throw
|
||||
// exception.
|
||||
}
|
||||
}
|
||||
return sMockCar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the manager returned by {@link Car#getCarManager(String)}.
|
||||
*
|
||||
* @param serviceName the name for the service request that should return this car manager.
|
||||
* @param carManager the object returned by a call with this service.
|
||||
*/
|
||||
public static void setCarManager(String serviceName, Object carManager) {
|
||||
sServiceName = serviceName;
|
||||
sCarManager = carManager;
|
||||
try {
|
||||
doReturn(carManager).when(sMockCar).getCarManager(serviceName);
|
||||
} catch (CarNotConnectedException e) {
|
||||
// do nothing, have to do this because compiler doesn't understand mock can't throw e.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the shadow state, note this will not remove stubbed behavior on references to older
|
||||
* calls to {@link #createCar(Context, ServiceConnection)}.
|
||||
*/
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sMockCar = mock(Car.class);
|
||||
sServiceName = null;
|
||||
sCarManager = null;
|
||||
sIsConnected = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import com.android.car.settings.units.CarUnitsManager;
|
||||
import com.android.car.settings.units.Unit;
|
||||
import com.android.car.settings.units.UnitsMap;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Shadow class for {@link CarUnitsManager}.
|
||||
*/
|
||||
@Implements(CarUnitsManager.class)
|
||||
public class ShadowCarUnitsManager {
|
||||
private static boolean sConnected = false;
|
||||
private static CarUnitsManager.OnCarServiceListener sListener;
|
||||
private static HashMap<Integer, Unit[]> sSupportedUnits = new HashMap<>();
|
||||
private static HashMap<Integer, Unit> sUnitsBeingUsed = new HashMap<>();
|
||||
|
||||
@Implementation
|
||||
protected void connect() {
|
||||
sConnected = true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void disconnect() {
|
||||
sConnected = false;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static Unit[] getUnitsSupportedByProperty(int propertyId) {
|
||||
return sSupportedUnits.get(propertyId);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static Unit getUnitUsedByProperty(int propertyId) {
|
||||
return sUnitsBeingUsed.get(propertyId);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static void setUnitUsedByProperty(int propertyId, int unitId) {
|
||||
sUnitsBeingUsed.put(propertyId, UnitsMap.MAP.get(unitId));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static void registerCarServiceListener(
|
||||
CarUnitsManager.OnCarServiceListener listener) {
|
||||
sListener = listener;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static void unregisterCarServiceListener() {
|
||||
sListener = null;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sConnected = false;
|
||||
sListener = null;
|
||||
sSupportedUnits = new HashMap<>();
|
||||
sUnitsBeingUsed = new HashMap<>();
|
||||
}
|
||||
|
||||
public static void setUnitsSupportedByProperty(int propertyId, Unit[] units) {
|
||||
sSupportedUnits.put(propertyId, units);
|
||||
}
|
||||
|
||||
public static boolean isConnected() {
|
||||
return sConnected;
|
||||
}
|
||||
|
||||
public static CarUnitsManager.OnCarServiceListener getListener() {
|
||||
return sListener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.SoftApConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
|
||||
import com.android.car.settings.wifi.CarWifiManager;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** TODO(b/148971715): Refactor all methods to run without relying on sInstance. */
|
||||
@Implements(CarWifiManager.class)
|
||||
public class ShadowCarWifiManager {
|
||||
|
||||
public static final int STATE_UNKNOWN = -1;
|
||||
public static final int STATE_STARTED = 0;
|
||||
public static final int STATE_STOPPED = 1;
|
||||
public static final int STATE_DESTROYED = 2;
|
||||
|
||||
private static CarWifiManager sInstance;
|
||||
private static int sCurrentState = STATE_UNKNOWN;
|
||||
private static SoftApConfiguration sSoftApConfiguration =
|
||||
new SoftApConfiguration.Builder().build();
|
||||
private static boolean sIs5GhzBandSupported = true;
|
||||
private static int sWifiState = WifiManager.WIFI_STATE_UNKNOWN;
|
||||
|
||||
public static void setInstance(CarWifiManager wifiManager) {
|
||||
sInstance = wifiManager;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sInstance = null;
|
||||
sSoftApConfiguration = new SoftApConfiguration.Builder().build();
|
||||
sCurrentState = STATE_UNKNOWN;
|
||||
sIs5GhzBandSupported = true;
|
||||
sWifiState = WifiManager.WIFI_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void __constructor__(Context context) {
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void start() {
|
||||
sCurrentState = STATE_STARTED;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void stop() {
|
||||
sCurrentState = STATE_STOPPED;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void destroy() {
|
||||
sCurrentState = STATE_DESTROYED;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void setSoftApConfig(SoftApConfiguration config) {
|
||||
sSoftApConfiguration = config;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public SoftApConfiguration getSoftApConfig() {
|
||||
return sSoftApConfiguration;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isWifiEnabled() {
|
||||
return sInstance.isWifiEnabled();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public int getWifiState() {
|
||||
return sWifiState;
|
||||
}
|
||||
|
||||
public static void setWifiState(int wifiState) {
|
||||
sWifiState = wifiState;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isWifiApEnabled() {
|
||||
return sInstance.isWifiApEnabled();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public List<WifiEntry> getAllWifiEntries() {
|
||||
return sInstance.getAllWifiEntries();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public List<WifiEntry> getSavedWifiEntries() {
|
||||
return sInstance.getSavedWifiEntries();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getCountryCode() {
|
||||
return "1";
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean is5GhzBandSupported() {
|
||||
return sIs5GhzBandSupported;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean addListener(CarWifiManager.Listener listener) {
|
||||
return sInstance.addListener(listener);
|
||||
}
|
||||
|
||||
public static void setIs5GhzBandSupported(boolean supported) {
|
||||
sIs5GhzBandSupported = supported;
|
||||
}
|
||||
|
||||
public static int getCurrentState() {
|
||||
return sCurrentState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(CarrierConfigManager.class)
|
||||
public class ShadowCarrierConfigManager {
|
||||
|
||||
private SparseArray<PersistableBundle> mBundles = new SparseArray<>();
|
||||
|
||||
@Implementation
|
||||
protected PersistableBundle getConfigForSubId(int subId) {
|
||||
return mBundles.get(subId);
|
||||
}
|
||||
|
||||
public void setConfigForSubId(int subId, PersistableBundle config) {
|
||||
mBundles.put(subId, config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Handler;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(ConnectivityManager.class)
|
||||
public class ShadowConnectivityManager extends org.robolectric.shadows.ShadowConnectivityManager {
|
||||
|
||||
private static int sResetCalledCount = 0;
|
||||
|
||||
private final Map<Network, NetworkCapabilities> mCapabilitiesMap = new HashMap<>();
|
||||
|
||||
private int mStartTetheringCalledCount = 0;
|
||||
private int mStopTetheringCalledCount = 0;
|
||||
private int mTetheringType;
|
||||
|
||||
public static boolean verifyFactoryResetCalled(int numTimes) {
|
||||
return sResetCalledCount == numTimes;
|
||||
}
|
||||
|
||||
public boolean verifyStartTetheringCalled(int numTimes) {
|
||||
return mStartTetheringCalledCount == numTimes;
|
||||
}
|
||||
|
||||
public boolean verifyStopTetheringCalled(int numTimes) {
|
||||
return mStopTetheringCalledCount == numTimes;
|
||||
}
|
||||
|
||||
public int getTetheringType() {
|
||||
return mTetheringType;
|
||||
}
|
||||
|
||||
public void addNetworkCapabilities(Network network, NetworkCapabilities capabilities) {
|
||||
super.addNetwork(network, mock(NetworkInfo.class));
|
||||
mCapabilitiesMap.put(network, capabilities);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected NetworkCapabilities getNetworkCapabilities(Network network) {
|
||||
return mCapabilitiesMap.get(network);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void startTethering(int type, boolean showProvisioningUi,
|
||||
final ConnectivityManager.OnStartTetheringCallback callback, Handler handler) {
|
||||
mTetheringType = type;
|
||||
mStartTetheringCalledCount++;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void stopTethering(int type) {
|
||||
mTetheringType = type;
|
||||
mStopTetheringCalledCount++;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void factoryReset() {
|
||||
sResetCalledCount++;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sResetCalledCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.SyncAdapterType;
|
||||
import android.content.SyncInfo;
|
||||
import android.content.SyncStatusInfo;
|
||||
import android.content.SyncStatusObserver;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Derived from {@link com.android.settings.testutils.shadow.ShadowContentResolver}
|
||||
*
|
||||
* <p>Needed for many account-related tests because the default ShadowContentResolver does not
|
||||
* include an implementation of getSyncAdapterTypesAsUser, which is used by {@link
|
||||
* com.android.settingslib.accounts.AuthenticatorHelper#buildAccountTypeToAuthoritiesMap}.
|
||||
*/
|
||||
@Implements(ContentResolver.class)
|
||||
public class ShadowContentResolver extends org.robolectric.shadows.ShadowContentResolver {
|
||||
private static final int SYNCABLE = 1;
|
||||
|
||||
private static SyncAdapterType[] sSyncAdapterTypes = new SyncAdapterType[0];
|
||||
private static Map<String, Integer> sSyncable = new HashMap<>();
|
||||
private static Map<String, Boolean> sSyncAutomatically = new HashMap<>();
|
||||
private static Map<Integer, Boolean> sMasterSyncAutomatically = new HashMap<>();
|
||||
private static Map<String, SyncStatusInfo> sSyncStatus = new HashMap<>();
|
||||
private static List<SyncInfo> sSyncs = new ArrayList<>();
|
||||
private static SyncListener sSyncListener;
|
||||
private static SyncStatusObserver sStatusObserver;
|
||||
|
||||
@Implementation
|
||||
protected static SyncAdapterType[] getSyncAdapterTypesAsUser(int userId) {
|
||||
return sSyncAdapterTypes;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static int getIsSyncableAsUser(Account account, String authority, int userId) {
|
||||
return sSyncable.getOrDefault(authority, SYNCABLE);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean getSyncAutomaticallyAsUser(Account account, String authority,
|
||||
int userId) {
|
||||
return sSyncAutomatically.getOrDefault(authority, true);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean getMasterSyncAutomaticallyAsUser(int userId) {
|
||||
return sMasterSyncAutomatically.getOrDefault(userId, true);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static List<SyncInfo> getCurrentSyncsAsUser(@UserIdInt int userId) {
|
||||
return sSyncs;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static SyncStatusInfo getSyncStatusAsUser(Account account, String authority,
|
||||
@UserIdInt int userId) {
|
||||
return sSyncStatus.get(authority);
|
||||
}
|
||||
|
||||
public static void setSyncAdapterTypes(SyncAdapterType[] syncAdapterTypes) {
|
||||
sSyncAdapterTypes = syncAdapterTypes;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static void setIsSyncable(Account account, String authority, int syncable) {
|
||||
sSyncable.put(authority, syncable);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static void setSyncAutomaticallyAsUser(Account account, String authority,
|
||||
boolean sync, @UserIdInt int userId) {
|
||||
sSyncAutomatically.put(authority, sync);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static void setMasterSyncAutomaticallyAsUser(boolean sync, @UserIdInt int userId) {
|
||||
sMasterSyncAutomatically.put(userId, sync);
|
||||
}
|
||||
|
||||
public static void setCurrentSyncs(List<SyncInfo> syncs) {
|
||||
sSyncs = syncs;
|
||||
}
|
||||
|
||||
public static void setSyncStatus(Account account, String authority, SyncStatusInfo status) {
|
||||
sSyncStatus.put(authority, status);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static void cancelSyncAsUser(Account account, String authority, @UserIdInt int userId) {
|
||||
if (sSyncListener != null) {
|
||||
sSyncListener.onSyncCanceled(account, authority, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static void requestSyncAsUser(Account account, String authority, @UserIdInt int userId,
|
||||
Bundle extras) {
|
||||
if (sSyncListener != null) {
|
||||
sSyncListener.onSyncRequested(account, authority, userId, extras);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setSyncListener(SyncListener syncListener) {
|
||||
sSyncListener = syncListener;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static Object addStatusChangeListener(int mask, SyncStatusObserver callback) {
|
||||
sStatusObserver = callback;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static void removeStatusChangeListener(Object handle) {
|
||||
sStatusObserver = null;
|
||||
}
|
||||
|
||||
public static SyncStatusObserver getStatusChangeListener() {
|
||||
return sStatusObserver;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
org.robolectric.shadows.ShadowContentResolver.reset();
|
||||
sSyncable.clear();
|
||||
sSyncAutomatically.clear();
|
||||
sMasterSyncAutomatically.clear();
|
||||
sSyncAdapterTypes = new SyncAdapterType[0];
|
||||
sSyncStatus.clear();
|
||||
sSyncs = new ArrayList<>();
|
||||
sSyncListener = null;
|
||||
sStatusObserver = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener interface that can be used to verify calls to {@link #cancelSyncAsUser} and {@link
|
||||
* #requestSyncAsUser}
|
||||
*/
|
||||
public interface SyncListener {
|
||||
void onSyncCanceled(Account account, String authority, @UserIdInt int userId);
|
||||
|
||||
void onSyncRequested(Account account, String authority, @UserIdInt int userId,
|
||||
Bundle extras);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.net.NetworkTemplate;
|
||||
|
||||
import com.android.settingslib.net.DataUsageController;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(DataUsageController.class)
|
||||
public class ShadowDataUsageController {
|
||||
|
||||
private static DataUsageController sInstance;
|
||||
|
||||
public static void setInstance(DataUsageController dataUsageController) {
|
||||
sInstance = dataUsageController;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected DataUsageController.DataUsageInfo getDataUsageInfo(NetworkTemplate template) {
|
||||
return sInstance.getDataUsageInfo(template);
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sInstance = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telecom.DefaultDialerManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(DefaultDialerManager.class)
|
||||
public class ShadowDefaultDialerManager {
|
||||
|
||||
private static String sDefaultDialerPackage;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sDefaultDialerPackage = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static String getDefaultDialerApplication(Context context) {
|
||||
return sDefaultDialerPackage;
|
||||
}
|
||||
|
||||
public static void setDefaultDialerApplication(String defaultDialerPackage) {
|
||||
sDefaultDialerPackage = defaultDialerPackage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Implements(value = DevicePolicyManager.class)
|
||||
public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDevicePolicyManager {
|
||||
@Nullable
|
||||
private static List<String> sPermittedInputMethods;
|
||||
|
||||
private Set<String> mActiveAdminsPackages = new ArraySet<>();
|
||||
private boolean mIsInstallInQueue;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sPermittedInputMethods = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Nullable
|
||||
protected List<String> getPermittedInputMethodsForCurrentUser() {
|
||||
return sPermittedInputMethods;
|
||||
}
|
||||
|
||||
public static void setPermittedInputMethodsForCurrentUser(@Nullable List<String> inputMethods) {
|
||||
sPermittedInputMethods = inputMethods;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean packageHasActiveAdmins(String packageName) {
|
||||
return mActiveAdminsPackages.contains(packageName);
|
||||
}
|
||||
|
||||
public void setPackageHasActiveAdmins(String packageName, boolean hasActiveAdmins) {
|
||||
if (hasActiveAdmins) {
|
||||
mActiveAdminsPackages.add(packageName);
|
||||
} else {
|
||||
mActiveAdminsPackages.remove(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isUninstallInQueue(String packageName) {
|
||||
return mIsInstallInQueue;
|
||||
}
|
||||
|
||||
public void setIsUninstallInQueue(boolean isUninstallInQueue) {
|
||||
mIsInstallInQueue = isUninstallInQueue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.hardware.usb.IUsbManager;
|
||||
import android.os.IBinder;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(value = IUsbManager.Stub.class)
|
||||
public class ShadowIUsbManager {
|
||||
|
||||
private static IUsbManager sInstance;
|
||||
|
||||
public static void setInstance(IUsbManager instance) {
|
||||
sInstance = instance;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static IUsbManager asInterface(IBinder obj) {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sInstance = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 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.car.settings.testutils;
|
||||
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.IconDrawableFactory;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(value = IconDrawableFactory.class)
|
||||
public class ShadowIconDrawableFactory {
|
||||
|
||||
@Implementation
|
||||
protected Drawable getBadgedIcon(ApplicationInfo appInfo) {
|
||||
return new ColorDrawable(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.provider.Settings;
|
||||
import android.view.inputmethod.InputMethodInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.car.settings.inputmethod.InputMethodUtil;
|
||||
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Implements(value = InputMethodManager.class)
|
||||
public class ShadowInputMethodManager extends org.robolectric.shadows.ShadowInputMethodManager {
|
||||
private static List<InputMethodSubtype> sInputMethodSubtypes = new ArrayList<>();
|
||||
private static List<InputMethodInfo> sInputMethodList = new ArrayList<>();
|
||||
private static Map<String, InputMethodInfo> sInputMethodMap = new HashMap<>();
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sInputMethodSubtypes.clear();
|
||||
sInputMethodList.clear();
|
||||
sInputMethodMap.clear();
|
||||
org.robolectric.shadows.ShadowInputMethodManager.reset();
|
||||
}
|
||||
|
||||
public static void setEnabledInputMethodSubtypeList(List<InputMethodSubtype> list) {
|
||||
sInputMethodSubtypes = list;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
|
||||
boolean allowsImplicitlySelectedSubtypes) {
|
||||
return sInputMethodSubtypes;
|
||||
}
|
||||
|
||||
public static void setEnabledInputMethodList(@Nullable List<InputMethodInfo> list) {
|
||||
if (list == null || list.size() == 0) {
|
||||
Settings.Secure.putString(RuntimeEnvironment.application.getContentResolver(),
|
||||
Settings.Secure.ENABLED_INPUT_METHODS, "");
|
||||
return;
|
||||
}
|
||||
|
||||
String concatenatedInputMethodIds = createInputMethodIdString(list.stream().map(
|
||||
imi -> imi.getId()).collect(Collectors.toList()).toArray(new String[list.size()]));
|
||||
Settings.Secure.putString(RuntimeEnvironment.application.getContentResolver(),
|
||||
Settings.Secure.ENABLED_INPUT_METHODS, concatenatedInputMethodIds);
|
||||
addInputMethodInfosToMap(list);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<InputMethodInfo> getEnabledInputMethodList() {
|
||||
List<InputMethodInfo> enabledInputMethodList = new ArrayList<>();
|
||||
|
||||
String inputMethodIdString = Settings.Secure.getString(
|
||||
RuntimeEnvironment.application.getContentResolver(),
|
||||
Settings.Secure.ENABLED_INPUT_METHODS);
|
||||
if (inputMethodIdString == null || inputMethodIdString.isEmpty()) {
|
||||
return enabledInputMethodList;
|
||||
}
|
||||
|
||||
InputMethodUtil.sInputMethodSplitter.setString(inputMethodIdString);
|
||||
while (InputMethodUtil.sInputMethodSplitter.hasNext()) {
|
||||
enabledInputMethodList.add(sInputMethodMap.get(InputMethodUtil.sInputMethodSplitter
|
||||
.next()));
|
||||
}
|
||||
return enabledInputMethodList;
|
||||
}
|
||||
|
||||
public void setInputMethodList(List<InputMethodInfo> inputMethodInfos) {
|
||||
sInputMethodList = inputMethodInfos;
|
||||
if (inputMethodInfos == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
addInputMethodInfosToMap(inputMethodInfos);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<InputMethodInfo> getInputMethodList() {
|
||||
return sInputMethodList;
|
||||
}
|
||||
|
||||
private static String createInputMethodIdString(String... ids) {
|
||||
int size = ids == null ? 0 : ids.length;
|
||||
|
||||
if (size == 1) {
|
||||
return ids[0];
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
builder.append(ids[i]);
|
||||
if (i != size - 1) {
|
||||
builder.append(InputMethodUtil.INPUT_METHOD_DELIMITER);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static void addInputMethodInfosToMap(List<InputMethodInfo> inputMethodInfos) {
|
||||
if (sInputMethodMap == null || sInputMethodMap.size() == 0) {
|
||||
sInputMethodMap = inputMethodInfos.stream().collect(Collectors.toMap(
|
||||
InputMethodInfo::getId, imi -> imi));
|
||||
return;
|
||||
}
|
||||
|
||||
inputMethodInfos.forEach(imi -> {
|
||||
sInputMethodMap.put(imi.getId(), imi);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(LocalBluetoothAdapter.class)
|
||||
public class ShadowLocalBluetoothAdapter {
|
||||
|
||||
private int mState = BluetoothAdapter.STATE_OFF;
|
||||
private boolean mIsBluetoothEnabled = true;
|
||||
private int mScanMode = BluetoothAdapter.SCAN_MODE_NONE;
|
||||
|
||||
@Implementation
|
||||
protected boolean isEnabled() {
|
||||
return mIsBluetoothEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean enable() {
|
||||
mIsBluetoothEnabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean disable() {
|
||||
mIsBluetoothEnabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getScanMode() {
|
||||
return mScanMode;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void setScanMode(int mode) {
|
||||
mScanMode = mode;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean setScanMode(int mode, int duration) {
|
||||
mScanMode = mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
public void setState(int state) {
|
||||
mState = state;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
import org.robolectric.util.ReflectionHelpers.ClassParameter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Implements(LocalBroadcastManager.class)
|
||||
public class ShadowLocalBroadcastManager {
|
||||
private static List<Intent> sSentBroadcastIntents = new ArrayList<>();
|
||||
private static List<Wrapper> sRegisteredReceivers = new ArrayList<>();
|
||||
|
||||
@Implementation
|
||||
public static LocalBroadcastManager getInstance(final Context context) {
|
||||
return ShadowApplication.getInstance().getSingleton(LocalBroadcastManager.class,
|
||||
() -> ReflectionHelpers.callConstructor(LocalBroadcastManager.class,
|
||||
ClassParameter.from(Context.class, context)));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
|
||||
sRegisteredReceivers.add(new Wrapper(receiver, filter));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void unregisterReceiver(BroadcastReceiver receiver) {
|
||||
Iterator<Wrapper> iterator = sRegisteredReceivers.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Wrapper wrapper = iterator.next();
|
||||
if (wrapper.getBroadcastReceiver() == receiver) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean sendBroadcast(Intent intent) {
|
||||
boolean sent = false;
|
||||
sSentBroadcastIntents.add(intent);
|
||||
List<Wrapper> copy = new ArrayList<>(sRegisteredReceivers);
|
||||
for (Wrapper wrapper : copy) {
|
||||
if (wrapper.getIntentFilter().matchAction(intent.getAction())) {
|
||||
int match = wrapper.getIntentFilter().matchData(intent.getType(),
|
||||
intent.getScheme(), intent.getData());
|
||||
if (match != IntentFilter.NO_MATCH_DATA && match != IntentFilter.NO_MATCH_TYPE) {
|
||||
sent = true;
|
||||
final BroadcastReceiver receiver = wrapper.getBroadcastReceiver();
|
||||
final Intent broadcastIntent = intent;
|
||||
Robolectric.getForegroundThreadScheduler().post(
|
||||
(Runnable) () -> receiver.onReceive(RuntimeEnvironment.application,
|
||||
broadcastIntent));
|
||||
}
|
||||
}
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sSentBroadcastIntents.clear();
|
||||
sRegisteredReceivers.clear();
|
||||
}
|
||||
|
||||
public static List<Intent> getSentBroadcastIntents() {
|
||||
return sSentBroadcastIntents;
|
||||
}
|
||||
|
||||
public static List<Wrapper> getRegisteredBroadcastReceivers() {
|
||||
return sRegisteredReceivers;
|
||||
}
|
||||
|
||||
public static class Wrapper {
|
||||
private final BroadcastReceiver mBroadcastReceiver;
|
||||
private final IntentFilter mIntentFilter;
|
||||
|
||||
public Wrapper(BroadcastReceiver broadcastReceiver, IntentFilter intentFilter) {
|
||||
this.mBroadcastReceiver = broadcastReceiver;
|
||||
this.mIntentFilter = intentFilter;
|
||||
}
|
||||
|
||||
public BroadcastReceiver getBroadcastReceiver() {
|
||||
return mBroadcastReceiver;
|
||||
}
|
||||
|
||||
public IntentFilter getIntentFilter() {
|
||||
return mIntentFilter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.internal.app.LocaleStore;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Implements(LocaleStore.class)
|
||||
public class ShadowLocaleStore {
|
||||
|
||||
private static Map<LocaleStore.LocaleInfo, Set<LocaleStore.LocaleInfo>>
|
||||
sLocaleInfoRelationships = new HashMap<>();
|
||||
|
||||
public static void addLocaleRelationship(Locale parent, Locale child) {
|
||||
LocaleStore.LocaleInfo parentInfo = LocaleStore.getLocaleInfo(parent);
|
||||
LocaleStore.LocaleInfo childInfo = LocaleStore.getLocaleInfo(child);
|
||||
Set<LocaleStore.LocaleInfo> set = sLocaleInfoRelationships.getOrDefault(parentInfo,
|
||||
new HashSet<>());
|
||||
set.add(childInfo);
|
||||
sLocaleInfoRelationships.put(parentInfo, set);
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sLocaleInfoRelationships.clear();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static Set<LocaleStore.LocaleInfo> getLevelLocales(Context context,
|
||||
Set<String> ignorables, LocaleStore.LocaleInfo parent, boolean translatedOnly) {
|
||||
if (parent != null) {
|
||||
return sLocaleInfoRelationships.getOrDefault(parent, new HashSet<>());
|
||||
} else {
|
||||
return sLocaleInfoRelationships.keySet();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.location.LocationManager;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(value = LocationManager.class)
|
||||
public class ShadowLocationManager {
|
||||
|
||||
@Implementation
|
||||
protected void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
|
||||
int newMode = enabled
|
||||
? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY
|
||||
: Settings.Secure.LOCATION_MODE_OFF;
|
||||
|
||||
Settings.Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE, newMode, userHandle.getIdentifier());
|
||||
RuntimeEnvironment.application.sendBroadcast(new Intent(
|
||||
LocationManager.MODE_CHANGED_ACTION));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isLocationEnabled() {
|
||||
return Settings.Secure.getInt(RuntimeEnvironment.application.getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF)
|
||||
!= Settings.Secure.LOCATION_MODE_OFF;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
/**
|
||||
* Shadow for LockPatternUtils.
|
||||
*/
|
||||
@Implements(LockPatternUtils.class)
|
||||
public class ShadowLockPatternUtils {
|
||||
|
||||
public static final int NO_USER = -1;
|
||||
|
||||
private static int sPasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
private static byte[] sSavedPassword;
|
||||
private static byte[] sSavedPattern;
|
||||
private static LockscreenCredential sClearLockCredential;
|
||||
private static int sClearLockUser = NO_USER;
|
||||
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sPasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
sSavedPassword = null;
|
||||
sSavedPattern = null;
|
||||
sClearLockCredential = null;
|
||||
sClearLockUser = NO_USER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current password quality that is returned by
|
||||
* {@link LockPatternUtils#getKeyguardStoredPasswordQuality}.
|
||||
*/
|
||||
public static void setPasswordQuality(int passwordQuality) {
|
||||
sPasswordQuality = passwordQuality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password saved by a call to {@link LockPatternUtils#saveLockPassword}.
|
||||
*/
|
||||
public static byte[] getSavedPassword() {
|
||||
return sSavedPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the saved credential passed in to clear the lock, null if it has not been cleared.
|
||||
*/
|
||||
public static LockscreenCredential getClearLockCredential() {
|
||||
return sClearLockCredential;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user passed in to clear the lock, {@link #NO_USER} if it has not been cleared.
|
||||
*/
|
||||
public static int getClearLockUser() {
|
||||
return sClearLockUser;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the pattern saved by a call to {@link LockPatternUtils#saveLockPattern}.
|
||||
*/
|
||||
public static byte[] getSavedPattern() {
|
||||
return sSavedPattern;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getKeyguardStoredPasswordQuality(int userHandle) {
|
||||
return sPasswordQuality;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean setLockCredential(LockscreenCredential newCredential,
|
||||
LockscreenCredential savedCredential, int userId) {
|
||||
if (newCredential.isPassword() || newCredential.isPin()) {
|
||||
sSavedPassword = newCredential.duplicate().getCredential();
|
||||
} else if (newCredential.isPattern()) {
|
||||
sSavedPattern = newCredential.duplicate().getCredential();
|
||||
} else if (newCredential.isNone()) {
|
||||
sClearLockCredential = savedCredential.duplicate();
|
||||
sClearLockUser = userId;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.car.settings.testutils;
|
||||
|
||||
import android.net.NetworkPolicy;
|
||||
import android.net.NetworkTemplate;
|
||||
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(NetworkPolicyEditor.class)
|
||||
public class ShadowNetworkPolicyEditor {
|
||||
|
||||
private static NetworkPolicy sNetworkPolicy;
|
||||
|
||||
@Implementation
|
||||
public NetworkPolicy getPolicy(NetworkTemplate template) {
|
||||
return sNetworkPolicy;
|
||||
}
|
||||
|
||||
public static void setNetworkPolicy(NetworkPolicy networkPolicy) {
|
||||
sNetworkPolicy = networkPolicy;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sNetworkPolicy = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.NetworkPolicy;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(NetworkPolicyManager.class)
|
||||
public class ShadowNetworkPolicyManager {
|
||||
|
||||
private static NetworkPolicyManager sNetworkPolicyManager;
|
||||
private static Iterator<Pair<ZonedDateTime, ZonedDateTime>> sCycleIterator;
|
||||
private static Map<String, Integer> sResetCalledForSubscriberCount = new HashMap<>();
|
||||
|
||||
public static boolean verifyFactoryResetCalled(String subscriber, int numTimes) {
|
||||
if (!sResetCalledForSubscriberCount.containsKey(subscriber)) return false;
|
||||
return sResetCalledForSubscriberCount.get(subscriber) == numTimes;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void factoryReset(String subscriber) {
|
||||
sResetCalledForSubscriberCount.put(subscriber,
|
||||
sResetCalledForSubscriberCount.getOrDefault(subscriber, 0) + 1);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int[] getUidsWithPolicy(int policy) {
|
||||
return sNetworkPolicyManager == null ? new int[0] : sNetworkPolicyManager
|
||||
.getUidsWithPolicy(policy);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(
|
||||
NetworkPolicy policy) {
|
||||
return sCycleIterator;
|
||||
}
|
||||
|
||||
public static void setCycleIterator(
|
||||
Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator) {
|
||||
sCycleIterator = cycleIterator;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static NetworkPolicyManager from(Context context) {
|
||||
return sNetworkPolicyManager;
|
||||
}
|
||||
|
||||
public static void setNetworkPolicyManager(NetworkPolicyManager networkPolicyManager) {
|
||||
sNetworkPolicyManager = networkPolicyManager;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sResetCalledForSubscriberCount.clear();
|
||||
sCycleIterator = null;
|
||||
sNetworkPolicyManager = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.permission.PermissionControllerManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A RuntimePermissionPresenter that changes nothing and <u>never returns callbacks</u>.
|
||||
*/
|
||||
@Implements(PermissionControllerManager.class)
|
||||
public class ShadowPermissionControllerManager {
|
||||
@Implementation
|
||||
protected void __constructor__(Context context, @NonNull Handler handler) {
|
||||
// no nothing, everything is shadowed
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void getAppPermissions(String packageName,
|
||||
PermissionControllerManager.OnGetAppPermissionResultCallback callback,
|
||||
Handler handler) {
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void revokeRuntimePermission(String packageName, String permissionName) {
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void countPermissionApps(List<String> permissionNames, boolean countOnlyGranted,
|
||||
boolean countSystem,
|
||||
PermissionControllerManager.OnCountPermissionAppsResultCallback callback,
|
||||
Handler handler) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.RecoverySystem;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(RecoverySystem.class)
|
||||
public class ShadowRecoverySystem {
|
||||
|
||||
private static int sWipeEuiccDataCalledCount = 0;
|
||||
|
||||
public static boolean verifyWipeEuiccDataCalled(int numTimes) {
|
||||
return sWipeEuiccDataCalledCount == numTimes;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean wipeEuiccData(Context context, final String packageName) {
|
||||
sWipeEuiccDataCalledCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sWipeEuiccDataCalledCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(RestrictedLockUtilsInternal.class)
|
||||
public class ShadowRestrictedLockUtilsInternal {
|
||||
|
||||
private static RestrictedLockUtils.EnforcedAdmin sEnforcedAdmin;
|
||||
private static boolean sHasBaseUserRestriction;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sEnforcedAdmin = null;
|
||||
sHasBaseUserRestriction = false;
|
||||
}
|
||||
|
||||
public static void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin enforcedAdmin) {
|
||||
sEnforcedAdmin = enforcedAdmin;
|
||||
}
|
||||
|
||||
public static void setHasBaseUserRestriction(boolean hasBaseUserRestriction) {
|
||||
sHasBaseUserRestriction = hasBaseUserRestriction;
|
||||
}
|
||||
|
||||
public static void sendShowAdminSupportDetailsIntent(Context context,
|
||||
RestrictedLockUtils.EnforcedAdmin admin) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static RestrictedLockUtils.EnforcedAdmin checkIfRestrictionEnforced(Context context,
|
||||
String userRestriction, int userId) {
|
||||
return sEnforcedAdmin;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean hasBaseUserRestriction(Context context,
|
||||
String userRestriction, int userId) {
|
||||
return sHasBaseUserRestriction;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.Ringtone;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(Ringtone.class)
|
||||
public class ShadowRingtone {
|
||||
|
||||
private static Map<Uri, String> sTitleForGivenUri = new HashMap<>();
|
||||
|
||||
public static void setExpectedTitleForUri(Uri uri, String title) {
|
||||
sTitleForGivenUri.put(uri, title);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static String getTitle(
|
||||
Context context, Uri uri, boolean followSettingsUri, boolean allowRemote) {
|
||||
return sTitleForGivenUri.getOrDefault(uri, null);
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sTitleForGivenUri.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(RingtoneManager.class)
|
||||
public class ShadowRingtoneManager {
|
||||
private static Ringtone sRingtone;
|
||||
private static Map<Integer, Uri> sSetDefaultRingtoneCalled = new HashMap<>();
|
||||
|
||||
public static void setRingtone(Ringtone ringtone) {
|
||||
sRingtone = ringtone;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static Ringtone getRingtone(final Context context, Uri ringtoneUri) {
|
||||
return sRingtone;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static void setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri) {
|
||||
sSetDefaultRingtoneCalled.put(type, ringtoneUri);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static Uri getActualDefaultRingtoneUri(Context context, int type) {
|
||||
return sSetDefaultRingtoneCalled.getOrDefault(type, null);
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sRingtone = null;
|
||||
sSetDefaultRingtoneCalled.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.provider.Settings;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowSettings;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@Implements(Settings.Secure.class)
|
||||
public class ShadowSecureSettings extends ShadowSettings.ShadowSecure {
|
||||
|
||||
@Implementation
|
||||
protected static int getInt(ContentResolver resolver, String name) {
|
||||
return Shadow.directlyOn(
|
||||
Settings.Secure.class,
|
||||
"getInt",
|
||||
ReflectionHelpers.ClassParameter.from(ContentResolver.class, resolver),
|
||||
ReflectionHelpers.ClassParameter.from(String.class, name));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static int getInt(ContentResolver resolver, String name, int def) {
|
||||
return Shadow.directlyOn(
|
||||
Settings.Secure.class,
|
||||
"getInt",
|
||||
ReflectionHelpers.ClassParameter.from(ContentResolver.class, resolver),
|
||||
ReflectionHelpers.ClassParameter.from(String.class, name),
|
||||
ReflectionHelpers.ClassParameter.from(int.class, def));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static int getIntForUser(ContentResolver resolver, String name, int def,
|
||||
int userHandle) {
|
||||
return Shadow.directlyOn(
|
||||
Settings.Secure.class,
|
||||
"getIntForUser",
|
||||
ReflectionHelpers.ClassParameter.from(ContentResolver.class, resolver),
|
||||
ReflectionHelpers.ClassParameter.from(String.class, name),
|
||||
ReflectionHelpers.ClassParameter.from(int.class, def),
|
||||
ReflectionHelpers.ClassParameter.from(int.class, userHandle));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean putInt(ContentResolver resolver, String name, int value) {
|
||||
return Shadow.directlyOn(
|
||||
Settings.Secure.class,
|
||||
"putInt",
|
||||
ReflectionHelpers.ClassParameter.from(ContentResolver.class, resolver),
|
||||
ReflectionHelpers.ClassParameter.from(String.class, name),
|
||||
ReflectionHelpers.ClassParameter.from(int.class, value));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean putIntForUser(ContentResolver resolver, String name, int value,
|
||||
int userHandle) {
|
||||
return Shadow.directlyOn(
|
||||
Settings.Secure.class,
|
||||
"putIntForUser",
|
||||
ReflectionHelpers.ClassParameter.from(ContentResolver.class, resolver),
|
||||
ReflectionHelpers.ClassParameter.from(String.class, name),
|
||||
ReflectionHelpers.ClassParameter.from(int.class, value),
|
||||
ReflectionHelpers.ClassParameter.from(int.class, userHandle));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 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.car.settings.testutils;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.internal.telephony.SmsApplication;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(SmsApplication.class)
|
||||
public class ShadowSmsApplication {
|
||||
|
||||
private static ComponentName sDefaultSmsApplication;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sDefaultSmsApplication = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static ComponentName getDefaultSmsApplication(
|
||||
Context context, boolean updateIfNeeded) {
|
||||
return sDefaultSmsApplication;
|
||||
}
|
||||
|
||||
public static void setDefaultSmsApplication(ComponentName defaultSmsApplication) {
|
||||
sDefaultSmsApplication = defaultSmsApplication;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.car.settings.testutils;
|
||||
|
||||
import android.telephony.SmsManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(SmsManager.class)
|
||||
public class ShadowSmsManager {
|
||||
|
||||
private static SmsManager sSmsManager;
|
||||
|
||||
public static void setDefault(SmsManager smsManager) {
|
||||
sSmsManager = smsManager;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sSmsManager = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static SmsManager getDefault() {
|
||||
|
||||
return sSmsManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 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.car.settings.testutils;
|
||||
|
||||
import android.os.storage.VolumeInfo;
|
||||
|
||||
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(StorageManagerVolumeProvider.class)
|
||||
public class ShadowStorageManagerVolumeProvider {
|
||||
|
||||
private static VolumeInfo sVolumeInfo;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sVolumeInfo = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected VolumeInfo findEmulatedForPrivate(VolumeInfo privateVolume) {
|
||||
return sVolumeInfo;
|
||||
}
|
||||
|
||||
public static void setVolumeInfo(VolumeInfo volumeInfo) {
|
||||
sVolumeInfo = volumeInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||
import android.telephony.SubscriptionPlan;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Implements(SubscriptionManager.class)
|
||||
public class ShadowSubscriptionManager extends org.robolectric.shadows.ShadowSubscriptionManager {
|
||||
|
||||
private static SubscriptionInfo sDefaultDataSubscriptionInfo = null;
|
||||
|
||||
private List<SubscriptionPlan> mSubscriptionPlanList;
|
||||
private List<SubscriptionInfo> mSelectableSubscriptionInfoList;
|
||||
private List<OnSubscriptionsChangedListener> mOnSubscriptionsChangedListeners =
|
||||
new ArrayList<>();
|
||||
private int mCurrentActiveSubscriptionId;
|
||||
|
||||
@Implementation
|
||||
protected List<SubscriptionPlan> getSubscriptionPlans(int subId) {
|
||||
return mSubscriptionPlanList;
|
||||
}
|
||||
|
||||
public void setSubscriptionPlans(List<SubscriptionPlan> subscriptionPlanList) {
|
||||
mSubscriptionPlanList = subscriptionPlanList;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected SubscriptionInfo getDefaultDataSubscriptionInfo() {
|
||||
return sDefaultDataSubscriptionInfo;
|
||||
}
|
||||
|
||||
public static void setDefaultDataSubscriptionInfo(SubscriptionInfo subscriptionInfo) {
|
||||
sDefaultDataSubscriptionInfo = subscriptionInfo;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
|
||||
return mSelectableSubscriptionInfoList;
|
||||
}
|
||||
|
||||
public void setSelectableSubscriptionInfoList(List<SubscriptionInfo> infos) {
|
||||
mSelectableSubscriptionInfoList = infos;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
|
||||
super.addOnSubscriptionsChangedListener(listener);
|
||||
mOnSubscriptionsChangedListeners.add(listener);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
|
||||
super.removeOnSubscriptionsChangedListener(listener);
|
||||
mOnSubscriptionsChangedListeners.remove(listener);
|
||||
}
|
||||
|
||||
public List<OnSubscriptionsChangedListener> getOnSubscriptionChangedListeners() {
|
||||
return mOnSubscriptionsChangedListeners;
|
||||
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isActiveSubscriptionId(int subscriptionId) {
|
||||
return mCurrentActiveSubscriptionId == subscriptionId;
|
||||
}
|
||||
|
||||
public void setCurrentActiveSubscriptionId(int subscriptionId) {
|
||||
mCurrentActiveSubscriptionId = subscriptionId;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
org.robolectric.shadows.ShadowSubscriptionManager.reset();
|
||||
sDefaultDataSubscriptionInfo = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import static android.telephony.PhoneStateListener.LISTEN_NONE;
|
||||
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(TelephonyManager.class)
|
||||
public class ShadowTelephonyManager extends org.robolectric.shadows.ShadowTelephonyManager {
|
||||
|
||||
public static final String SUBSCRIBER_ID = "test_id";
|
||||
private static Map<Integer, Integer> sSubIdsWithResetCalledCount = new HashMap<>();
|
||||
private static int sSimCount = 1;
|
||||
private final Map<PhoneStateListener, Integer> mPhoneStateRegistrations = new HashMap<>();
|
||||
private boolean mIsDataEnabled = false;
|
||||
private boolean mIsRoamingEnabled = false;
|
||||
|
||||
public static boolean verifyFactoryResetCalled(int subId, int numTimes) {
|
||||
if (!sSubIdsWithResetCalledCount.containsKey(subId)) return false;
|
||||
return sSubIdsWithResetCalledCount.get(subId) == numTimes;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void listen(PhoneStateListener listener, int flags) {
|
||||
super.listen(listener, flags);
|
||||
|
||||
if (flags == LISTEN_NONE) {
|
||||
mPhoneStateRegistrations.remove(listener);
|
||||
} else {
|
||||
mPhoneStateRegistrations.put(listener, flags);
|
||||
}
|
||||
}
|
||||
|
||||
public List<PhoneStateListener> getListenersForFlags(int flags) {
|
||||
List<PhoneStateListener> listeners = new ArrayList<>();
|
||||
for (PhoneStateListener listener : mPhoneStateRegistrations.keySet()) {
|
||||
if ((mPhoneStateRegistrations.get(listener) & flags) != 0) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
return listeners;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public void setDataEnabled(boolean enable) {
|
||||
mIsDataEnabled = enable;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isDataEnabled() {
|
||||
return mIsDataEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void factoryReset(int subId) {
|
||||
sSubIdsWithResetCalledCount.put(subId,
|
||||
sSubIdsWithResetCalledCount.getOrDefault(subId, 0) + 1);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getSubscriberId(int subId) {
|
||||
return subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID ? null : SUBSCRIBER_ID;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getSimCount() {
|
||||
return sSimCount;
|
||||
}
|
||||
|
||||
public static void setSimCount(int simCount) {
|
||||
sSimCount = simCount;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void setDataRoamingEnabled(boolean isEnabled) {
|
||||
mIsRoamingEnabled = isEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isDataRoamingEnabled() {
|
||||
return mIsRoamingEnabled;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sSubIdsWithResetCalledCount.clear();
|
||||
sSimCount = 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.Voice;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Implements(TextToSpeech.class)
|
||||
public class ShadowTextToSpeech {
|
||||
|
||||
private static TextToSpeech sInstance;
|
||||
private static TextToSpeech.OnInitListener sOnInitListener;
|
||||
private static String sEngine;
|
||||
|
||||
public static void setInstance(TextToSpeech textToSpeech) {
|
||||
sInstance = textToSpeech;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override constructor and only store the name of the last constructed engine and init
|
||||
* listener.
|
||||
*/
|
||||
public void __constructor__(Context context, TextToSpeech.OnInitListener listener,
|
||||
String engine,
|
||||
String packageName, boolean useFallback) {
|
||||
sOnInitListener = listener;
|
||||
sEngine = engine;
|
||||
}
|
||||
|
||||
public void __constructor__(Context context, TextToSpeech.OnInitListener listener,
|
||||
String engine) {
|
||||
__constructor__(context, listener, engine, null, false);
|
||||
}
|
||||
|
||||
public void __constructor__(Context context, TextToSpeech.OnInitListener listener) {
|
||||
__constructor__(context, listener, null, null, false);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getCurrentEngine() {
|
||||
return sInstance.getCurrentEngine();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int setLanguage(final Locale loc) {
|
||||
return sInstance.setLanguage(loc);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void shutdown() {
|
||||
sInstance.shutdown();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int setSpeechRate(float speechRate) {
|
||||
return sInstance.setSpeechRate(speechRate);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int setPitch(float pitch) {
|
||||
return sInstance.setPitch(pitch);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Voice getVoice() {
|
||||
return sInstance.getVoice();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int isLanguageAvailable(final Locale loc) {
|
||||
return sInstance.isLanguageAvailable(loc);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int speak(final CharSequence text,
|
||||
final int queueMode,
|
||||
final Bundle params,
|
||||
final String utteranceId) {
|
||||
return sInstance.speak(text, queueMode, params, utteranceId);
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sInstance = null;
|
||||
sOnInitListener = null;
|
||||
sEngine = null;
|
||||
}
|
||||
|
||||
/** Check for the last constructed engine name. */
|
||||
public static String getLastConstructedEngine() {
|
||||
return sEngine;
|
||||
}
|
||||
|
||||
/** Trigger the initializtion callback given the input status. */
|
||||
public static void callInitializationCallbackWithStatus(int status) {
|
||||
sOnInitListener.onInit(status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.TtsEngines;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@Implements(TtsEngines.class)
|
||||
public class ShadowTtsEngines {
|
||||
private static TtsEngines sInstance;
|
||||
|
||||
public static void setInstance(TtsEngines ttsEngines) {
|
||||
sInstance = ttsEngines;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<TextToSpeech.EngineInfo> getEngines() {
|
||||
return sInstance.getEngines();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected TextToSpeech.EngineInfo getEngineInfo(String packageName) {
|
||||
return sInstance.getEngineInfo(packageName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getDefaultEngine() {
|
||||
return sInstance.getDefaultEngine();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Intent getSettingsIntent(String engine) {
|
||||
return sInstance.getSettingsIntent(engine);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isLocaleSetToDefaultForEngine(String engineName) {
|
||||
return sInstance.isLocaleSetToDefaultForEngine(engineName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Locale getLocalePrefForEngine(String engineName) {
|
||||
return sInstance.getLocalePrefForEngine(engineName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected synchronized void updateLocalePrefForEngine(String engineName, Locale newLocale) {
|
||||
sInstance.updateLocalePrefForEngine(engineName, newLocale);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Locale parseLocaleString(String localeString) {
|
||||
return sInstance.parseLocaleString(localeString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 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.car.settings.testutils;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
/**
|
||||
* This is to shadow an extra function that old versions of Robolectric don't cover.
|
||||
*/
|
||||
@Implements(value = Typeface.class)
|
||||
public class ShadowTypeface extends org.robolectric.shadows.ShadowLegacyTypeface {
|
||||
|
||||
@Implementation
|
||||
public static Typeface create(Typeface family, int weight, boolean italic) {
|
||||
return create(family, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.car.settings.testutils;
|
||||
|
||||
import com.android.settingslib.net.UidDetail;
|
||||
import com.android.settingslib.net.UidDetailProvider;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(UidDetailProvider.class)
|
||||
public class ShadowUidDetailProvider {
|
||||
|
||||
private static UidDetail sUidDetail;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sUidDetail = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public UidDetail getUidDetail(int uid, boolean blocking) {
|
||||
return sUidDetail;
|
||||
}
|
||||
|
||||
public static void setUidDetail(UidDetail uidDetail) {
|
||||
sUidDetail = uidDetail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.UserInfo;
|
||||
|
||||
import com.android.car.settings.profiles.ProfileHelper;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Shadow for {@link ProfileHelper}.
|
||||
*/
|
||||
@Implements(ProfileHelper.class)
|
||||
public class ShadowUserHelper {
|
||||
private static ProfileHelper sInstance;
|
||||
|
||||
public static void setInstance(ProfileHelper profileHelper) {
|
||||
sInstance = profileHelper;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean canCurrentProcessModifyAccounts() {
|
||||
return sInstance.canCurrentProcessModifyAccounts();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<UserInfo> getAllUsers() {
|
||||
return sInstance.getAllProfiles();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<UserInfo> getAllSwitchableUsers() {
|
||||
return sInstance.getAllSwitchableProfiles();
|
||||
}
|
||||
|
||||
|
||||
@Implementation
|
||||
protected List<UserInfo> getAllPersistentUsers() {
|
||||
return sInstance.getAllPersistentProfiles();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isCurrentProcessUser(UserInfo userInfo) {
|
||||
return sInstance.isCurrentProcessUser(userInfo);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected UserInfo getCurrentProcessUserInfo() {
|
||||
return sInstance.getCurrentProcessUserInfo();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@ProfileHelper.RemoveProfileResult
|
||||
public int removeUser(Context context, UserInfo userInfo) {
|
||||
return sInstance.removeProfile(context, userInfo);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public UserInfo createNewOrFindExistingGuest(Context context) {
|
||||
return sInstance.createNewOrFindExistingGuest(context);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public List<UserInfo> getAllLivingUsers(@Nullable Predicate<? super UserInfo> filter) {
|
||||
return sInstance.getAllLivingProfiles(filter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.UserManager;
|
||||
|
||||
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
|
||||
|
||||
import com.android.car.settings.profiles.ProfileIconProvider;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(ProfileIconProvider.class)
|
||||
public class ShadowUserIconProvider {
|
||||
@Implementation
|
||||
protected RoundedBitmapDrawable getRoundedUserIcon(UserInfo userInfo, Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected RoundedBitmapDrawable getRoundedGuestDefaultIcon(Resources resources) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Bitmap assignDefaultIcon(
|
||||
UserManager userManager, Resources resources, UserInfo userInfo) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.annotation.UserIdInt;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(UserManager.class)
|
||||
public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {
|
||||
|
||||
private static boolean sIsHeadlessSystemUserMode = true;
|
||||
private static boolean sCanAddMoreUsers = true;
|
||||
private static Map<Integer, List<UserInfo>> sProfiles = new ArrayMap<>();
|
||||
private static Map<Integer, Bitmap> sUserIcons = new ArrayMap<>();
|
||||
|
||||
@Implementation
|
||||
protected int[] getProfileIdsWithDisabled(int userId) {
|
||||
if (sProfiles.containsKey(userId)) {
|
||||
return sProfiles.get(userId).stream().mapToInt(userInfo -> userInfo.id).toArray();
|
||||
}
|
||||
return new int[]{};
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<UserInfo> getProfiles(int userHandle) {
|
||||
if (sProfiles.containsKey(userHandle)) {
|
||||
return new ArrayList<>(sProfiles.get(userHandle));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/** Adds a profile to be returned by {@link #getProfiles(int)}. **/
|
||||
public void addProfile(
|
||||
int userHandle, int profileUserHandle, String profileName, int profileFlags) {
|
||||
sProfiles.putIfAbsent(userHandle, new ArrayList<>());
|
||||
sProfiles.get(userHandle).add(new UserInfo(profileUserHandle, profileName, profileFlags));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void setUserRestriction(String key, boolean value, UserHandle userHandle) {
|
||||
setUserRestriction(userHandle, key, value);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<UserInfo> getUsers(boolean excludeDying) {
|
||||
return super.getUsers();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isHeadlessSystemUserMode() {
|
||||
return sIsHeadlessSystemUserMode;
|
||||
}
|
||||
|
||||
public static void setIsHeadlessSystemUserMode(boolean isEnabled) {
|
||||
sIsHeadlessSystemUserMode = isEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean canAddMoreUsers() {
|
||||
return sCanAddMoreUsers;
|
||||
}
|
||||
|
||||
public static void setCanAddMoreUsers(boolean isEnabled) {
|
||||
sCanAddMoreUsers = isEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public Bitmap getUserIcon(@UserIdInt int userId) {
|
||||
return sUserIcons.get(userId);
|
||||
}
|
||||
|
||||
public static void setUserIcon(@UserIdInt int userId, Bitmap icon) {
|
||||
sUserIcons.put(userId, icon);
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
org.robolectric.shadows.ShadowUserManager.reset();
|
||||
sIsHeadlessSystemUserMode = true;
|
||||
sCanAddMoreUsers = true;
|
||||
sProfiles.clear();
|
||||
sUserIcons.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(value = Utils.class)
|
||||
public class ShadowUtils {
|
||||
private static String sDeviceProvisioningPackage;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sDeviceProvisioningPackage = null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isDeviceProvisioningPackage(Resources resources,
|
||||
String packageName) {
|
||||
return sDeviceProvisioningPackage != null && sDeviceProvisioningPackage.equals(
|
||||
packageName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static Drawable getBadgedIcon(Context context, ApplicationInfo appInfo) {
|
||||
return new ColorDrawable(0);
|
||||
}
|
||||
|
||||
public static void setDeviceProvisioningPackage(String deviceProvisioningPackage) {
|
||||
sDeviceProvisioningPackage = deviceProvisioningPackage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.service.voice.VoiceInteractionServiceInfo;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(VoiceInteractionServiceInfo.class)
|
||||
public class ShadowVoiceInteractionServiceInfo {
|
||||
private static Map<ServiceInfo, Boolean> sSupportsAssistMap = new HashMap<>();
|
||||
private static Map<ServiceInfo, String> sRecognitionServiceMap = new HashMap<>();
|
||||
private static Map<ServiceInfo, String> sSettingsActivityMap = new HashMap<>();
|
||||
|
||||
private ServiceInfo mServiceInfo;
|
||||
|
||||
public void __constructor__(PackageManager pm, ServiceInfo si) {
|
||||
mServiceInfo = si;
|
||||
}
|
||||
|
||||
public static void setSupportsAssist(ServiceInfo si, boolean supports) {
|
||||
sSupportsAssistMap.put(si, supports);
|
||||
}
|
||||
|
||||
public static void setRecognitionService(ServiceInfo si, String recognitionService) {
|
||||
sRecognitionServiceMap.put(si, recognitionService);
|
||||
}
|
||||
|
||||
public static void setSettingsActivity(ServiceInfo si, String settingsActivity) {
|
||||
sSettingsActivityMap.put(si, settingsActivity);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean getSupportsAssist() {
|
||||
return sSupportsAssistMap.get(mServiceInfo);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getRecognitionService() {
|
||||
return sRecognitionServiceMap.get(mServiceInfo);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getSettingsActivity() {
|
||||
return sSettingsActivityMap.get(mServiceInfo);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected ServiceInfo getServiceInfo() {
|
||||
return mServiceInfo;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sSupportsAssistMap.clear();
|
||||
sRecognitionServiceMap.clear();
|
||||
sSettingsActivityMap.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.car.settings.testutils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.DhcpInfo;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowConnectivityManager;
|
||||
import org.robolectric.shadows.ShadowNetworkInfo;
|
||||
import org.robolectric.shadows.ShadowWifiInfo;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(WifiManager.class)
|
||||
public class ShadowWifiManager extends org.robolectric.shadows.ShadowWifiManager {
|
||||
private static final int LOCAL_HOST = 2130706433;
|
||||
|
||||
private static int sResetCalledCount = 0;
|
||||
|
||||
private final Map<Integer, WifiConfiguration> mNetworkIdToConfiguredNetworks =
|
||||
new LinkedHashMap<>();
|
||||
private Pair<Integer, Boolean> mLastEnabledNetwork;
|
||||
private int mLastForgottenNetwork = Integer.MIN_VALUE;
|
||||
private WifiInfo mActiveWifiInfo;
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected int addNetwork(WifiConfiguration config) {
|
||||
int networkId = mNetworkIdToConfiguredNetworks.size();
|
||||
config.networkId = -1;
|
||||
mNetworkIdToConfiguredNetworks.put(networkId, makeCopy(config, networkId));
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected void connect(WifiConfiguration wifiConfiguration,
|
||||
WifiManager.ActionListener listener) {
|
||||
int networkId = mNetworkIdToConfiguredNetworks.size();
|
||||
mNetworkIdToConfiguredNetworks.put(networkId,
|
||||
makeCopy(wifiConfiguration, wifiConfiguration.networkId));
|
||||
mLastEnabledNetwork = new Pair<>(wifiConfiguration.networkId, true);
|
||||
|
||||
WifiInfo wifiInfo = getConnectionInfo();
|
||||
|
||||
String ssid = isQuoted(wifiConfiguration.SSID)
|
||||
? stripQuotes(wifiConfiguration.SSID)
|
||||
: wifiConfiguration.SSID;
|
||||
|
||||
ShadowWifiInfo shadowWifiInfo = Shadow.extract(wifiInfo);
|
||||
shadowWifiInfo.setSSID(ssid);
|
||||
shadowWifiInfo.setBSSID(wifiConfiguration.BSSID);
|
||||
shadowWifiInfo.setNetworkId(wifiConfiguration.networkId);
|
||||
setConnectionInfo(wifiInfo);
|
||||
|
||||
// Now that we're "connected" to wifi, update Dhcp and point it to localhost.
|
||||
DhcpInfo dhcpInfo = new DhcpInfo();
|
||||
dhcpInfo.gateway = LOCAL_HOST;
|
||||
dhcpInfo.ipAddress = LOCAL_HOST;
|
||||
setDhcpInfo(dhcpInfo);
|
||||
|
||||
// Now add the network to ConnectivityManager.
|
||||
NetworkInfo networkInfo =
|
||||
ShadowNetworkInfo.newInstance(
|
||||
NetworkInfo.DetailedState.CONNECTED,
|
||||
ConnectivityManager.TYPE_WIFI,
|
||||
0 /* subType */,
|
||||
true /* isAvailable */,
|
||||
true /* isConnected */);
|
||||
ShadowConnectivityManager connectivityManager =
|
||||
Shadow.extract(RuntimeEnvironment.application
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE));
|
||||
connectivityManager.setActiveNetworkInfo(networkInfo);
|
||||
|
||||
mActiveWifiInfo = wifiInfo;
|
||||
|
||||
if (listener != null) {
|
||||
listener.onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isQuoted(String str) {
|
||||
if (str == null || str.length() < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return str.charAt(0) == '"' && str.charAt(str.length() - 1) == '"';
|
||||
}
|
||||
|
||||
private static String stripQuotes(String str) {
|
||||
return str.substring(1, str.length() - 1);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@Override
|
||||
protected boolean reconnect() {
|
||||
WifiConfiguration wifiConfiguration = getMostRecentNetwork();
|
||||
if (wifiConfiguration == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(wifiConfiguration, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
private WifiConfiguration getMostRecentNetwork() {
|
||||
if (getLastEnabledNetwork() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getWifiConfiguration(getLastEnabledNetwork().first);
|
||||
}
|
||||
|
||||
public WifiConfiguration getLastAddedNetworkConfiguration() {
|
||||
return mNetworkIdToConfiguredNetworks.get(getLastAddedNetworkId());
|
||||
}
|
||||
|
||||
public int getLastAddedNetworkId() {
|
||||
return mNetworkIdToConfiguredNetworks.size() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Integer, Boolean> getLastEnabledNetwork() {
|
||||
return mLastEnabledNetwork;
|
||||
}
|
||||
|
||||
public WifiInfo getActiveWifiInfo() {
|
||||
return mActiveWifiInfo;
|
||||
}
|
||||
|
||||
public static boolean verifyFactoryResetCalled(int numTimes) {
|
||||
return sResetCalledCount == numTimes;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void forget(int netId, WifiManager.ActionListener listener) {
|
||||
mLastForgottenNetwork = netId;
|
||||
}
|
||||
|
||||
public int getLastForgottenNetwork() {
|
||||
return mLastForgottenNetwork;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void factoryReset() {
|
||||
sResetCalledCount++;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sResetCalledCount = 0;
|
||||
}
|
||||
|
||||
private WifiConfiguration makeCopy(WifiConfiguration config, int networkId) {
|
||||
WifiConfiguration copy = Shadows.shadowOf(config).copy();
|
||||
copy.networkId = networkId;
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user