diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index f3e9f105500e9..c895636ddc824 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1796,6 +1796,7 @@ class ContextImpl extends Context { && ((flags & Context.RECEIVER_NOT_EXPORTED) == 0)) { flags = flags | Context.RECEIVER_EXPORTED; } + final Intent intent = ActivityManager.getService().registerReceiverWithFeature( mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(), AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId, @@ -1810,6 +1811,9 @@ class ContextImpl extends Context { return intent; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } catch (WtfException e) { + Log.wtf(TAG, e.getMessage()); + return null; } } diff --git a/core/java/android/app/WtfException.java b/core/java/android/app/WtfException.java new file mode 100644 index 0000000000000..ba8dbefad160e --- /dev/null +++ b/core/java/android/app/WtfException.java @@ -0,0 +1,66 @@ +/* + * 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 android.app; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Exception meant to be thrown instead of calling Log.wtf() such that server side code can + * throw this exception, and it will carry across the binder to do client side logging. + * {@hide} + */ +public final class WtfException extends RuntimeException implements Parcelable { + public static final @android.annotation.NonNull + Creator CREATOR = new Creator() { + @Override + public WtfException createFromParcel(Parcel source) { + return new WtfException(source.readString8()); + } + + @Override + public WtfException[] newArray(int size) { + return new WtfException[size]; + } + }; + + public WtfException(@android.annotation.NonNull String message) { + super(message); + } + + /** {@hide} */ + public static Throwable readFromParcel(Parcel in) { + final String msg = in.readString8(); + return new WtfException(msg); + } + + /** {@hide} */ + public static void writeToParcel(Parcel out, Throwable t) { + out.writeString8(t.getMessage()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@android.annotation.NonNull Parcel dest, int flags) { + dest.writeString8(getMessage()); + } +} + diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f0f6bd172770e..ebce30ab38493 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -189,6 +189,7 @@ import android.app.ProfilerInfo; import android.app.PropertyInvalidatedCache; import android.app.SyncNotedAppOp; import android.app.WaitResult; +import android.app.WtfException; import android.app.backup.BackupManager.OperationType; import android.app.backup.IBackupManager; import android.app.compat.CompatChanges; @@ -12634,6 +12635,7 @@ public class ActivityManagerService extends IActivityManager.Stub int callingUid; int callingPid; boolean instantApp; + boolean throwWtfException = false; synchronized(this) { if (caller != null) { callerApp = getRecordForAppLOSP(caller); @@ -12728,13 +12730,9 @@ public class ActivityManagerService extends IActivityManager.Stub + "RECEIVER_NOT_EXPORTED be specified when registering a " + "receiver"); } else { - Slog.wtf(TAG, - callerPackage + ": Targeting T+ (version " - + Build.VERSION_CODES.TIRAMISU - + " and above) requires that one of RECEIVER_EXPORTED or " - + "RECEIVER_NOT_EXPORTED be specified when registering a " - + "receiver"); + // will be removed when enforcement is required // Assume default behavior-- flag check is not enforced + throwWtfException = true; flags |= Context.RECEIVER_EXPORTED; } } else if (!requireExplicitFlagForDynamicReceivers) { @@ -12865,6 +12863,15 @@ public class ActivityManagerService extends IActivityManager.Stub } } + if (throwWtfException) { + throw new WtfException( + callerPackage + ": Targeting T+ (version " + + Build.VERSION_CODES.TIRAMISU + + " and above) requires that one of RECEIVER_EXPORTED or " + + "RECEIVER_NOT_EXPORTED be specified when registering a " + + "receiver"); + } + return sticky; } }