Setup external/robolectric for SettingsRoboTests
Current failing tests: ab/I64100010182936387 Had to Ignore some of com.android.settings.accessibility tests, which will be fixed separately Bug: 261728063 Test: atest SettingsRoboTests -- --test-arg com.android.tradefed.testtype.IsolatedHostTest:java-flags:-XX:CompressedClassSpaceSize=3g Change-Id: I4a0cb992db924936826e0c9808accc78dddb5f30
This commit is contained in:
@@ -23,7 +23,7 @@ import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(ActivityManager.class)
|
||||
public class ShadowActivityManager {
|
||||
public class ShadowActivityManager extends org.robolectric.shadows.ShadowActivityManager {
|
||||
private static int sCurrentUserId = 0;
|
||||
private static IActivityManager sService = null;
|
||||
|
||||
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 android.app.ApplicationPackageManager;
|
||||
import android.content.pm.PackageInfo;
|
||||
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(ApplicationPackageManager.class)
|
||||
public class ShadowApplicationPackageManager
|
||||
extends org.robolectric.shadows.ShadowApplicationPackageManager {
|
||||
static final Map<Integer, List<String>> packagesForUserId = new HashMap<>();
|
||||
|
||||
public void setInstalledPackagesForUserId(int userId, List<String> packages) {
|
||||
packagesForUserId.put(userId, packages);
|
||||
for (String packageName : packages) {
|
||||
addPackage(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
|
||||
List<PackageInfo> packages = new ArrayList<>();
|
||||
for (String packageName : packagesForUserId.getOrDefault(userId, new ArrayList<>())) {
|
||||
try {
|
||||
packages.add(getPackageInfo(packageName, flags));
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
}
|
@@ -31,12 +31,12 @@ import android.media.AudioDeviceCallback;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Handler;
|
||||
|
||||
import java.util.List;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Implements(value = AudioManager.class)
|
||||
public class ShadowAudioManager extends org.robolectric.shadows.ShadowAudioManager {
|
||||
@@ -46,7 +46,7 @@ public class ShadowAudioManager extends org.robolectric.shadows.ShadowAudioManag
|
||||
private List<AudioDeviceCallback> mDeviceCallbacks = new ArrayList<>();
|
||||
|
||||
@Implementation
|
||||
private int getRingerModeInternal() {
|
||||
protected int getRingerModeInternal() {
|
||||
return mRingerMode;
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,7 @@ public class ShadowAuthenticationHelper {
|
||||
static final String[] LABELS = {"LABEL1", "LABEL2", "LABEL3", "LABEL4"};
|
||||
private static String[] sEnabledAccount = TYPES;
|
||||
|
||||
@Implementation
|
||||
protected void __constructor__(Context context, UserHandle userHandle,
|
||||
AuthenticatorHelper.OnAccountsUpdateListener listener) {
|
||||
}
|
||||
|
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.content.pm.CrossProfileApps;
|
||||
import android.content.pm.ICrossProfileApps;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Implements(CrossProfileApps.class)
|
||||
public class ShadowCrossProfileApps extends org.robolectric.shadows.ShadowCrossProfileApps {
|
||||
private static final Set<String> configurableInteractAcrossProfilePackages = new HashSet<>();
|
||||
private Context mContext;
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
@Implementation
|
||||
protected void __constructor__(Context context, ICrossProfileApps service) {
|
||||
super.__constructor__(context, service);
|
||||
this.mContext = context;
|
||||
this.mPackageManager = context.getPackageManager();
|
||||
}
|
||||
public void addCrossProfilePackage(String packageName) {
|
||||
configurableInteractAcrossProfilePackages.add(packageName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean canConfigureInteractAcrossProfiles(@NonNull String packageName) {
|
||||
return configurableInteractAcrossProfilePackages.contains(packageName);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected boolean canUserAttemptToConfigureInteractAcrossProfiles(@NonNull String packageName) {
|
||||
PackageInfo packageInfo;
|
||||
try {
|
||||
packageInfo = mPackageManager.getPackageInfo(packageName, /* flags= */ 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
if (packageInfo == null || packageInfo.requestedPermissions == null) {
|
||||
return false;
|
||||
}
|
||||
return Arrays.asList(packageInfo.requestedPermissions).contains(
|
||||
Manifest.permission.INTERACT_ACROSS_PROFILES);
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.content.Context;
|
||||
import android.text.format.DateFormat;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Implements(DateFormat.class)
|
||||
public class ShadowDateFormat {
|
||||
|
||||
@Implementation
|
||||
protected static java.text.DateFormat getDateFormat(Context context) {
|
||||
return new java.text.SimpleDateFormat("MMM-dd-yyyy", Locale.ROOT);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static java.text.DateFormat getLongDateFormat(Context context) {
|
||||
return new java.text.SimpleDateFormat("MMMM dd, yyyy", Locale.ROOT);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static java.text.DateFormat getTimeFormat(Context context) {
|
||||
return new java.text.SimpleDateFormat("HH:mm:ss", Locale.ROOT);
|
||||
}
|
||||
}
|
@@ -1,8 +1,25 @@
|
||||
/*
|
||||
* 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 android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
import static android.os.Build.VERSION_CODES.O;
|
||||
import static android.os.Build.VERSION_CODES.Q;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -22,10 +39,12 @@ import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Implements(DevicePolicyManager.class)
|
||||
public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDevicePolicyManager {
|
||||
@@ -34,12 +53,14 @@ public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDev
|
||||
private final Map<String, Integer> mDeviceOwnerTypes = new HashMap<>();
|
||||
private Map<Integer, CharSequence> mSupportMessagesMap = new HashMap<>();
|
||||
private boolean mIsAdminActiveAsUser = false;
|
||||
private ComponentName mProfileOwner;
|
||||
private ComponentName mDeviceOwnerComponentName;
|
||||
private ManagedSubscriptionsPolicy mManagedSubscriptionsPolicy;
|
||||
private int mDeviceOwnerUserId = -1;
|
||||
private int mPasswordMinQuality = PASSWORD_QUALITY_UNSPECIFIED;
|
||||
private int mPasswordMinLength = 0;
|
||||
private int mPasswordMinSymbols = 0;
|
||||
private Set<String> mCrossProfileCalendarPackages = Collections.emptySet();
|
||||
|
||||
private List<String> mPermittedAccessibilityServices = null;
|
||||
|
||||
@@ -149,4 +170,32 @@ public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDev
|
||||
ApplicationProvider.getApplicationContext()
|
||||
.getSystemService(DevicePolicyManager.class));
|
||||
}
|
||||
|
||||
// BEGIN-INTERNAL
|
||||
@Implementation(minSdk = Q)
|
||||
protected Set<String> getCrossProfileCalendarPackages() {
|
||||
return mCrossProfileCalendarPackages;
|
||||
}
|
||||
|
||||
@Implementation(minSdk = Q)
|
||||
public void setCrossProfileCalendarPackages(ComponentName admin, Set<String> packageNames) {
|
||||
enforceProfileOwner(admin);
|
||||
mCrossProfileCalendarPackages = packageNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the admin as active admin and profile owner.
|
||||
*
|
||||
* @see DevicePolicyManager#getProfileOwner()
|
||||
*/
|
||||
public void setProfileOwner(ComponentName admin) {
|
||||
setActiveAdmin(admin);
|
||||
mProfileOwner = admin;
|
||||
}
|
||||
|
||||
private void enforceProfileOwner(ComponentName admin) {
|
||||
if (!admin.equals(mProfileOwner)) {
|
||||
throw new SecurityException("[" + admin + "] is not a profile owner");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
@Implements(ShadowDrawable.class)
|
||||
public class ShadowDrawable extends org.robolectric.shadows.ShadowDrawable {
|
||||
private static int sDefaultIntrinsicWidth = -1;
|
||||
private int mIntrinsicWidth = sDefaultIntrinsicWidth;
|
||||
|
||||
@Implementation
|
||||
public int getIntrinsicWidth() {
|
||||
return mIntrinsicWidth;
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
|
||||
|
||||
import android.hardware.input.IInputManager;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.os.Handler;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Shadow for {@link InputManager} that has accessors for registered
|
||||
* {@link InputManager.InputDeviceListener}s.
|
||||
*/
|
||||
@Implements(value = InputManager.class, callThroughByDefault = false)
|
||||
public class ShadowInputManager extends org.robolectric.shadows.ShadowInputManager {
|
||||
|
||||
private List<InputManager.InputDeviceListener> mInputDeviceListeners;
|
||||
|
||||
@Implementation
|
||||
protected void __constructor__(IInputManager service) {
|
||||
mInputDeviceListeners = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static InputManager getInstance() {
|
||||
return ReflectionHelpers.callConstructor(
|
||||
InputManager.class,
|
||||
from(IInputManager.class, null));
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void registerInputDeviceListener(InputManager.InputDeviceListener listener,
|
||||
Handler handler) {
|
||||
// TODO: Use handler.
|
||||
if (!mInputDeviceListeners.contains(listener)) {
|
||||
mInputDeviceListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected void unregisterInputDeviceListener(InputManager.InputDeviceListener listener) {
|
||||
mInputDeviceListeners.remove(listener);
|
||||
}
|
||||
}
|
@@ -28,7 +28,7 @@ public class ShadowKeyStore {
|
||||
private static boolean sIsHardwareBacked;
|
||||
|
||||
@Resetter
|
||||
public void reset() {
|
||||
public static void reset() {
|
||||
sIsHardwareBacked = false;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 android.service.persistentdata.PersistentDataBlockManager;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
@Implements(PersistentDataBlockManager.class)
|
||||
public class ShadowPersistentDataBlockManager {
|
||||
private static int sDataBlockSize = 0;
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sDataBlockSize = 0;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected int getDataBlockSize() {
|
||||
return sDataBlockSize;
|
||||
}
|
||||
|
||||
public static void setDataBlockSize(int dataBlockSize) {
|
||||
sDataBlockSize = dataBlockSize;
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.provider.Settings;
|
||||
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
import org.robolectric.shadows.ShadowSettings;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
@Implements(value = Settings.System.class)
|
||||
public class ShadowSystemSettings extends ShadowSettings.ShadowSystem {
|
||||
private static final Map<ContentResolver, Map<String, String>> sDataMap = new WeakHashMap<>();
|
||||
|
||||
@Resetter
|
||||
public static void reset() {
|
||||
sDataMap.clear();
|
||||
}
|
||||
|
||||
@Implementation(minSdk = JELLY_BEAN_MR1)
|
||||
protected static boolean putStringForUser(ContentResolver cr, String name, String value,
|
||||
int userHandle) {
|
||||
return putString(cr, name, value);
|
||||
}
|
||||
|
||||
@Implementation(minSdk = JELLY_BEAN_MR1)
|
||||
protected static String getStringForUser(ContentResolver cr, String name, int userHandle) {
|
||||
return getString(cr, name);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static boolean putString(ContentResolver cr, String name, String value) {
|
||||
get(cr).put(name, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
protected static String getString(ContentResolver cr, String name) {
|
||||
return get(cr).get(name);
|
||||
}
|
||||
|
||||
private static Map<String, String> get(ContentResolver cr) {
|
||||
Map<String, String> map = sDataMap.get(cr);
|
||||
if (map == null) {
|
||||
map = new HashMap<>();
|
||||
sDataMap.put(cr, map);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user