Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cf5c3fe authored by Bernardo Rufino's avatar Bernardo Rufino Committed by Android (Google) Code Review
Browse files

Merge "[Roll Forward] Block background custom toasts"

parents 3de74227 60c39b3b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ interface INotificationManager
    void cancelAllNotifications(String pkg, int userId);

    void clearData(String pkg, int uid, boolean fromApp);
    // TODO: Replace parameter (ITransientNotification callback) with (CharSequence text)
    void enqueueTextToast(String pkg, ITransientNotification callback, int duration, int displayId);
    @UnsupportedAppUsage
    void enqueueToast(String pkg, ITransientNotification callback, int duration, int displayId);
    @UnsupportedAppUsage
+9 −1
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ public class Toast {
    @UnsupportedAppUsage
    int mDuration;
    View mNextView;
    // TODO(b/128611929): Remove this and check for null view when toast creation is in the system
    boolean mIsCustomToast = false;

    /**
     * Construct an empty Toast object.  You must call {@link #setView} before you
@@ -140,7 +142,11 @@ public class Toast {
        final int displayId = mContext.getDisplayId();

        try {
            if (mIsCustomToast) {
                service.enqueueToast(pkg, tn, mDuration, displayId);
            } else {
                service.enqueueTextToast(pkg, tn, mDuration, displayId);
            }
        } catch (RemoteException e) {
            // Empty
        }
@@ -160,6 +166,7 @@ public class Toast {
     * @see #getView
     */
    public void setView(View view) {
        mIsCustomToast = true;
        mNextView = view;
    }

@@ -168,6 +175,7 @@ public class Toast {
     * @see #setView
     */
    public View getView() {
        mIsCustomToast = true;
        return mNextView;
    }

+4 −0
Original line number Diff line number Diff line
@@ -118,6 +118,10 @@ java_library_static {
        "dnsresolver_aidl_interface-V2-java",
        "netd_event_listener_interface-java",
    ],

    plugins: [
        "compat-changeid-annotation-processor",
    ],
}

java_genrule {
+64 −10
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ import android.app.role.RoleManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
import android.companion.ICompanionDeviceManager;
import android.compat.annotation.ChangeId;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProvider;
@@ -216,6 +217,7 @@ import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
@@ -236,6 +238,7 @@ import com.android.server.EventLogTags;
import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.UiThread;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
import com.android.server.notification.ManagedServices.ManagedServiceInfo;
@@ -355,6 +358,15 @@ public class NotificationManagerService extends SystemService {
    private static final int REQUEST_CODE_TIMEOUT = 1;
    private static final String SCHEME_TIMEOUT = "timeout";
    private static final String EXTRA_KEY = "key";

    /**
     * Apps targeting R+ that post custom toasts in the background will have those blocked. Apps can
     * still post toasts created with {@link Toast#makeText(Context, CharSequence, int)} and its
     * variants while in the background.
     */
    @ChangeId
    private static final long CHANGE_BACKGROUND_CUSTOM_TOAST_BLOCK = 128611929L;

    private IActivityManager mAm;
    private ActivityManager mActivityManager;
    private IPackageManager mPackageManager;
@@ -372,9 +384,11 @@ public class NotificationManagerService extends SystemService {
    private UriGrantsManagerInternal mUgmInternal;
    private RoleObserver mRoleObserver;
    private UserManager mUm;
    private IPlatformCompat mPlatformCompat;

    final IBinder mForegroundToken = new Binder();
    private WorkerHandler mHandler;
    private Handler mUiHandler;
    private final HandlerThread mRankingThread = new HandlerThread("ranker",
            Process.THREAD_PRIORITY_BACKGROUND);

@@ -1782,8 +1796,11 @@ public class NotificationManagerService extends SystemService {
                ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
        mDpm = dpm;
        mUm = userManager;
        mPlatformCompat = IPlatformCompat.Stub.asInterface(
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));

        mHandler = new WorkerHandler(looper);
        mUiHandler = new Handler(UiThread.get().getLooper());
        String[] extractorNames;
        try {
            extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors);
@@ -2449,10 +2466,20 @@ public class NotificationManagerService extends SystemService {
        // Toasts
        // ============================================================================

        @Override
        public void enqueueTextToast(String pkg, ITransientNotification callback, int duration,
                int displayId) {
            enqueueToast(pkg, callback, duration, displayId, false);
        }

        @Override
        public void enqueueToast(String pkg, ITransientNotification callback, int duration,
                int displayId)
        {
                int displayId) {
            enqueueToast(pkg, callback, duration, displayId, true);
        }

        private void enqueueToast(String pkg, ITransientNotification callback, int duration,
                int displayId, boolean isCustomToast) {
            if (DBG) {
                Slog.i(TAG, "enqueueToast pkg=" + pkg + " callback=" + callback
                        + " duration=" + duration + " displayId=" + displayId);
@@ -2464,16 +2491,22 @@ public class NotificationManagerService extends SystemService {
            }

            final int callingUid = Binder.getCallingUid();
            final UserHandle callingUser = Binder.getCallingUserHandle();
            final boolean isSystemToast = isCallerSystemOrPhone()
                    || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(pkg);
            final boolean isPackageSuspended = isPackagePaused(pkg);
            final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg,
                    callingUid);

            final boolean appIsForeground;
            long callingIdentity = Binder.clearCallingIdentity();
            try {
                final boolean appIsForeground = mActivityManager.getUidImportance(callingUid)
                appIsForeground = mActivityManager.getUidImportance(callingUid)
                        == IMPORTANCE_FOREGROUND;
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
            }

            if (ENABLE_BLOCKED_TOASTS && !isSystemToast && ((notificationsDisabledForPackage
                    && !appIsForeground) || isPackageSuspended)) {
                Slog.e(TAG, "Suppressing toast from package " + pkg
@@ -2481,8 +2514,29 @@ public class NotificationManagerService extends SystemService {
                        : " by user request."));
                return;
            }
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);

            if (isCustomToast && !appIsForeground && !isSystemToast) {
                boolean block;
                try {
                    block = mPlatformCompat.isChangeEnabledByPackageName(
                            CHANGE_BACKGROUND_CUSTOM_TOAST_BLOCK, pkg,
                            callingUser.getIdentifier());
                } catch (RemoteException e) {
                    // Shouldn't happen have since it's a local local
                    Slog.e(TAG, "Unexpected exception while checking block background custom toasts"
                            + " change", e);
                    block = false;
                }
                if (block) {
                    // TODO(b/144152069): Remove informative toast
                    mUiHandler.post(() -> Toast.makeText(getContext(),
                            "Background custom toast blocked for package " + pkg + ".\n"
                                    + "See go/r-toast-block.",
                            Toast.LENGTH_SHORT).show());
                    Slog.w(TAG, "Blocking custom toast from package " + pkg
                            + " due to package not in the foreground");
                    return;
                }
            }

            synchronized (mToastQueue) {