From d5f77656e88d190883137fd03073fe4dba353f5e Mon Sep 17 00:00:00 2001 From: Jackal Guo Date: Sat, 18 Feb 2023 11:41:13 +0800 Subject: Have more meaningful error message When building a PreapprovalDetails oblject, throwing IllegalArgument- Exception with a message explaining what was missing instead of a NullPointerException without any message. Due to the limitation, manually construct the Builder and related methods instead of using codegen. Fix: 269731101 Test: atest CtsContentTestCases:PreapprovalDetailsTest Test: atest CtsPackageInstallTestCases:PreapprovalInstallTest Test: manually building a PreapprovalDetails object with supplying all required details, and check if the message tells me what is going on. Change-Id: I0cd641d90ab45830ab6740e94357e4280fac2d4c --- core/java/android/content/pm/PackageInstaller.java | 211 +++++++++------------ 1 file changed, 94 insertions(+), 117 deletions(-) diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 7766896c7367..8acdf510484b 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -3981,8 +3981,7 @@ public class PackageInstaller { /** * Details for requesting the pre-commit install approval. */ - @DataClass(genParcelable = true, genHiddenConstructor = true, genBuilder = true, - genToString = true) + @DataClass(genConstructor = false, genToString = true) public static final class PreapprovalDetails implements Parcelable { /** * The icon representing the app to be installed. @@ -4001,22 +4000,6 @@ public class PackageInstaller { */ private final @NonNull String mPackageName; - - - - // Code below generated by codegen v1.0.23. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/PackageInstaller.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - /** * Creates a new PreapprovalDetails. * @@ -4030,78 +4013,25 @@ public class PackageInstaller { * The package name of the app to be installed. * @hide */ - @DataClass.Generated.Member public PreapprovalDetails( @Nullable Bitmap icon, @NonNull CharSequence label, @NonNull ULocale locale, @NonNull String packageName) { - this.mIcon = icon; - this.mLabel = label; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mLabel); - this.mLocale = locale; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mLocale); - this.mPackageName = packageName; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mPackageName); - - // onConstructed(); // You can define this method to get a callback - } - - /** - * The icon representing the app to be installed. - */ - @DataClass.Generated.Member - public @Nullable Bitmap getIcon() { - return mIcon; - } - - /** - * The label representing the app to be installed. - */ - @DataClass.Generated.Member - public @NonNull CharSequence getLabel() { - return mLabel; - } - - /** - * The locale of the app label being used. - */ - @DataClass.Generated.Member - public @NonNull ULocale getLocale() { - return mLocale; - } - - /** - * The package name of the app to be installed. - */ - @DataClass.Generated.Member - public @NonNull String getPackageName() { - return mPackageName; + mIcon = icon; + mLabel = label; + Preconditions.checkArgument(!TextUtils.isEmpty(mLabel), + "App label cannot be empty."); + mLocale = locale; + Preconditions.checkArgument(!Objects.isNull(mLocale), + "Locale cannot be null."); + mPackageName = packageName; + Preconditions.checkArgument(!TextUtils.isEmpty(mPackageName), + "Package name cannot be empty."); } @Override - @DataClass.Generated.Member - public String toString() { - // You can override field toString logic by defining methods like: - // String fieldNameToString() { ... } - - return "PreapprovalDetails { " + - "icon = " + mIcon + ", " + - "label = " + mLabel + ", " + - "locale = " + mLocale + ", " + - "packageName = " + mPackageName + - " }"; - } - - @Override - @DataClass.Generated.Member public void writeToParcel(@NonNull Parcel dest, int flags) { - // You can override field parcelling by defining methods like: - // void parcelFieldName(Parcel dest, int flags) { ... } - byte flg = 0; if (mIcon != null) flg |= 0x1; dest.writeByte(flg); @@ -4112,37 +4042,28 @@ public class PackageInstaller { } @Override - @DataClass.Generated.Member public int describeContents() { return 0; } /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member /* package-private */ PreapprovalDetails(@NonNull Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - byte flg = in.readByte(); - Bitmap icon = (flg & 0x1) == 0 ? null : Bitmap.CREATOR.createFromParcel(in); - CharSequence label = (CharSequence) in.readCharSequence(); - ULocale locale = new ULocale(in.readString8()); - String packageName = in.readString8(); - - this.mIcon = icon; - this.mLabel = label; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mLabel); - this.mLocale = locale; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mLocale); - this.mPackageName = packageName; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mPackageName); - - // onConstructed(); // You can define this method to get a callback + final Bitmap icon = (flg & 0x1) == 0 ? null : Bitmap.CREATOR.createFromParcel(in); + final CharSequence label = in.readCharSequence(); + final ULocale locale = new ULocale(in.readString8()); + final String packageName = in.readString8(); + + mIcon = icon; + mLabel = label; + Preconditions.checkArgument(!TextUtils.isEmpty(mLabel), + "App label cannot be empty."); + mLocale = locale; + Preconditions.checkArgument(!Objects.isNull(mLocale), + "Locale cannot be null."); + mPackageName = packageName; + Preconditions.checkArgument(!TextUtils.isEmpty(mPackageName), + "Package name cannot be empty."); } - @DataClass.Generated.Member public static final @NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override @@ -4159,8 +4080,6 @@ public class PackageInstaller { /** * A builder for {@link PreapprovalDetails} */ - @SuppressWarnings("WeakerAccess") - @DataClass.Generated.Member public static final class Builder { private @Nullable Bitmap mIcon; @@ -4178,7 +4097,6 @@ public class PackageInstaller { /** * The icon representing the app to be installed. */ - @DataClass.Generated.Member public @NonNull Builder setIcon(@NonNull Bitmap value) { checkNotUsed(); mBuilderFieldsSet |= 0x1; @@ -4189,7 +4107,6 @@ public class PackageInstaller { /** * The label representing the app to be installed. */ - @DataClass.Generated.Member public @NonNull Builder setLabel(@NonNull CharSequence value) { checkNotUsed(); mBuilderFieldsSet |= 0x2; @@ -4200,7 +4117,6 @@ public class PackageInstaller { /** * The locale of the app label being used. */ - @DataClass.Generated.Member public @NonNull Builder setLocale(@NonNull ULocale value) { checkNotUsed(); mBuilderFieldsSet |= 0x4; @@ -4211,7 +4127,6 @@ public class PackageInstaller { /** * The package name of the app to be installed. */ - @DataClass.Generated.Member public @NonNull Builder setPackageName(@NonNull String value) { checkNotUsed(); mBuilderFieldsSet |= 0x8; @@ -4234,17 +4149,79 @@ public class PackageInstaller { private void checkNotUsed() { if ((mBuilderFieldsSet & 0x10) != 0) { - throw new IllegalStateException( - "This Builder should not be reused. Use a new Builder instance instead"); + throw new IllegalStateException("This Builder should not be reused. " + + "Use a new Builder instance instead"); } } } + + + + // Code below generated by codegen v1.0.23. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/PackageInstaller.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + /** + * The icon representing the app to be installed. + */ + @DataClass.Generated.Member + public @Nullable Bitmap getIcon() { + return mIcon; + } + + /** + * The label representing the app to be installed. + */ + @DataClass.Generated.Member + public @NonNull CharSequence getLabel() { + return mLabel; + } + + /** + * The locale of the app label being used. + */ + @DataClass.Generated.Member + public @NonNull ULocale getLocale() { + return mLocale; + } + + /** + * The package name of the app to be installed. + */ + @DataClass.Generated.Member + public @NonNull String getPackageName() { + return mPackageName; + } + + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "PreapprovalDetails { " + + "icon = " + mIcon + ", " + + "label = " + mLabel + ", " + + "locale = " + mLocale + ", " + + "packageName = " + mPackageName + + " }"; + } + @DataClass.Generated( - time = 1666748098353L, + time = 1676970504308L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/PackageInstaller.java", - inputSignatures = "private final @android.annotation.Nullable android.graphics.Bitmap mIcon\nprivate final @android.annotation.NonNull java.lang.CharSequence mLabel\nprivate final @android.annotation.NonNull android.icu.util.ULocale mLocale\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nclass PreapprovalDetails extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genHiddenConstructor=true, genBuilder=true, genToString=true)") + inputSignatures = "private final @android.annotation.Nullable android.graphics.Bitmap mIcon\nprivate final @android.annotation.NonNull java.lang.CharSequence mLabel\nprivate final @android.annotation.NonNull android.icu.util.ULocale mLocale\nprivate final @android.annotation.NonNull java.lang.String mPackageName\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator CREATOR\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\npublic @java.lang.Override int describeContents()\nclass PreapprovalDetails extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.Nullable android.graphics.Bitmap mIcon\nprivate @android.annotation.NonNull java.lang.CharSequence mLabel\nprivate @android.annotation.NonNull android.icu.util.ULocale mLocale\nprivate @android.annotation.NonNull java.lang.String mPackageName\nprivate long mBuilderFieldsSet\npublic @android.annotation.NonNull android.content.pm.PackageInstaller.PreapprovalDetails.Builder setIcon(android.graphics.Bitmap)\npublic @android.annotation.NonNull android.content.pm.PackageInstaller.PreapprovalDetails.Builder setLabel(java.lang.CharSequence)\npublic @android.annotation.NonNull android.content.pm.PackageInstaller.PreapprovalDetails.Builder setLocale(android.icu.util.ULocale)\npublic @android.annotation.NonNull android.content.pm.PackageInstaller.PreapprovalDetails.Builder setPackageName(java.lang.String)\npublic @android.annotation.NonNull android.content.pm.PackageInstaller.PreapprovalDetails build()\nprivate void checkNotUsed()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true)") @Deprecated private void __metadata() {} @@ -4347,7 +4324,7 @@ public class PackageInstaller { }; @DataClass.Generated( - time = 1675135664641L, + time = 1676970504336L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/PackageInstaller.java", inputSignatures = "private boolean mAllConstraintsSatisfied\npublic boolean areAllConstraintsSatisfied()\nclass InstallConstraintsResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genHiddenConstructor=true)") @@ -4635,7 +4612,7 @@ public class PackageInstaller { }; @DataClass.Generated( - time = 1675135664653L, + time = 1676970504352L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/PackageInstaller.java", inputSignatures = "public static final @android.annotation.NonNull android.content.pm.PackageInstaller.InstallConstraints GENTLE_UPDATE\nprivate final boolean mDeviceIdleRequired\nprivate final boolean mAppNotForegroundRequired\nprivate final boolean mAppNotInteractingRequired\nprivate final boolean mAppNotTopVisibleRequired\nprivate final boolean mNotInCallRequired\nclass InstallConstraints extends java.lang.Object implements [android.os.Parcelable]\nprivate boolean mDeviceIdleRequired\nprivate boolean mAppNotForegroundRequired\nprivate boolean mAppNotInteractingRequired\nprivate boolean mAppNotTopVisibleRequired\nprivate boolean mNotInCallRequired\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.content.pm.PackageInstaller.InstallConstraints.Builder setDeviceIdleRequired()\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.content.pm.PackageInstaller.InstallConstraints.Builder setAppNotForegroundRequired()\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.content.pm.PackageInstaller.InstallConstraints.Builder setAppNotInteractingRequired()\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.content.pm.PackageInstaller.InstallConstraints.Builder setAppNotTopVisibleRequired()\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.content.pm.PackageInstaller.InstallConstraints.Builder setNotInCallRequired()\npublic @android.annotation.NonNull android.content.pm.PackageInstaller.InstallConstraints build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genParcelable=true, genHiddenConstructor=true, genEqualsHashCode=true)") -- cgit v1.2.3-59-g8ed1b