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

Commit b504d427 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Grant CPU_TIME for ongoing service binder calls" into main

parents 1dfb208f d8febe9a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -501,6 +501,11 @@ public abstract class ActivityManagerInternal {
     */
    public static final int OOM_ADJ_REASON_RECONFIGURATION = 24;

    /**
     * Oom Adj Reason: Either a binder call has started or finished.
     */
    public static final int OOM_ADJ_REASON_SERVICE_BINDER_CALL = 25;

    @IntDef(prefix = {"OOM_ADJ_REASON_"}, value = {
        OOM_ADJ_REASON_NONE,
        OOM_ADJ_REASON_ACTIVITY,
@@ -527,6 +532,7 @@ public abstract class ActivityManagerInternal {
        OOM_ADJ_REASON_COMPONENT_DISABLED,
        OOM_ADJ_REASON_FOLLOW_UP,
        OOM_ADJ_REASON_RECONFIGURATION,
        OOM_ADJ_REASON_SERVICE_BINDER_CALL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface OomAdjReason {}
+23 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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;

/** @hide */
interface IBinderSession {
    long binderTransactionStarting(in String debugTag);
    void binderTransactionCompleted(in long token);
}
+3 −2
Original line number Diff line number Diff line
@@ -17,11 +17,12 @@

package android.app;

import android.app.IBinderSession;
import android.content.ComponentName;

/** @hide */
oneway interface IServiceConnection {
    @UnsupportedAppUsage
    void connected(in ComponentName name, IBinder service, boolean dead);
    void connected(in ComponentName name, IBinder service, in @nullable IBinderSession session,
        boolean dead);
}
+18 −13
Original line number Diff line number Diff line
@@ -2080,11 +2080,11 @@ public final class LoadedApk {
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
            }

            public void connected(ComponentName name, IBinder service, boolean dead)
                    throws RemoteException {
            public void connected(ComponentName name, IBinder service, IBinderSession binderSession,
                    boolean dead) throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);
                    sd.connected(name, service, binderSession, dead);
                }
            }
        }
@@ -2172,27 +2172,29 @@ public final class LoadedApk {
            return mUnbindLocation;
        }

        public void connected(ComponentName name, IBinder service, boolean dead) {
        public void connected(ComponentName name, IBinder service, IBinderSession session,
                boolean dead) {
            if (mActivityExecutor != null) {
                mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
                mActivityExecutor.execute(new RunConnection(name, service, session, 0, dead));
            } else if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 0, dead));
                mActivityThread.post(new RunConnection(name, service, session, 0, dead));
            } else {
                doConnected(name, service, dead);
                doConnected(name, service, session, dead);
            }
        }

        public void death(ComponentName name, IBinder service) {
            if (mActivityExecutor != null) {
                mActivityExecutor.execute(new RunConnection(name, service, 1, false));
                mActivityExecutor.execute(new RunConnection(name, service, null, 1, false));
            } else if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 1, false));
                mActivityThread.post(new RunConnection(name, service, null, 1, false));
            } else {
                doDeath(name, service);
            }
        }

        public void doConnected(ComponentName name, IBinder service, boolean dead) {
        public void doConnected(ComponentName name, IBinder service, IBinderSession session,
                boolean dead) {
            ServiceDispatcher.ConnectionInfo old;
            ServiceDispatcher.ConnectionInfo info;

@@ -2242,7 +2244,7 @@ public final class LoadedApk {
            } else {
                // If there is a new viable service, it is now connected.
                if (service != null) {
                    mConnection.onServiceConnected(name, service);
                    mConnection.onServiceConnected(name, service, session);
                } else {
                    // The binding machinery worked, but the remote returned null from onBind().
                    mConnection.onNullBinding(name);
@@ -2266,16 +2268,18 @@ public final class LoadedApk {
        }

        private final class RunConnection implements Runnable {
            RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
            RunConnection(ComponentName name, IBinder service, IBinderSession session, int command,
                    boolean dead) {
                mName = name;
                mService = service;
                mBinderSession = session;
                mCommand = command;
                mDead = dead;
            }

            public void run() {
                if (mCommand == 0) {
                    doConnected(mName, mService, mDead);
                    doConnected(mName, mService, mBinderSession, mDead);
                } else if (mCommand == 1) {
                    doDeath(mName, mService);
                }
@@ -2283,6 +2287,7 @@ public final class LoadedApk {

            final ComponentName mName;
            final IBinder mService;
            final IBinderSession mBinderSession;
            final int mCommand;
            final boolean mDead;
        }
+30 −0
Original line number Diff line number Diff line
@@ -16,7 +16,10 @@

package android.content;

import android.annotation.Nullable;
import android.app.IBinderSession;
import android.os.IBinder;
import android.util.Log;

/**
 * Interface for monitoring the state of an application service.  See
@@ -44,6 +47,33 @@ public interface ServiceConnection {
     */
    void onServiceConnected(ComponentName name, IBinder service);

    /**
     * Same as {@link #onServiceConnected(ComponentName, IBinder)} but provides a
     * {@link IBinderSession} to account for binder calls to a frozen remote process whenever the
     * {@link Context#BIND_ALLOW_FREEZE} was used with the bindService call.
     *
     * <p>Clients who do not use the {@link Context#BIND_ALLOW_FREEZE} flag can continue using
     * {@link #onServiceConnected(ComponentName, IBinder)} normally. Note that clients that use
     * {@link Context#BIND_ALLOW_FREEZE} but do not override this will have to deal with the remote
     * process's frozen state on their own.
     *
     * @param name The concrete component name of the service that has been connected.
     * @param service The IBinder of the Service's communication channel, which you can now make
     *                calls on.
     * @param binderSession An IBinderSession used to keep the remote service unfrozen to process
     *                      any binder calls. Will be {@code null} when
     *                      {@link Context#BIND_ALLOW_FREEZE} was not used.
     * @hide
     */
    default void onServiceConnected(ComponentName name, IBinder service,
            @Nullable IBinderSession binderSession) {
        if (binderSession != null) {
            final String tag = getClass().getSimpleName();
            Log.w(tag, "Binder session present but potentially unused for binding to " + name);
        }
        onServiceConnected(name, service);
    }

    /**
     * Called when a connection to the Service has been lost.  This typically
     * happens when the process hosting the service has crashed or been killed.
Loading