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

Commit 7b3c52a3 authored by Li Li's avatar Li Li
Browse files

Add callback for binder transaction errors

If a process has set its binder callback for transaction errors, those
binder transaction erros will be delivered to AMS. Freezer then checks
the frozen apps to kill whoever recevie sync binder calls or run out of
async binder buffer.

Bug: 199336863
Bug: 308190346
Test: atest BinderfsStatsReaderTest
Test: send binder calls to frozen apps and check logcat
Change-Id: Iedf4d1c988d5afdeb4fad0f354322828c0c3698e
Merged-In: Iedf4d1c988d5afdeb4fad0f354322828c0c3698e
(cherry picked from commit 99defbed)
parent b178b6a1
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -127,6 +127,7 @@ import android.os.GraphicsEnvironment;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.IBinder;
import android.os.IBinderCallback;
import android.os.ICancellationSignal;
import android.os.ICancellationSignal;
import android.os.LocaleList;
import android.os.LocaleList;
import android.os.Looper;
import android.os.Looper;
@@ -7055,6 +7056,18 @@ public final class ActivityThread extends ClientTransactionHandler
        } catch (RemoteException ex) {
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
            throw ex.rethrowFromSystemServer();
        }
        }

        // Set binder transaction callback after finishing bindApplication
        Binder.setTransactionCallback(new IBinderCallback() {
            @Override
            public void onTransactionError(int pid, int code, int flags, int err) {
                try {
                    mgr.frozenBinderTransactionDetected(pid, code, flags, err);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
        });
    }
    }


    @UnsupportedAppUsage
    @UnsupportedAppUsage
+36 −0
Original line number Original line Diff line number Diff line
@@ -460,6 +460,33 @@ public final class ApplicationExitInfo implements Parcelable {
     */
     */
    public static final int SUBREASON_SDK_SANDBOX_NOT_NEEDED = 28;
    public static final int SUBREASON_SDK_SANDBOX_NOT_NEEDED = 28;


    /**
     * The process was killed because the binder proxy limit for system server was exceeded.
     *
     * For internal use only.
     * @hide
     */
    public static final int SUBREASON_EXCESSIVE_BINDER_OBJECTS = 29;

    /**
     * The process was killed by the [kernel] Out-of-memory (OOM) killer; this
     * would be set only when the reason is {@link #REASON_LOW_MEMORY}.
     *
     * For internal use only.
     * @hide
     */
    public static final int SUBREASON_OOM_KILL = 30;

    /**
     * The process was killed because its async kernel binder buffer is running out
     * while being frozen.
     * this would be set only when the reason is {@link #REASON_FREEZER}.
     *
     * For internal use only.
     * @hide
     */
    public static final int SUBREASON_FREEZER_BINDER_ASYNC_FULL = 31;

    // If there is any OEM code which involves additional app kill reasons, it should
    // If there is any OEM code which involves additional app kill reasons, it should
    // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.
    // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.


@@ -635,6 +662,9 @@ public final class ApplicationExitInfo implements Parcelable {
        SUBREASON_KILL_BACKGROUND,
        SUBREASON_KILL_BACKGROUND,
        SUBREASON_PACKAGE_UPDATE,
        SUBREASON_PACKAGE_UPDATE,
        SUBREASON_UNDELIVERED_BROADCAST,
        SUBREASON_UNDELIVERED_BROADCAST,
        SUBREASON_EXCESSIVE_BINDER_OBJECTS,
        SUBREASON_OOM_KILL,
        SUBREASON_FREEZER_BINDER_ASYNC_FULL,
    })
    })
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    public @interface SubReason {}
    public @interface SubReason {}
@@ -1360,6 +1390,12 @@ public final class ApplicationExitInfo implements Parcelable {
                return "PACKAGE UPDATE";
                return "PACKAGE UPDATE";
            case SUBREASON_UNDELIVERED_BROADCAST:
            case SUBREASON_UNDELIVERED_BROADCAST:
                return "UNDELIVERED BROADCAST";
                return "UNDELIVERED BROADCAST";
            case SUBREASON_EXCESSIVE_BINDER_OBJECTS:
                return "EXCESSIVE BINDER OBJECTS";
            case SUBREASON_OOM_KILL:
                return "OOM KILL";
            case SUBREASON_FREEZER_BINDER_ASYNC_FULL:
                return "FREEZER BINDER ASYNC FULL";
            default:
            default:
                return "UNKNOWN";
                return "UNKNOWN";
        }
        }
+10 −0
Original line number Original line Diff line number Diff line
@@ -924,4 +924,14 @@ interface IActivityManager {
    void unregisterUidFrozenStateChangedCallback(in IUidFrozenStateChangedCallback callback);
    void unregisterUidFrozenStateChangedCallback(in IUidFrozenStateChangedCallback callback);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)")
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)")
    int[] getUidFrozenState(in int[] uids);
    int[] getUidFrozenState(in int[] uids);

    /**
     * Notify AMS about binder transactions to frozen apps.
     *
     * @param debugPid The binder transaction sender
     * @param code The binder transaction code
     * @param flags The binder transaction flags
     * @param err The binder transaction error
     */
    oneway void frozenBinderTransactionDetected(int debugPid, int code, int flags, int err);
}
}
+26 −0
Original line number Original line Diff line number Diff line
@@ -642,6 +642,32 @@ public class Binder implements IBinder {
     */
     */
    public static final native void blockUntilThreadAvailable();
    public static final native void blockUntilThreadAvailable();



    /**
     * TODO (b/308179628): Move this to libbinder for non-Java usages.
     */
    private static IBinderCallback sBinderCallback = null;

    /**
     * Set callback function for unexpected binder transaction errors.
     *
     * @hide
     */
    public static final void setTransactionCallback(IBinderCallback callback) {
        sBinderCallback = callback;
    }

    /**
     * Execute the callback function if it's already set.
     *
     * @hide
     */
    public static final void transactionCallback(int pid, int code, int flags, int err) {
        if (sBinderCallback != null) {
            sBinderCallback.onTransactionError(pid, code, flags, err);
        }
    }

    /**
    /**
     * Default constructor just initializes the object.
     * Default constructor just initializes the object.
     *
     *
+34 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.os;

/**
 * Callback interface for binder transaction errors
 *
 * @hide
 */
public interface IBinderCallback {
    /**
     * Callback function for unexpected binder transaction errors.
     *
     * @param debugPid The binder transaction sender
     * @param code The binder transaction code
     * @param flags The binder transaction flags
     * @param err The binder transaction error
     */
    void onTransactionError(int debugPid, int code, int flags, int err);
}
Loading