Use resource processor for Settings
Bug: 293810334 Test: m Settings Test: robotests Change-Id: Ie515e137648eddfdfcab5e8095f5be99721d9e1b
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import static org.robolectric.RuntimeEnvironment.application;
|
||||
import static org.robolectric.shadow.api.Shadow.directlyOn;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.NotFoundException;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.annotation.ArrayRes;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.RealObject;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
import org.robolectric.shadows.ShadowResources;
|
||||
import org.robolectric.util.ReflectionHelpers.ClassParameter;
|
||||
|
||||
/**
|
||||
* Shadow Resources and Theme classes to handle resource references that Robolectric shadows cannot
|
||||
* handle because they are too new or private.
|
||||
*/
|
||||
@Implements(value = Resources.class)
|
||||
public class SettingsShadowResources extends ShadowResources {
|
||||
|
||||
@RealObject
|
||||
public Resources realResources;
|
||||
|
||||
private static SparseArray<Object> sResourceOverrides = new SparseArray<>();
|
||||
|
||||
public static void overrideResource(int id, Object value) {
|
||||
sResourceOverrides.put(id, value);
|
||||
}
|
||||
|
||||
public static void overrideResource(String name, Object value) {
|
||||
final Resources res = application.getResources();
|
||||
final int resId = res.getIdentifier(name, null, null);
|
||||
if (resId == 0) {
|
||||
throw new Resources.NotFoundException("Cannot override \"" + name + "\"");
|
||||
}
|
||||
overrideResource(resId, value);
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sResourceOverrides.clear();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int[] getIntArray(@ArrayRes int id) throws NotFoundException {
|
||||
final Object override = sResourceOverrides.get(id);
|
||||
if (override instanceof int[]) {
|
||||
return (int[]) override;
|
||||
}
|
||||
return directlyOn(realResources, Resources.class).getIntArray(id);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected String getString(int id) {
|
||||
final Object override = sResourceOverrides.get(id);
|
||||
if (override instanceof String) {
|
||||
return (String) override;
|
||||
}
|
||||
return directlyOn(
|
||||
realResources, Resources.class, "getString", ClassParameter.from(int.class, id));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getInteger(int id) {
|
||||
final Object override = sResourceOverrides.get(id);
|
||||
if (override instanceof Integer) {
|
||||
return (Integer) override;
|
||||
}
|
||||
return directlyOn(
|
||||
realResources, Resources.class, "getInteger", ClassParameter.from(int.class, id));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean getBoolean(int id) {
|
||||
final Object override = sResourceOverrides.get(id);
|
||||
if (override instanceof Boolean) {
|
||||
return (boolean) override;
|
||||
}
|
||||
return directlyOn(realResources, Resources.class, "getBoolean",
|
||||
ClassParameter.from(int.class, id));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(AccessibilityServiceInfo.class)
|
||||
public class ShadowAccessibilityServiceInfo {
|
||||
private static ComponentName sComponentName;
|
||||
|
||||
public static void setComponentName(String componentName) {
|
||||
sComponentName = ComponentName.unflattenFromString(componentName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected ComponentName getComponentName() {
|
||||
return sComponentName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import com.android.settings.testutils.CustomActivity;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(CustomActivity.class)
|
||||
public class ShadowActivity extends org.robolectric.shadows.ShadowActivity {
|
||||
|
||||
@Implementation
|
||||
protected void startActivityAsUser(Intent intent, UserHandle user) {
|
||||
realActivity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
/**
|
||||
* Shadow class for {@link ActivityEmbeddingUtils} to test embedding activity features.
|
||||
*/
|
||||
@Implements(ActivityEmbeddingUtils.class)
|
||||
public class ShadowActivityEmbeddingUtils {
|
||||
private static boolean sIsEmbeddingActivityEnabled;
|
||||
|
||||
@Implementation
|
||||
public static boolean isEmbeddingActivityEnabled(Context context) {
|
||||
return sIsEmbeddingActivityEnabled;
|
||||
}
|
||||
|
||||
public static void setIsEmbeddingActivityEnabled(boolean isEmbeddingActivityEnabled) {
|
||||
sIsEmbeddingActivityEnabled = isEmbeddingActivityEnabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.RealObject;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowDialog;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/* Robolectric shadow for the androidx alert dialog. */
|
||||
@Implements(AlertDialog.class)
|
||||
public class ShadowAlertDialogCompat extends ShadowDialog {
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
@Nullable
|
||||
private static ShadowAlertDialogCompat sLatestSupportAlertDialog;
|
||||
@RealObject
|
||||
private AlertDialog mRealAlertDialog;
|
||||
|
||||
@Implementation
|
||||
public void show() {
|
||||
super.show();
|
||||
sLatestSupportAlertDialog = this;
|
||||
}
|
||||
|
||||
public CharSequence getMessage() {
|
||||
final Object alertController = ReflectionHelpers.getField(mRealAlertDialog, "mAlert");
|
||||
return ReflectionHelpers.getField(alertController, "mMessage");
|
||||
}
|
||||
|
||||
public CharSequence getTitle() {
|
||||
final Object alertController = ReflectionHelpers.getField(mRealAlertDialog, "mAlert");
|
||||
return ReflectionHelpers.getField(alertController, "mTitle");
|
||||
}
|
||||
|
||||
public View getView() {
|
||||
final Object alertController = ReflectionHelpers.getField(mRealAlertDialog, "mAlert");
|
||||
return ReflectionHelpers.getField(alertController, "mView");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AlertDialog getLatestAlertDialog() {
|
||||
return sLatestSupportAlertDialog == null
|
||||
? null : sLatestSupportAlertDialog.mRealAlertDialog;
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sLatestSupportAlertDialog = null;
|
||||
}
|
||||
|
||||
public static ShadowAlertDialogCompat shadowOf(AlertDialog alertDialog) {
|
||||
return (ShadowAlertDialogCompat) Shadow.extract(alertDialog);
|
||||
}
|
||||
|
||||
public void clickOnItem(int index) {
|
||||
Shadows.shadowOf(mRealAlertDialog.getListView()).performItemClick(index);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Implements(value = BluetoothAdapter.class)
|
||||
public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBluetoothAdapter {
|
||||
|
||||
private int mState;
|
||||
private List<Integer> mSupportedProfiles = new ArrayList<>();
|
||||
private List<BluetoothDevice> mMostRecentlyConnectedDevices = new ArrayList<>();
|
||||
|
||||
@Implementation
|
||||
protected List<Integer> getSupportedProfiles() {
|
||||
return mSupportedProfiles;
|
||||
}
|
||||
|
||||
public void addSupportedProfiles(int profile) {
|
||||
mSupportedProfiles.add(profile);
|
||||
}
|
||||
|
||||
public void clearSupportedProfiles() {
|
||||
mSupportedProfiles.clear();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getConnectionState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
public void setConnectionState(int state) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean factoryReset() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<BluetoothDevice> getMostRecentlyConnectedDevices() {
|
||||
return mMostRecentlyConnectedDevices;
|
||||
}
|
||||
|
||||
public void setMostRecentlyConnectedDevices(List<BluetoothDevice> list) {
|
||||
mMostRecentlyConnectedDevices = list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.net.ConnectivityManager;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
@Implements(value = ConnectivityManager.class)
|
||||
public class ShadowConnectivityManager extends org.robolectric.shadows.ShadowConnectivityManager {
|
||||
|
||||
private final SparseBooleanArray mSupportedNetworkTypes = new SparseBooleanArray();
|
||||
private boolean mTetheringSupported = false;
|
||||
|
||||
public void setNetworkSupported(int networkType, boolean supported) {
|
||||
mSupportedNetworkTypes.put(networkType, supported);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isNetworkSupported(int networkType) {
|
||||
return mSupportedNetworkTypes.get(networkType);
|
||||
}
|
||||
|
||||
public void setTetheringSupported(boolean supported) {
|
||||
mTetheringSupported = supported;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isTetheringSupported() {
|
||||
return mTetheringSupported;
|
||||
}
|
||||
|
||||
public static ShadowConnectivityManager getShadow() {
|
||||
return Shadow.extract(
|
||||
RuntimeEnvironment.application.getSystemService(ConnectivityManager.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import com.android.settings.datausage.DataSaverBackend;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(DataSaverBackend.class)
|
||||
public class ShadowDataSaverBackend {
|
||||
|
||||
private static boolean sIsEnabled = true;
|
||||
|
||||
@Implementation
|
||||
protected boolean isDataSaverEnabled() {
|
||||
return sIsEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void setDataSaverEnabled(boolean enabled) {
|
||||
sIsEnabled = enabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(value = Fragment.class)
|
||||
public class ShadowFragment {
|
||||
|
||||
private Fragment mTargetFragment;
|
||||
|
||||
@Implementation
|
||||
public void onCreate(Bundle icicle) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void setTargetFragment(Fragment fragment, int requestCode) {
|
||||
mTargetFragment = fragment;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Fragment getTargetFragment() {
|
||||
return mTargetFragment;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import com.android.internal.jank.InteractionJankMonitor;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link com.android.settingslib.testutils.shadow.ShadowInteractionJankMonitor}
|
||||
*/
|
||||
@Deprecated
|
||||
@Implements(InteractionJankMonitor.class)
|
||||
public class ShadowInteractionJankMonitor {
|
||||
|
||||
@Implementation
|
||||
public static InteractionJankMonitor getInstance() {
|
||||
return mock(InteractionJankMonitor.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.PasswordMetrics;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
|
||||
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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(LockPatternUtils.class)
|
||||
public class ShadowLockPatternUtils {
|
||||
|
||||
private static boolean sDeviceEncryptionEnabled;
|
||||
private static Map<Integer, Integer> sUserToActivePasswordQualityMap = new HashMap<>();
|
||||
private static Map<Integer, Integer> sUserToComplexityMap = new HashMap<>();
|
||||
private static Map<Integer, Integer> sUserToProfileComplexityMap = new HashMap<>();
|
||||
private static Map<Integer, PasswordMetrics> sUserToMetricsMap = new HashMap<>();
|
||||
private static Map<Integer, PasswordMetrics> sUserToProfileMetricsMap = new HashMap<>();
|
||||
private static Map<Integer, Boolean> sUserToIsSecureMap = new HashMap<>();
|
||||
private static Map<Integer, Boolean> sUserToVisiblePatternEnabledMap = new HashMap<>();
|
||||
private static Map<Integer, Boolean> sUserToBiometricAllowedMap = new HashMap<>();
|
||||
private static Map<Integer, Boolean> sUserToLockPatternEnabledMap = new HashMap<>();
|
||||
|
||||
private static boolean sIsUserOwnsFrpCredential;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sUserToActivePasswordQualityMap.clear();
|
||||
sUserToComplexityMap.clear();
|
||||
sUserToProfileComplexityMap.clear();
|
||||
sUserToMetricsMap.clear();
|
||||
sUserToProfileMetricsMap.clear();
|
||||
sUserToIsSecureMap.clear();
|
||||
sUserToVisiblePatternEnabledMap.clear();
|
||||
sUserToBiometricAllowedMap.clear();
|
||||
sUserToLockPatternEnabledMap.clear();
|
||||
sDeviceEncryptionEnabled = false;
|
||||
sIsUserOwnsFrpCredential = false;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean hasSecureLockScreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isSecure(int userId) {
|
||||
Boolean isSecure = sUserToIsSecureMap.get(userId);
|
||||
if (isSecure == null) {
|
||||
return true;
|
||||
}
|
||||
return isSecure;
|
||||
}
|
||||
|
||||
public static void setIsSecure(int userId, boolean isSecure) {
|
||||
sUserToIsSecureMap.put(userId, isSecure);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getActivePasswordQuality(int userId) {
|
||||
final Integer activePasswordQuality = sUserToActivePasswordQualityMap.get(userId);
|
||||
if (activePasswordQuality == null) {
|
||||
return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
}
|
||||
return activePasswordQuality;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getKeyguardStoredPasswordQuality(int userHandle) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isDeviceEncryptionEnabled() {
|
||||
return sDeviceEncryptionEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<ComponentName> getEnabledTrustAgents(int userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setDeviceEncryptionEnabled(boolean deviceEncryptionEnabled) {
|
||||
sDeviceEncryptionEnabled = deviceEncryptionEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected byte[] getPasswordHistoryHashFactor(
|
||||
LockscreenCredential currentPassword, int userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean checkPasswordHistory(byte[] passwordToCheck, byte[] hashFactor, int userId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public @DevicePolicyManager.PasswordComplexity int getRequestedPasswordComplexity(int userId) {
|
||||
return getRequestedPasswordComplexity(userId, false);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@DevicePolicyManager.PasswordComplexity
|
||||
public int getRequestedPasswordComplexity(int userId, boolean deviceWideOnly) {
|
||||
int complexity = sUserToComplexityMap.getOrDefault(userId,
|
||||
DevicePolicyManager.PASSWORD_COMPLEXITY_NONE);
|
||||
if (!deviceWideOnly) {
|
||||
complexity = Math.max(complexity, sUserToProfileComplexityMap.getOrDefault(userId,
|
||||
DevicePolicyManager.PASSWORD_COMPLEXITY_NONE));
|
||||
}
|
||||
return complexity;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static boolean userOwnsFrpCredential(Context context, UserInfo info) {
|
||||
return sIsUserOwnsFrpCredential;
|
||||
}
|
||||
|
||||
public static void setUserOwnsFrpCredential(boolean isUserOwnsFrpCredential) {
|
||||
sIsUserOwnsFrpCredential = isUserOwnsFrpCredential;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isVisiblePatternEnabled(int userId) {
|
||||
return sUserToVisiblePatternEnabledMap.getOrDefault(userId, false);
|
||||
}
|
||||
|
||||
public static void setIsVisiblePatternEnabled(int userId, boolean isVisiblePatternEnabled) {
|
||||
sUserToVisiblePatternEnabledMap.put(userId, isVisiblePatternEnabled);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isBiometricAllowedForUser(int userId) {
|
||||
return sUserToBiometricAllowedMap.getOrDefault(userId, false);
|
||||
}
|
||||
|
||||
public static void setIsBiometricAllowedForUser(int userId, boolean isBiometricAllowed) {
|
||||
sUserToBiometricAllowedMap.put(userId, isBiometricAllowed);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isLockPatternEnabled(int userId) {
|
||||
return sUserToBiometricAllowedMap.getOrDefault(userId, false);
|
||||
}
|
||||
|
||||
public static void setIsLockPatternEnabled(int userId, boolean isLockPatternEnabled) {
|
||||
sUserToLockPatternEnabledMap.put(userId, isLockPatternEnabled);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean setLockCredential(
|
||||
@NonNull LockscreenCredential newCredential,
|
||||
@NonNull LockscreenCredential savedCredential, int userHandle) {
|
||||
setIsSecure(userHandle, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean checkCredential(
|
||||
@NonNull LockscreenCredential credential, int userId,
|
||||
@Nullable LockPatternUtils.CheckCredentialProgressCallback progressCallback)
|
||||
throws LockPatternUtils.RequestThrottledException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void setRequiredPasswordComplexity(int userHandle, int complexity) {
|
||||
sUserToComplexityMap.put(userHandle, complexity);
|
||||
}
|
||||
|
||||
public static void setRequiredPasswordComplexity(int complexity) {
|
||||
sUserToComplexityMap.put(UserHandle.myUserId(), complexity);
|
||||
}
|
||||
|
||||
public static void setRequiredProfilePasswordComplexity(int complexity) {
|
||||
sUserToProfileComplexityMap.put(UserHandle.myUserId(), complexity);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public PasswordMetrics getRequestedPasswordMetrics(int userId, boolean deviceWideOnly) {
|
||||
PasswordMetrics metrics = sUserToMetricsMap.getOrDefault(userId,
|
||||
new PasswordMetrics(LockPatternUtils.CREDENTIAL_TYPE_NONE));
|
||||
if (!deviceWideOnly) {
|
||||
metrics.maxWith(sUserToProfileMetricsMap.getOrDefault(userId,
|
||||
new PasswordMetrics(LockPatternUtils.CREDENTIAL_TYPE_NONE)));
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
|
||||
public static void setRequestedPasswordMetrics(PasswordMetrics metrics) {
|
||||
sUserToMetricsMap.put(UserHandle.myUserId(), metrics);
|
||||
}
|
||||
|
||||
public static void setRequestedProfilePasswordMetrics(PasswordMetrics metrics) {
|
||||
sUserToProfileMetricsMap.put(UserHandle.myUserId(), metrics);
|
||||
}
|
||||
|
||||
public static void setActivePasswordQuality(int quality) {
|
||||
sUserToActivePasswordQualityMap.put(UserHandle.myUserId(), quality);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isLockScreenDisabled(int userId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isSeparateProfileChallengeEnabled(int userHandle) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(ThreadUtils.class)
|
||||
public class ShadowThreadUtils {
|
||||
|
||||
private static boolean sIsMainThread = true;
|
||||
private static final String TAG = "ShadowThreadUtils";
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sIsMainThread = true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static void postOnBackgroundThread(Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static void postOnMainThread(Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isMainThread() {
|
||||
return sIsMainThread;
|
||||
}
|
||||
|
||||
public static void setIsMainThread(boolean isMainThread) {
|
||||
sIsMainThread = isMainThread;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.annotation.UserIdInt;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManager.EnforcingUser;
|
||||
|
||||
import com.google.android.collect.Maps;
|
||||
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Implements(value = UserManager.class)
|
||||
public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {
|
||||
|
||||
private static boolean sIsSupportsMultipleUsers;
|
||||
|
||||
private static final int PRIMARY_USER_ID = 0;
|
||||
|
||||
private final List<String> mBaseRestrictions = new ArrayList<>();
|
||||
private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
|
||||
private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
|
||||
private final Set<Integer> mManagedProfiles = new HashSet<>();
|
||||
private final Set<String> mEnabledTypes = new HashSet<>();
|
||||
private boolean mIsQuietModeEnabled = false;
|
||||
private int[] mProfileIdsForUser = new int[0];
|
||||
private boolean mUserSwitchEnabled;
|
||||
private Bundle mDefaultGuestUserRestriction = new Bundle();
|
||||
private boolean mIsGuestUser = false;
|
||||
|
||||
private @UserManager.UserSwitchabilityResult int mSwitchabilityStatus =
|
||||
UserManager.SWITCHABILITY_STATUS_OK;
|
||||
private final Map<Integer, Integer> mSameProfileGroupIds = Maps.newHashMap();
|
||||
|
||||
public void addProfile(UserInfo userInfo) {
|
||||
mUserProfileInfos.add(userInfo);
|
||||
}
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sIsSupportsMultipleUsers = false;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<UserInfo> getProfiles(@UserIdInt int userHandle) {
|
||||
return mUserProfileInfos;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int[] getProfileIds(@UserIdInt int userHandle, boolean enabledOnly) {
|
||||
int[] ids = new int[mUserProfileInfos.size()];
|
||||
for (int i = 0; i < mUserProfileInfos.size(); i++) {
|
||||
ids[i] = mUserProfileInfos.get(i).id;
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getCredentialOwnerProfile(@UserIdInt int userHandle) {
|
||||
return userHandle;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean hasBaseUserRestriction(String restrictionKey, UserHandle userHandle) {
|
||||
return mBaseRestrictions.contains(restrictionKey);
|
||||
}
|
||||
|
||||
public void addBaseUserRestriction(String restriction) {
|
||||
mBaseRestrictions.add(restriction);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected Bundle getDefaultGuestRestrictions() {
|
||||
return mDefaultGuestUserRestriction;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void setDefaultGuestRestrictions(Bundle restrictions) {
|
||||
mDefaultGuestUserRestriction = restrictions;
|
||||
}
|
||||
|
||||
public void addGuestUserRestriction(String restriction) {
|
||||
mDefaultGuestUserRestriction.putBoolean(restriction, true);
|
||||
}
|
||||
|
||||
public boolean hasGuestUserRestriction(String restriction, boolean expectedValue) {
|
||||
return mDefaultGuestUserRestriction.containsKey(restriction)
|
||||
&& mDefaultGuestUserRestriction.getBoolean(restriction) == expectedValue;
|
||||
}
|
||||
|
||||
|
||||
@Implementation
|
||||
protected boolean hasUserRestriction(String restrictionKey) {
|
||||
return hasUserRestriction(restrictionKey, UserHandle.of(UserHandle.myUserId()));
|
||||
}
|
||||
|
||||
public static ShadowUserManager getShadow() {
|
||||
return (ShadowUserManager) Shadow.extract(
|
||||
RuntimeEnvironment.application.getSystemService(UserManager.class));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected List<EnforcingUser> getUserRestrictionSources(
|
||||
String restrictionKey, UserHandle userHandle) {
|
||||
// Return empty list when there is no enforcing user, otherwise might trigger
|
||||
// NullPointer Exception in RestrictedLockUtils.checkIfRestrictionEnforced.
|
||||
List<EnforcingUser> enforcingUsers =
|
||||
mRestrictionSources.get(restrictionKey + userHandle.getIdentifier());
|
||||
return enforcingUsers == null ? Collections.emptyList() : enforcingUsers;
|
||||
}
|
||||
|
||||
public void setUserRestrictionSources(
|
||||
String restrictionKey, UserHandle userHandle, List<EnforcingUser> enforcers) {
|
||||
mRestrictionSources.put(restrictionKey + userHandle.getIdentifier(), enforcers);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isQuietModeEnabled(UserHandle userHandle) {
|
||||
return mIsQuietModeEnabled;
|
||||
}
|
||||
|
||||
public void setQuietModeEnabled(boolean enabled) {
|
||||
mIsQuietModeEnabled = enabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int[] getProfileIdsWithDisabled(@UserIdInt int userId) {
|
||||
return mProfileIdsForUser;
|
||||
}
|
||||
|
||||
public void setProfileIdsWithDisabled(int[] profileIds) {
|
||||
mProfileIdsForUser = profileIds;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isUserSwitcherEnabled() {
|
||||
return mUserSwitchEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isManagedProfile(int userId) {
|
||||
return mManagedProfiles.contains(userId);
|
||||
}
|
||||
|
||||
public void setManagedProfiles(Set<Integer> profileIds) {
|
||||
mManagedProfiles.clear();
|
||||
mManagedProfiles.addAll(profileIds);
|
||||
}
|
||||
|
||||
public void setUserSwitcherEnabled(boolean userSwitchEnabled) {
|
||||
mUserSwitchEnabled = userSwitchEnabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean supportsMultipleUsers() {
|
||||
return sIsSupportsMultipleUsers;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isSameProfileGroup(@UserIdInt int userId, int otherUserId) {
|
||||
return mSameProfileGroupIds.containsKey(userId)
|
||||
&& mSameProfileGroupIds.get(userId) == otherUserId
|
||||
|| mSameProfileGroupIds.containsKey(otherUserId)
|
||||
&& mSameProfileGroupIds.get(otherUserId) == userId;
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getSameProfileGroupIds() {
|
||||
return mSameProfileGroupIds;
|
||||
}
|
||||
|
||||
public void setSupportsMultipleUsers(boolean supports) {
|
||||
sIsSupportsMultipleUsers = supports;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected UserInfo getUserInfo(@UserIdInt int userId) {
|
||||
return mUserProfileInfos.stream()
|
||||
.filter(userInfo -> userInfo.id == userId)
|
||||
.findFirst()
|
||||
.orElse(super.getUserInfo(userId));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected @UserManager.UserSwitchabilityResult int getUserSwitchability() {
|
||||
return mSwitchabilityStatus;
|
||||
}
|
||||
|
||||
public void setSwitchabilityStatus(@UserManager.UserSwitchabilityResult int newStatus) {
|
||||
mSwitchabilityStatus = newStatus;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isUserTypeEnabled(String userType) {
|
||||
return mEnabledTypes.contains(userType);
|
||||
}
|
||||
|
||||
public void setUserTypeEnabled(String type, boolean enabled) {
|
||||
if (enabled) {
|
||||
mEnabledTypes.add(type);
|
||||
} else {
|
||||
mEnabledTypes.remove(type);
|
||||
}
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected UserInfo getPrimaryUser() {
|
||||
return new UserInfo(PRIMARY_USER_ID, null, null,
|
||||
UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
|
||||
}
|
||||
|
||||
protected boolean setUserEphemeral(@UserIdInt int userId, boolean enableEphemeral) {
|
||||
UserInfo userInfo = mUserProfileInfos.stream()
|
||||
.filter(user -> user.id == userId)
|
||||
.findFirst()
|
||||
.orElse(super.getUserInfo(userId));
|
||||
|
||||
boolean isSuccess = false;
|
||||
boolean isEphemeralUser =
|
||||
(userInfo.flags & UserInfo.FLAG_EPHEMERAL) != 0;
|
||||
boolean isEphemeralOnCreateUser =
|
||||
(userInfo.flags & UserInfo.FLAG_EPHEMERAL_ON_CREATE)
|
||||
!= 0;
|
||||
// when user is created in ephemeral mode via FLAG_EPHEMERAL
|
||||
// its state cannot be changed.
|
||||
// FLAG_EPHEMERAL_ON_CREATE is used to keep track of this state
|
||||
if (!isEphemeralOnCreateUser) {
|
||||
isSuccess = true;
|
||||
if (isEphemeralUser != enableEphemeral) {
|
||||
if (enableEphemeral) {
|
||||
userInfo.flags |= UserInfo.FLAG_EPHEMERAL;
|
||||
} else {
|
||||
userInfo.flags &= ~UserInfo.FLAG_EPHEMERAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void setUserAdmin(@UserIdInt int userId) {
|
||||
for (int i = 0; i < mUserProfileInfos.size(); i++) {
|
||||
mUserProfileInfos.get(i).flags |= UserInfo.FLAG_ADMIN;
|
||||
}
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean isGuestUser() {
|
||||
return mIsGuestUser;
|
||||
}
|
||||
|
||||
public void setGuestUser(boolean isGuestUser) {
|
||||
mIsGuestUser = isGuestUser;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.testutils.shadow;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(Utils.class)
|
||||
public class ShadowUtils {
|
||||
|
||||
private static FingerprintManager sFingerprintManager = null;
|
||||
private static FaceManager sFaceManager = null;
|
||||
private static boolean sIsUserAMonkey;
|
||||
private static boolean sIsDemoUser;
|
||||
private static ComponentName sDeviceOwnerComponentName;
|
||||
private static Map<String, String> sAppNameMap;
|
||||
private static boolean sIsSystemAlertWindowEnabled;
|
||||
private static boolean sIsVoiceCapable;
|
||||
private static ArraySet<String> sResultLinks = new ArraySet<>();
|
||||
private static boolean sIsBatteryPresent;
|
||||
private static boolean sIsMultipleBiometricsSupported;
|
||||
|
||||
@Implementation
|
||||
protected static int enforceSameOwner(Context context, int userId) {
|
||||
return userId;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static FingerprintManager getFingerprintManagerOrNull(Context context) {
|
||||
return sFingerprintManager;
|
||||
}
|
||||
|
||||
public static void setFingerprintManager(FingerprintManager fingerprintManager) {
|
||||
sFingerprintManager = fingerprintManager;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static FaceManager getFaceManagerOrNull(Context context) {
|
||||
return sFaceManager;
|
||||
}
|
||||
|
||||
public static void setFaceManager(FaceManager faceManager) {
|
||||
sFaceManager = faceManager;
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
sFingerprintManager = null;
|
||||
sIsUserAMonkey = false;
|
||||
sIsDemoUser = false;
|
||||
sIsVoiceCapable = false;
|
||||
sResultLinks = new ArraySet<>();
|
||||
sIsBatteryPresent = true;
|
||||
sIsMultipleBiometricsSupported = false;
|
||||
}
|
||||
|
||||
public static void setIsDemoUser(boolean isDemoUser) {
|
||||
sIsDemoUser = isDemoUser;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static boolean isDemoUser(Context context) {
|
||||
return sIsDemoUser;
|
||||
}
|
||||
|
||||
public static void setIsUserAMonkey(boolean isUserAMonkey) {
|
||||
sIsUserAMonkey = isUserAMonkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Monkey is running.
|
||||
*/
|
||||
@Implementation
|
||||
protected static boolean isMonkeyRunning() {
|
||||
return sIsUserAMonkey;
|
||||
}
|
||||
|
||||
public static void setDeviceOwnerComponent(ComponentName componentName) {
|
||||
sDeviceOwnerComponentName = componentName;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static ComponentName getDeviceOwnerComponent(Context context) {
|
||||
return sDeviceOwnerComponentName;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static int getManagedProfileId(UserManager um, int parentUserId) {
|
||||
return UserHandle.USER_NULL;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static CharSequence getApplicationLabel(Context context, String packageName) {
|
||||
if (sAppNameMap != null) {
|
||||
return sAppNameMap.get(packageName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isPackageEnabled(Context context, String packageName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void setApplicationLabel(String packageName, String appLabel) {
|
||||
if (sAppNameMap == null) {
|
||||
sAppNameMap = new HashMap<>();
|
||||
}
|
||||
sAppNameMap.put(packageName, appLabel);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isSystemAlertWindowEnabled(Context context) {
|
||||
return sIsSystemAlertWindowEnabled;
|
||||
}
|
||||
|
||||
public static void setIsSystemAlertWindowEnabled(boolean enabled) {
|
||||
sIsSystemAlertWindowEnabled = enabled;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isVoiceCapable(Context context) {
|
||||
return sIsVoiceCapable;
|
||||
}
|
||||
|
||||
public static void setIsVoiceCapable(boolean isVoiceCapable) {
|
||||
sIsVoiceCapable = isVoiceCapable;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static ArraySet<String> getHandledDomains(PackageManager pm, String packageName) {
|
||||
return sResultLinks;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static Drawable getBadgedIcon(Context context, ApplicationInfo appInfo) {
|
||||
return new ColorDrawable(0);
|
||||
}
|
||||
|
||||
public static void setHandledDomains(ArraySet<String> links) {
|
||||
sResultLinks = links;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isBatteryPresent(Context context) {
|
||||
return sIsBatteryPresent;
|
||||
}
|
||||
|
||||
public static void setIsBatteryPresent(boolean isBatteryPresent) {
|
||||
sIsBatteryPresent = isBatteryPresent;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean isMultipleBiometricsSupported(Context context) {
|
||||
return sIsMultipleBiometricsSupported;
|
||||
}
|
||||
|
||||
public static void setIsMultipleBiometricsSupported(boolean isMultipleBiometricsSupported) {
|
||||
sIsMultipleBiometricsSupported = isMultipleBiometricsSupported;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user