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

Commit 7c65c003 authored by Achim Thesmann's avatar Achim Thesmann
Browse files

Log warning when activity start is aborted

Currently the information that an Activity start (by a PendingIntent/IntentSender) was blocked is not conveyed to the app process unless the app enables strict mode. And even then there is no useful trace to identify where the offending start originated.

The flag is not intended to be rolled out beyond trunkfood.

Test: atest ActivityStarterTest
Bug: 427863001
Flag: com.android.window.flags.bal_report_aborted_activity_starts
Change-Id: Id8248b8f23a2498e49f2a368d76386aa68a5c498
parent 412189fb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2418,6 +2418,9 @@ public class Instrumentation {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public static void checkStartActivityResult(int res, Object intent) {
        if (!ActivityManager.isStartResultFatalError(res)) {
            if (res == ActivityManager.START_ABORTED && Build.isDebuggable()) {
                Log.w(TAG, new StackTrace("Activity start aborted"));
            }
            return;
        }

+6 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
import static android.app.ActivityManager.INTENT_SENDER_BROADCAST;
import static android.app.ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
import static android.app.ActivityManager.INTENT_SENDER_SERVICE;
import static android.app.ActivityManager.START_ABORTED;

import android.Manifest.permission;
import android.annotation.IntDef;
@@ -1116,12 +1117,16 @@ public final class PendingIntent implements Parcelable {

            final IApplicationThread app = ActivityThread.currentActivityThread()
                    .getApplicationThread();
            return ActivityManager.getService().sendIntentSender(app,
            int result = ActivityManager.getService().sendIntentSender(app,
                    mTarget, mWhitelistToken, code, intent, resolvedType,
                    onFinished != null
                            ? new FinishedDispatcher(this, onFinished, handler)
                            : null,
                    requiredPermission, options);
            if (result == START_ABORTED && Build.isDebuggable()) {
                Log.w(TAG, new StackTrace("Activity start aborted"));
            }
            return result;
        } catch (RemoteException e) {
            throw new CanceledException(e);
        }
+7 −0
Original line number Diff line number Diff line
@@ -28,10 +28,12 @@ import android.app.ActivityManager.PendingIntentInfo;
import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.IApplicationThread;
import android.app.StackTrace;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -40,6 +42,7 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.AndroidException;
import android.util.Log;

import com.android.window.flags.Flags;

@@ -73,6 +76,7 @@ import java.util.concurrent.Executor;
 * {@link android.app.PendingIntent#getIntentSender() PendingIntent.getIntentSender()}.
 */
public class IntentSender implements Parcelable {
    private static final String TAG = "IntentSender";
    /** If enabled consider the deprecated @hide method as removed. */
    @ChangeId
    @EnabledAfter(targetSdkVersion = VANILLA_ICE_CREAM)
@@ -321,6 +325,9 @@ public class IntentSender implements Parcelable {
                            ? new FinishedDispatcher(this, onFinished, executor)
                            : null,
                    requiredPermission, options);
            if (res == ActivityManager.START_ABORTED && Build.isDebuggable()) {
                Log.w(TAG, new StackTrace("Activity start aborted"));
            }
            if (res < 0) {
                throw new SendIntentException();
            }
+7 −0
Original line number Diff line number Diff line
@@ -74,3 +74,10 @@ flag {
    description: "Cover IntentSender API in addition to PendingIntent."
    bug: "405995292"
}

flag {
    name: "bal_report_aborted_activity_starts"
    namespace: "responsible_apis"
    description: "Report aborted activity starts in the calling process."
    bug: "427863001"
}
+4 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.window.flags.Flags.balDontBringExistingBackgroundTaskStackToFg;
import static com.android.window.flags.Flags.balReportAbortedActivityStarts;

import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -1560,6 +1561,9 @@ class ActivityStarter {
    }

    static int getExternalResult(int result) {
        if (balReportAbortedActivityStarts()) {
            return result;
        }
        // Aborted results are treated as successes externally, but we must track them internally.
        return result != START_ABORTED ? result : START_SUCCESS;
    }