From e1398d13500e952f9e520b71733d3234ab4fd454 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Wed, 28 Mar 2018 16:07:55 -0700 Subject: [PATCH 1/2] Remove duplicate framework classes/robotest compile stub Bug: 76167422 Test: robotests Change-Id: Iad16b06e54bd7290fd363c3abebdb8c66434c0e2 --- .../android/app/admin/PasswordMetrics.java | 49 ------- .../bluetooth/BluetoothCodecConfig.java | 54 -------- .../android/content/om/IOverlayManager.java | 36 ----- .../src/android/net/NetworkScorerAppData.java | 130 ------------------ .../android/print/PrintServicesLoader.java | 19 --- .../internal/app/ColorDisplayController.java | 44 ------ .../internal/app/LocalePickerWithRegion.java | 11 -- 7 files changed, 343 deletions(-) delete mode 100644 tests/robotests/src/android/app/admin/PasswordMetrics.java delete mode 100644 tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java delete mode 100644 tests/robotests/src/android/content/om/IOverlayManager.java delete mode 100644 tests/robotests/src/android/net/NetworkScorerAppData.java delete mode 100644 tests/robotests/src/android/print/PrintServicesLoader.java delete mode 100644 tests/robotests/src/com/android/internal/app/ColorDisplayController.java delete mode 100644 tests/robotests/src/com/android/internal/app/LocalePickerWithRegion.java diff --git a/tests/robotests/src/android/app/admin/PasswordMetrics.java b/tests/robotests/src/android/app/admin/PasswordMetrics.java deleted file mode 100644 index a46130661b0..00000000000 --- a/tests/robotests/src/android/app/admin/PasswordMetrics.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.admin; - -import android.annotation.NonNull; - -/** - * Stub implementation of framework's PasswordMetrics for Robolectric tests. Otherwise Robolectric - * is throwing ClassNotFoundError. - * - * TODO: Remove this class when Robolectric supports O - */ -public class PasswordMetrics { - - // Maximum allowed number of repeated or ordered characters in a sequence before we'll - // consider it a complex PIN/password. - public static final int MAX_ALLOWED_SEQUENCE = 3; - - public int length = 0; - public int letters = 0; - public int upperCase = 0; - public int lowerCase = 0; - public int numeric = 0; - public int symbols = 0; - public int nonLetter = 0; - - public static int maxLengthSequence(@NonNull String string) { - // Stub implementation - return 1; - } - - public static PasswordMetrics computeForPassword(@NonNull String password) { - return new PasswordMetrics(); - } -} \ No newline at end of file diff --git a/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java b/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java deleted file mode 100644 index ee7bdb00276..00000000000 --- a/tests/robotests/src/android/bluetooth/BluetoothCodecConfig.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth; - -/** - * A placeholder class to prevent ClassNotFound exceptions caused by lack of visibility. - */ -public class BluetoothCodecConfig { - - public static final int SAMPLE_RATE_NONE = 0; - public static final int SAMPLE_RATE_48000 = 0x1 << 1; - public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000; - public static final int SOURCE_CODEC_TYPE_AAC = 1; - public static final int CODEC_PRIORITY_DEFAULT = 0; - public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000; - public static final int BITS_PER_SAMPLE_NONE = 0; - public static final int CHANNEL_MODE_NONE = 0; - public static final int BITS_PER_SAMPLE_24 = 0x1 << 1; - public static final int CHANNEL_MODE_STEREO = 0x1 << 1; - - public int getSampleRate() { - return 0; - } - - public int getCodecType() { - return 0; - } - - public int getBitsPerSample() { - return 0; - } - - public int getChannelMode() { - return 0; - } - - public long getCodecSpecific1() { - return 0; - } -} diff --git a/tests/robotests/src/android/content/om/IOverlayManager.java b/tests/robotests/src/android/content/om/IOverlayManager.java deleted file mode 100644 index 12f7f7f8e57..00000000000 --- a/tests/robotests/src/android/content/om/IOverlayManager.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package android.content.om; - -import android.os.IBinder; - -import java.util.List; - -public interface IOverlayManager { - - OverlayInfo getOverlayInfo(String packageName, int userId); - - List getOverlayInfosForTarget(String targetPackageName, int userId); - - boolean setEnabled(String packageName, boolean enabled, int userId); - - boolean setEnabledExclusiveInCategory(String packageName, int userId); - - class Stub { - public static IOverlayManager asInterface(IBinder b) { - return null; - } - } -} diff --git a/tests/robotests/src/android/net/NetworkScorerAppData.java b/tests/robotests/src/android/net/NetworkScorerAppData.java deleted file mode 100644 index f7da4d1ccd5..00000000000 --- a/tests/robotests/src/android/net/NetworkScorerAppData.java +++ /dev/null @@ -1,130 +0,0 @@ -package android.net; - -import android.annotation.Nullable; -import android.content.ComponentName; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * Holds metadata about a discovered network scorer/recommendation application. - * - * TODO: delete this class once robolectric supports Android O - */ -public final class NetworkScorerAppData implements Parcelable { - /** UID of the scorer app. */ - public final int packageUid; - private final ComponentName mRecommendationService; - /** User visible label in Settings for the recommendation service. */ - private final String mRecommendationServiceLabel; - /** - * The {@link ComponentName} of the Activity to start before enabling the "connect to open - * wifi networks automatically" feature. - */ - private final ComponentName mEnableUseOpenWifiActivity; - /** - * The {@link android.app.NotificationChannel} ID used by {@link #mRecommendationService} to - * post open network notifications. - */ - private final String mNetworkAvailableNotificationChannelId; - - public NetworkScorerAppData(int packageUid, ComponentName recommendationServiceComp, - String recommendationServiceLabel, ComponentName enableUseOpenWifiActivity, - String networkAvailableNotificationChannelId) { - this.packageUid = packageUid; - this.mRecommendationService = recommendationServiceComp; - this.mRecommendationServiceLabel = recommendationServiceLabel; - this.mEnableUseOpenWifiActivity = enableUseOpenWifiActivity; - this.mNetworkAvailableNotificationChannelId = networkAvailableNotificationChannelId; - } - - protected NetworkScorerAppData(Parcel in) { - packageUid = in.readInt(); - mRecommendationService = ComponentName.readFromParcel(in); - mRecommendationServiceLabel = in.readString(); - mEnableUseOpenWifiActivity = ComponentName.readFromParcel(in); - mNetworkAvailableNotificationChannelId = in.readString(); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(packageUid); - ComponentName.writeToParcel(mRecommendationService, dest); - dest.writeString(mRecommendationServiceLabel); - ComponentName.writeToParcel(mEnableUseOpenWifiActivity, dest); - dest.writeString(mNetworkAvailableNotificationChannelId); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Creator CREATOR = - new Creator() { - @Override - public NetworkScorerAppData createFromParcel(Parcel in) { - return new NetworkScorerAppData(in); - } - - @Override - public NetworkScorerAppData[] newArray(int size) { - return new NetworkScorerAppData[size]; - } - }; - - public String getRecommendationServicePackageName() { - return mRecommendationService.getPackageName(); - } - - public ComponentName getRecommendationServiceComponent() { - return mRecommendationService; - } - - @Nullable - public ComponentName getEnableUseOpenWifiActivity() { - return mEnableUseOpenWifiActivity; - } - - @Nullable - public String getRecommendationServiceLabel() { - return mRecommendationServiceLabel; - } - - @Nullable - public String getNetworkAvailableNotificationChannelId() { - return mNetworkAvailableNotificationChannelId; - } - - @Override - public String toString() { - return "NetworkScorerAppData{" + - "packageUid=" + packageUid + - ", mRecommendationService=" + mRecommendationService + - ", mRecommendationServiceLabel=" + mRecommendationServiceLabel + - ", mEnableUseOpenWifiActivity=" + mEnableUseOpenWifiActivity + - ", mNetworkAvailableNotificationChannelId=" + - mNetworkAvailableNotificationChannelId + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - NetworkScorerAppData that = (NetworkScorerAppData) o; - return packageUid == that.packageUid && - Objects.equals(mRecommendationService, that.mRecommendationService) && - Objects.equals(mRecommendationServiceLabel, that.mRecommendationServiceLabel) && - Objects.equals(mEnableUseOpenWifiActivity, that.mEnableUseOpenWifiActivity) && - Objects.equals(mNetworkAvailableNotificationChannelId, - that.mNetworkAvailableNotificationChannelId); - } - - @Override - public int hashCode() { - return Objects.hash(packageUid, mRecommendationService, mRecommendationServiceLabel, - mEnableUseOpenWifiActivity, mNetworkAvailableNotificationChannelId); - } -} diff --git a/tests/robotests/src/android/print/PrintServicesLoader.java b/tests/robotests/src/android/print/PrintServicesLoader.java deleted file mode 100644 index e4975edb813..00000000000 --- a/tests/robotests/src/android/print/PrintServicesLoader.java +++ /dev/null @@ -1,19 +0,0 @@ -package android.print; - -import android.annotation.NonNull; -import android.content.Context; -import android.content.Loader; -import android.printservice.PrintServiceInfo; -import com.android.internal.util.Preconditions; - -import java.util.List; - -/** - * A placeholder class to prevent ClassNotFound exceptions caused by lack of visibility. - */ -public class PrintServicesLoader extends Loader> { - public PrintServicesLoader(@NonNull PrintManager printManager, @NonNull Context context, - int selectionFlags) { - super(Preconditions.checkNotNull(context)); - } -} diff --git a/tests/robotests/src/com/android/internal/app/ColorDisplayController.java b/tests/robotests/src/com/android/internal/app/ColorDisplayController.java deleted file mode 100644 index e31ba518688..00000000000 --- a/tests/robotests/src/com/android/internal/app/ColorDisplayController.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ -package com.android.internal.app; - -/** - * Fake controller to make robolectric test compile. This is necessary since - * ColorDisplayController is not part of Android's API. - */ -public class ColorDisplayController { - - public static final int AUTO_MODE_DISABLED = 0; - public static final int AUTO_MODE_CUSTOM = 1; - public static final int AUTO_MODE_TWILIGHT = 2; - - public static final int COLOR_MODE_NATURAL = 0; - public static final int COLOR_MODE_BOOSTED = 1; - public static final int COLOR_MODE_SATURATED = 2; - - private int mColorMode; - - public void setColorMode(int colorMode) { - mColorMode = colorMode; - } - - public int getColorMode() { - return mColorMode; - } - - public interface Callback { - } -} diff --git a/tests/robotests/src/com/android/internal/app/LocalePickerWithRegion.java b/tests/robotests/src/com/android/internal/app/LocalePickerWithRegion.java deleted file mode 100644 index 9edda45cfe7..00000000000 --- a/tests/robotests/src/com/android/internal/app/LocalePickerWithRegion.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.android.internal.app; - -/** - * A placeholder class to prevent ClassNotFound exceptions caused by lack of visibility. - */ -public class LocalePickerWithRegion { - - public interface LocaleSelectedListener { - void onLocaleSelected(LocaleStore.LocaleInfo locale); - } -} From 92ca05e15e8b604475ad6f835d1adb9b881ce297 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Wed, 28 Mar 2018 17:29:26 -0700 Subject: [PATCH 2/2] Add conformance test for preference controller constructor BasePreferenceController's constructor must be in a certain format in order to work with search and slice. This test enforces that. Change-Id: I236b11248b09ce71f052c449d39e994c84981a06 Fixes: 77216595 Test: robotests --- ...lid_base_preference_controller_constructor | 31 +++++++ ...referenceControllerSignatureInspector.java | 89 +++++++++++++++++++ .../codeinspection/CodeInspectionTest.java | 6 ++ 3 files changed, 126 insertions(+) create mode 100644 tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor create mode 100644 tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java diff --git a/tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor b/tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor new file mode 100644 index 00000000000..bf2f29eade8 --- /dev/null +++ b/tests/robotests/assets/grandfather_invalid_base_preference_controller_constructor @@ -0,0 +1,31 @@ +com.android.settings.applications.appinfo.AppActionButtonPreferenceController +com.android.settings.applications.appinfo.AppBatteryPreferenceController +com.android.settings.applications.appinfo.AppDataUsagePreferenceController +com.android.settings.applications.appinfo.AppHeaderViewPreferenceController +com.android.settings.applications.appinfo.AppInstallerInfoPreferenceController +com.android.settings.applications.appinfo.AppMemoryPreferenceController +com.android.settings.applications.appinfo.AppNotificationPreferenceController +com.android.settings.applications.appinfo.AppOpenByDefaultPreferenceController +com.android.settings.applications.appinfo.AppPermissionPreferenceController +com.android.settings.applications.appinfo.AppStoragePreferenceController +com.android.settings.applications.appinfo.AppVersionPreferenceController +com.android.settings.applications.appinfo.DrawOverlayDetailPreferenceController +com.android.settings.applications.appinfo.ExternalSourceDetailPreferenceController +com.android.settings.applications.appinfo.InstantAppButtonsPreferenceController +com.android.settings.applications.appinfo.InstantAppDomainsPreferenceController +com.android.settings.applications.appinfo.PictureInPictureDetailPreferenceController +com.android.settings.applications.appinfo.WriteSystemSettingsPreferenceController +com.android.settings.bluetooth.BluetoothDeviceNamePreferenceController +com.android.settings.bluetooth.BluetoothDeviceRenamePreferenceController +com.android.settings.bluetooth.BluetoothSwitchPreferenceController +com.android.settings.connecteddevice.ConnectedDeviceGroupController +com.android.settings.connecteddevice.SavedDeviceGroupController +com.android.settings.datausage.DataUsageSummaryPreferenceController +com.android.settings.datetime.timezone.TimeZoneInfoPreferenceController +com.android.settings.fuelgauge.RestrictAppPreferenceController +com.android.settings.fuelgauge.batterysaver.AutoBatterySeekBarPreferenceController +com.android.settings.fuelgauge.batterysaver.BatterySaverButtonPreferenceController +com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController +com.android.settings.security.VisiblePatternProfilePreferenceController +com.android.settings.security.screenlock.LockScreenPreferenceController +com.android.settings.wifi.details.WifiMeteredPreferenceController \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java new file mode 100644 index 00000000000..a9b4f5dc550 --- /dev/null +++ b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java @@ -0,0 +1,89 @@ +/* + * 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.core; + +import static com.google.common.truth.Truth.assertWithMessage; + +import android.content.Context; + +import com.android.settings.core.codeinspection.CodeInspector; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +public class BasePreferenceControllerSignatureInspector extends CodeInspector { + + private final List grandfather; + + public BasePreferenceControllerSignatureInspector(List> classes) { + super(classes); + grandfather = new ArrayList<>(); + initializeGrandfatherList(grandfather, + "grandfather_invalid_base_preference_controller_constructor"); + } + + @Override + public void run() { + StringBuilder badClasses = new StringBuilder(); + + for (Class c : mClasses) { + if (!isConcreteSettingsClass(c)) { + // Not a Settings class, or is abstract, don't care. + continue; + } + if (!BasePreferenceController.class.isAssignableFrom(c)) { + // Not a BasePreferenceController, don't care. + continue; + } + final String className = c.getName(); + if (grandfather.remove(className)) { + continue; + } + final Constructor[] constructors = c.getDeclaredConstructors(); + if (constructors == null || constructors.length == 0) { + badClasses.append(c.getName()).append(","); + } + for (Constructor constructor : constructors) { + if (!hasValidConstructorSignature(constructor)) { + badClasses.append(className).append(","); + continue; + } + } + } + + assertWithMessage("All BasePreferenceController (and subclasses) constructor must either" + + "only take Context, or (Context, String). No other types are allowed") + .that(badClasses.toString()) + .isEmpty(); + + assertWithMessage("Something in the grandfather list is no longer relevant. Please remove") + .that(grandfather) + .isEmpty(); + } + + private static boolean hasValidConstructorSignature(Constructor constructor) { + final Class[] parameterTypes = constructor.getParameterTypes(); + if (parameterTypes.length == 1) { + return Context.class.isAssignableFrom(parameterTypes[0]); + } else if (parameterTypes.length == 2) { + return Context.class.isAssignableFrom(parameterTypes[0]) + && String.class.isAssignableFrom(parameterTypes[1]); + } + return false; + } +} diff --git a/tests/robotests/src/com/android/settings/core/codeinspection/CodeInspectionTest.java b/tests/robotests/src/com/android/settings/core/codeinspection/CodeInspectionTest.java index 8470acb045a..c8ad4d6c6da 100644 --- a/tests/robotests/src/com/android/settings/core/codeinspection/CodeInspectionTest.java +++ b/tests/robotests/src/com/android/settings/core/codeinspection/CodeInspectionTest.java @@ -18,6 +18,7 @@ package com.android.settings.core.codeinspection; import static com.google.common.truth.Truth.assertThat; +import com.android.settings.core.BasePreferenceControllerSignatureInspector; import com.android.settings.core.instrumentation.InstrumentableFragmentCodeInspector; import com.android.settings.search.SearchIndexProviderCodeInspector; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -49,6 +50,11 @@ public class CodeInspectionTest { new InstrumentableFragmentCodeInspector(mClasses).run(); } + @Test + public void runBasePreferenceControllerConstructorSignatureInspection() { + new BasePreferenceControllerSignatureInspector(mClasses).run(); + } + @Ignore("b/73960706") @Test public void runSearchIndexProviderCodeInspection() {