Merge "Removing obsolete robo test setup" into sc-v2-dev

This commit is contained in:
TreeHugger Robot
2021-09-09 15:02:57 +00:00
committed by Android (Google) Code Review
16 changed files with 7 additions and 888 deletions
-62
View File
@@ -1,62 +0,0 @@
// 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.
//
// Launcher Robolectric test target.
//
// "robolectric_android-all-stub", not needed, we write our own stubs
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "packages_apps_Launcher3_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["packages_apps_Launcher3_license"],
}
filegroup {
name: "launcher3-robolectric-resources",
path: "resources",
srcs: ["resources/*"],
}
filegroup {
name: "launcher3-robolectric-src",
srcs: ["src/**/*.java"],
}
android_robolectric_test {
name: "LauncherRoboTests",
srcs: [
":launcher3-robolectric-src",
],
java_resources: [":launcher3-robolectric-resources"],
static_libs: [
"truth-prebuilt",
"androidx.test.espresso.contrib",
"androidx.test.espresso.core",
"androidx.test.espresso.intents",
"androidx.test.ext.junit",
"androidx.test.runner",
"androidx.test.rules",
"mockito-robolectric-prebuilt",
"SystemUISharedLib",
],
robolectric_prebuilt_version: "4.5.1",
instrumentation_for: "Launcher3",
test_options: {
timeout: 36000,
},
}
@@ -1,36 +0,0 @@
<!--
Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- overlayable_icons references all of the drawables in this package
that are being overlayed by resource overlays. If you remove/rename
any of these resources, you must also change the resource overlay icons.-->
<array name="overlayable_icons">
<item>@drawable/ic_corp</item>
<item>@drawable/ic_drag_handle</item>
<item>@drawable/ic_hourglass_top</item>
<item>@drawable/ic_info_no_shadow</item>
<item>@drawable/ic_install_no_shadow</item>
<item>@drawable/ic_palette</item>
<item>@drawable/ic_pin</item>
<item>@drawable/ic_remove_no_shadow</item>
<item>@drawable/ic_setting</item>
<item>@drawable/ic_smartspace_preferences</item>
<item>@drawable/ic_split_screen</item>
<item>@drawable/ic_uninstall_no_shadow</item>
<item>@drawable/ic_warning</item>
<item>@drawable/ic_widget</item>
</array>
</resources>
@@ -1,15 +0,0 @@
sdk=30
shadows= \
com.android.launcher3.shadows.LShadowAppPredictionManager \
com.android.launcher3.shadows.LShadowAppWidgetManager \
com.android.launcher3.shadows.LShadowBackupManager \
com.android.launcher3.shadows.LShadowDisplay \
com.android.launcher3.shadows.LShadowLauncherApps \
com.android.launcher3.shadows.ShadowDeviceFlag \
com.android.launcher3.shadows.ShadowLooperExecutor \
com.android.launcher3.shadows.ShadowMainThreadInitializedObject \
com.android.launcher3.shadows.ShadowOverrides \
com.android.launcher3.shadows.ShadowSurfaceTransactionApplier \
application=com.android.launcher3.util.LauncherTestApplication
@@ -1,38 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import static org.mockito.Mockito.mock;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppPredictor;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
/**
* Shadow for {@link AppPredictionManager} which create mock predictors
*/
@Implements(value = AppPredictionManager.class)
public class LShadowAppPredictionManager {
@Implementation
public AppPredictor createAppPredictionSession(AppPredictionContext predictionContext) {
return mock(AppPredictor.class);
}
}
@@ -1,48 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.os.Process;
import android.os.UserHandle;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowAppWidgetManager;
import java.util.List;
import java.util.stream.Collectors;
/**
* Extension of {@link ShadowAppWidgetManager} with missing shadow methods
*/
@Implements(value = AppWidgetManager.class)
public class LShadowAppWidgetManager extends ShadowAppWidgetManager {
@Override
protected List<AppWidgetProviderInfo> getInstalledProviders() {
return getInstalledProvidersForProfile(null);
}
@Implementation
public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(UserHandle profile) {
UserHandle user = profile == null ? Process.myUserHandle() : profile;
return super.getInstalledProviders().stream().filter(
info -> user.equals(info.getProfile())).collect(Collectors.toList());
}
}
@@ -1,45 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import android.app.backup.BackupManager;
import android.os.UserHandle;
import android.util.LongSparseArray;
import androidx.annotation.Nullable;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowBackupManager;
/**
* Extension of {@link ShadowBackupManager} with missing shadow methods
*/
@Implements(value = BackupManager.class)
public class LShadowBackupManager extends ShadowBackupManager {
private LongSparseArray<UserHandle> mProfileMapping = new LongSparseArray<>();
public void addProfile(long userSerial, UserHandle userHandle) {
mProfileMapping.put(userSerial, userHandle);
}
@Implementation
@Nullable
public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
return mProfileMapping.get(ancestralSerialNumber);
}
}
@@ -1,54 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import static org.robolectric.shadow.api.Shadow.directlyOn;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.Display;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.shadows.ShadowDisplay;
/**
* Extension of {@link ShadowDisplay} with missing shadow methods
*/
@Implements(value = Display.class)
public class LShadowDisplay extends ShadowDisplay {
private final Rect mInsets = new Rect();
@RealObject Display realObject;
/**
* Sets the insets for the display
*/
public void setInsets(Rect insets) {
mInsets.set(insets);
}
@Override
protected void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
directlyOn(realObject, Display.class).getCurrentSizeRange(outSmallestSize, outLargestSize);
outSmallestSize.x -= mInsets.left + mInsets.right;
outLargestSize.x -= mInsets.left + mInsets.right;
outSmallestSize.y -= mInsets.top + mInsets.bottom;
outLargestSize.y -= mInsets.top + mInsets.bottom;
}
}
@@ -1,136 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import static org.robolectric.util.ReflectionHelpers.ClassParameter;
import static org.robolectric.util.ReflectionHelpers.callConstructor;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.os.UserHandle;
import android.util.ArraySet;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowLauncherApps;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
/**
* Extension of {@link ShadowLauncherApps} with missing shadow methods
*/
@Implements(value = LauncherApps.class)
public class LShadowLauncherApps extends ShadowLauncherApps {
public final ArraySet<PackageUserKey> disabledApps = new ArraySet<>();
public final ArraySet<ComponentKey> disabledActivities = new ArraySet<>();
@Implementation
@Override
protected List<ShortcutInfo> getShortcuts(LauncherApps.ShortcutQuery query, UserHandle user) {
try {
return super.getShortcuts(query, user);
} catch (UnsupportedOperationException e) {
return Collections.emptyList();
}
}
@Implementation
protected boolean isPackageEnabled(String packageName, UserHandle user) {
return !disabledApps.contains(new PackageUserKey(packageName, user));
}
@Implementation
protected boolean isActivityEnabled(ComponentName component, UserHandle user) {
return !disabledActivities.contains(new ComponentKey(component, user));
}
@Implementation
protected LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
ResolveInfo ri = RuntimeEnvironment.application.getPackageManager()
.resolveActivity(intent, 0);
return ri == null ? null : getLauncherActivityInfo(ri.activityInfo, user);
}
public LauncherActivityInfo getLauncherActivityInfo(
ActivityInfo activityInfo, UserHandle user) {
return callConstructor(LauncherActivityInfo.class,
ClassParameter.from(Context.class, RuntimeEnvironment.application),
ClassParameter.from(ActivityInfo.class, activityInfo),
ClassParameter.from(UserHandle.class, user));
}
@Implementation
public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user)
throws PackageManager.NameNotFoundException {
return RuntimeEnvironment.application.getPackageManager()
.getApplicationInfo(packageName, flags);
}
@Implementation
public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
Intent intent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(packageName);
return RuntimeEnvironment.application.getPackageManager().queryIntentActivities(intent, 0)
.stream()
.map(ri -> getLauncherActivityInfo(ri.activityInfo, user))
.collect(Collectors.toList());
}
@Implementation
public boolean hasShortcutHostPermission() {
return true;
}
@Implementation
public List<PackageInstaller.SessionInfo> getAllPackageInstallerSessions() {
return RuntimeEnvironment.application.getPackageManager().getPackageInstaller()
.getAllSessions();
}
@Implementation
public void registerPackageInstallerSessionCallback(
Executor executor, PackageInstaller.SessionCallback callback) {
}
@Override
protected List<LauncherActivityInfo> getShortcutConfigActivityList(String packageName,
UserHandle user) {
Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName);
return RuntimeEnvironment.application.getPackageManager().queryIntentActivities(intent, 0)
.stream()
.map(ri -> getLauncherActivityInfo(ri.activityInfo, user))
.collect(Collectors.toList());
}
}
@@ -1,62 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import android.content.Context;
import androidx.annotation.Nullable;
import com.android.launcher3.uioverrides.DeviceFlag;
import com.android.launcher3.util.LooperExecutor;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.shadow.api.Shadow;
/**
* Shadow for {@link LooperExecutor} to provide reset functionality for static executors.
*/
@Implements(value = DeviceFlag.class, isInAndroidSdk = false)
public class ShadowDeviceFlag {
@RealObject private DeviceFlag mRealObject;
@Nullable private Boolean mValue;
/**
* Mock change listener as it uses internal system classes not available to robolectric
*/
@Implementation
protected void addChangeListener(Context context, Runnable r) { }
@Implementation
protected static boolean getDeviceValue(String key, boolean defaultValue) {
return defaultValue;
}
@Implementation
public boolean get() {
if (mValue != null) {
return mValue;
}
return Shadow.directlyOn(mRealObject, DeviceFlag.class, "get");
}
public void setValue(boolean value) {
mValue = new Boolean(value);
}
}
@@ -1,63 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import static com.android.launcher3.util.Executors.createAndStartNewLooper;
import static org.robolectric.shadow.api.Shadow.directlyOn;
import static org.robolectric.util.ReflectionHelpers.setField;
import android.os.Handler;
import androidx.annotation.Nullable;
import com.android.launcher3.util.LooperExecutor;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
/**
* Shadow for {@link LooperExecutor} to provide reset functionality for static executors.
*/
@Implements(value = LooperExecutor.class, isInAndroidSdk = false)
public class ShadowLooperExecutor {
@RealObject private LooperExecutor mRealExecutor;
private Handler mOverriddenHandler;
@Implementation
protected Handler getHandler() {
if (mOverriddenHandler != null) {
return mOverriddenHandler;
}
Handler handler = directlyOn(mRealExecutor, LooperExecutor.class, "getHandler");
Thread thread = handler.getLooper().getThread();
if (!thread.isAlive()) {
// Robolectric destroys all loopers at the end of every test. Since Launcher maintains
// some static threads, they need to be reinitialized in case they were destroyed.
setField(mRealExecutor, "mHandler",
new Handler(createAndStartNewLooper(thread.getName())));
}
return directlyOn(mRealExecutor, LooperExecutor.class, "getHandler");
}
public void setHandler(@Nullable Handler handler) {
mOverriddenHandler = handler;
}
}
@@ -1,61 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import static org.robolectric.shadow.api.Shadow.invokeConstructor;
import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.MainThreadInitializedObject.ObjectProvider;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
import java.util.WeakHashMap;
/**
* Shadow for {@link MainThreadInitializedObject} to provide reset functionality for static sObjects
*/
@Implements(value = MainThreadInitializedObject.class, isInAndroidSdk = false)
public class ShadowMainThreadInitializedObject {
// Keep reference to all created MainThreadInitializedObject so they can be cleared after test
private static Set<MainThreadInitializedObject> sObjects =
Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
@RealObject private MainThreadInitializedObject mRealObject;
@Implementation
protected void __constructor__(ObjectProvider provider) {
invokeConstructor(MainThreadInitializedObject.class, mRealObject,
from(ObjectProvider.class, provider));
sObjects.add(mRealObject);
}
/**
* Resets all the initialized sObjects to be null
*/
public static void resetInitializedObjects() {
for (MainThreadInitializedObject object : new ArrayList<>(sObjects)) {
object.initializeForTesting(null);
}
}
}
@@ -1,61 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import android.content.Context;
import com.android.launcher3.util.MainThreadInitializedObject.ObjectProvider;
import com.android.launcher3.util.ResourceBasedOverride;
import com.android.launcher3.util.ResourceBasedOverride.Overrides;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
import java.util.HashMap;
import java.util.Map;
/**
* Shadow for {@link Overrides} to provide custom overrides for test
*/
@Implements(value = Overrides.class, isInAndroidSdk = false)
public class ShadowOverrides {
private static Map<Class, ObjectProvider> sProviderMap = new HashMap<>();
@Implementation
public static <T extends ResourceBasedOverride> T getObject(
Class<T> clazz, Context context, int resId) {
ObjectProvider<T> provider = sProviderMap.get(clazz);
if (provider != null) {
return provider.get(context);
}
return Shadow.directlyOn(Overrides.class, "getObject",
ClassParameter.from(Class.class, clazz),
ClassParameter.from(Context.class, context),
ClassParameter.from(int.class, resId));
}
public static <T> void setProvider(Class<T> clazz, ObjectProvider<T> provider) {
sProviderMap.put(clazz, provider);
}
public static void clearProvider() {
sProviderMap.clear();
}
}
@@ -1,42 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.shadows;
import static org.robolectric.shadow.api.Shadow.invokeConstructor;
import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
import android.view.View;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
/**
* Shadow for SurfaceTransactionApplier to override default functionality
*/
@Implements(className = "com.android.quickstep.util.SurfaceTransactionApplier",
isInAndroidSdk = false)
public class ShadowSurfaceTransactionApplier {
@RealObject
private Object mRealObject;
@Implementation
protected void __constructor__(View view) {
invokeConstructor(mRealObject.getClass(), mRealObject, from(View.class, null));
}
}
@@ -1,50 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.util;
import static org.mockito.Mockito.mock;
import android.app.Application;
import com.android.launcher3.shadows.ShadowMainThreadInitializedObject;
import com.android.launcher3.shadows.ShadowOverrides;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import org.robolectric.TestLifecycleApplication;
import org.robolectric.shadows.ShadowLog;
import java.lang.reflect.Method;
public class LauncherTestApplication extends Application implements TestLifecycleApplication {
@Override
public void beforeTest(Method method) {
ShadowLog.stream = System.out;
// Disable plugins
PluginManagerWrapper.INSTANCE.initializeForTesting(mock(PluginManagerWrapper.class));
}
@Override
public void prepareTest(Object test) { }
@Override
public void afterTest(Method method) {
ShadowLog.stream = null;
ShadowMainThreadInitializedObject.resetInitializedObjects();
ShadowOverrides.clearProvider();
}
}
@@ -1,115 +0,0 @@
/*
* 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.launcher3.util;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.net.Uri;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class SettingsCacheTest {
public static final Uri KEY_SYSTEM_URI_TEST1 = Uri.parse("content://settings/system/test1");
public static final Uri KEY_SYSTEM_URI_TEST2 = Uri.parse("content://settings/system/test2");;
private SettingsCache.OnChangeListener mChangeListener;
private SettingsCache mSettingsCache;
@Before
public void setup() {
mChangeListener = mock(SettingsCache.OnChangeListener.class);
Context targetContext = RuntimeEnvironment.application;
mSettingsCache = SettingsCache.INSTANCE.get(targetContext);
mSettingsCache.register(KEY_SYSTEM_URI_TEST1, mChangeListener);
}
@Test
public void listenerCalledOnChange() {
mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1);
verify(mChangeListener, times(1)).onSettingsChanged(true);
}
@Test
public void getValueRespectsDefaultValue() {
// Case of key not found
boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0);
assertFalse(val);
}
@Test
public void getValueHitsCache() {
mSettingsCache.setKeyCache(Collections.singletonMap(KEY_SYSTEM_URI_TEST1, true));
boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0);
assertTrue(val);
}
@Test
public void getValueUpdatedCache() {
// First ensure there's nothing in cache
boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0);
assertFalse(val);
mSettingsCache.setKeyCache(Collections.singletonMap(KEY_SYSTEM_URI_TEST1, true));
val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0);
assertTrue(val);
}
@Test
public void multipleListenersSingleKey() {
SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class);
mSettingsCache.register(KEY_SYSTEM_URI_TEST1, secondListener);
mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1);
verify(mChangeListener, times(1)).onSettingsChanged(true);
verify(secondListener, times(1)).onSettingsChanged(true);
}
@Test
public void singleListenerMultipleKeys() {
SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class);
mSettingsCache.register(KEY_SYSTEM_URI_TEST2, secondListener);
mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1);
mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST2);
verify(mChangeListener, times(1)).onSettingsChanged(true);
verify(secondListener, times(1)).onSettingsChanged(true);
}
@Test
public void sameListenerMultipleKeys() {
SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class);
mSettingsCache.register(KEY_SYSTEM_URI_TEST2, mChangeListener);
mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1);
mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST2);
verify(mChangeListener, times(2)).onSettingsChanged(true);
verify(secondListener, times(0)).onSettingsChanged(true);
}
}
@@ -55,6 +55,7 @@ import com.android.systemui.shared.plugins.PluginPrefs;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -75,6 +76,7 @@ public class SettingsActivityTest {
}
@Test
@Ignore // b/199309785
public void testSettings_aboutTap_launchesActivity() {
ActivityScenario.launch(SettingsActivity.class);
onView(withId(R.id.recycler_view)).perform(
@@ -88,6 +90,7 @@ public class SettingsActivityTest {
}
@Test
@Ignore // b/199309785
public void testSettings_developerOptionsTap_launchesActivityWithFragment() {
PluginPrefs.setHasPlugins(mApplicationContext);
ActivityScenario.launch(SettingsActivity.class);
@@ -100,6 +103,7 @@ public class SettingsActivityTest {
}
@Test
@Ignore // b/199309785
public void testSettings_aboutScreenIntent() {
Bundle fragmentArgs = new Bundle();
fragmentArgs.putString(ARG_PREFERENCE_ROOT, "about_screen");
@@ -114,6 +118,7 @@ public class SettingsActivityTest {
}
@Test
@Ignore // b/199309785
public void testSettings_developerOptionsFragmentIntent() {
Intent intent = new Intent(mApplicationContext, SettingsActivity.class)
.putExtra(EXTRA_FRAGMENT, DeveloperOptionsFragment.class.getName());
@@ -125,6 +130,7 @@ public class SettingsActivityTest {
}
@Test
@Ignore // b/199309785
public void testSettings_intentWithUnknownFragment() {
String fragmentClass = PreferenceFragmentCompat.class.getName();
Intent intent = new Intent(mApplicationContext, SettingsActivity.class)
@@ -139,6 +145,7 @@ public class SettingsActivityTest {
}
@Test
@Ignore // b/199309785
public void testSettings_backButtonFinishesActivity() {
Bundle fragmentArgs = new Bundle();
fragmentArgs.putString(ARG_PREFERENCE_ROOT, "about_screen");