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

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

Merge changes I9f724edd,If1aac17a into main

* changes:
  am: Decouple ConnectionRecord with OomAdjuster
  psc: Extract ConnectionRecord flags/ongoing calls to internal class
parents f54de1f8 9d74e620
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -685,6 +685,7 @@ com.android.server.SystemServiceManager

com.android.server.am.BoundServiceSession
com.android.server.am.ConnectionRecord
com.android.server.am.psc.ConnectionRecordInternal
com.android.server.utils.TimingsTraceAndSlog

com.google.android.collect.Lists
+16 −54
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ import android.util.proto.ProtoUtils;

import com.android.internal.app.procstats.AssociationState;
import com.android.internal.app.procstats.ProcessStats;
import com.android.server.am.psc.ProcessRecordInternal;
import com.android.server.am.psc.ConnectionRecordInternal;
import com.android.server.wm.ActivityServiceConnectionsHolder;

import java.io.PrintWriter;
@@ -41,15 +41,13 @@ import java.io.PrintWriter;
 * Description of a single binding to a service.
 */
@RavenwoodKeepWholeClass
final class ConnectionRecord implements OomAdjusterImpl.Connection{
final class ConnectionRecord extends ConnectionRecordInternal {
    BoundServiceSession mBoundServiceSession;  // The associated bound service session if created.
    final AppBindRecord binding;    // The application/service binding.
    final ActivityServiceConnectionsHolder<ConnectionRecord> activity;  // If non-null, the owning activity.
    final IServiceConnection conn;  // The client connection.
    private final long flags;                // Binding options.
    final int clientLabel;          // String resource labeling this client.
    final PendingIntent clientIntent; // How to launch the client.
    private boolean mOngoingCalls;  // Any ongoing transactions over this connection?
    final int clientUid;            // The identity of this connection's client
    final String clientProcessName; // The source process of this connection's client
    final String clientPackageName; // The source package of this connection's client
@@ -112,11 +110,11 @@ final class ConnectionRecord implements OomAdjusterImpl.Connection{
            activity.dump(pw, prefix);
        }
        pw.println(prefix + "conn=" + conn.asBinder()
                + " flags=0x" + Long.toHexString(flags));
                + " flags=0x" + Long.toHexString(getFlags()));

        pw.print(prefix);
        pw.print("ongoingCalls=");
        pw.println(mOngoingCalls);
        pw.println(getOngoingCalls());
        if (mBoundServiceSession != null) {
            mBoundServiceSession.dump(new IndentingPrintWriter(pw, "  ", prefix));
        }
@@ -128,10 +126,11 @@ final class ConnectionRecord implements OomAdjusterImpl.Connection{
            int _clientLabel, PendingIntent _clientIntent,
            int _clientUid, String _clientProcessName, String _clientPackageName,
            ComponentName _aliasComponent) {
        super(_flags);

        binding = _binding;
        activity = _activity;
        conn = _conn;
        flags = _flags;
        clientLabel = _clientLabel;
        clientIntent = _clientIntent;
        clientUid = _clientUid;
@@ -140,57 +139,19 @@ final class ConnectionRecord implements OomAdjusterImpl.Connection{
        aliasComponent = _aliasComponent;
    }

    boolean setOngoingCalls(boolean ongoingCalls) {
        if (mOngoingCalls != ongoingCalls) {
            mOngoingCalls = ongoingCalls;
            return true;
        }
        return false;
    }

    @Override
    public void computeHostOomAdjLSP(OomAdjuster oomAdjuster, ProcessRecordInternal host,
            ProcessRecordInternal client, long now, ProcessRecordInternal topApp, boolean doingAll,
            int oomAdjReason, int cachedAdj) {
        oomAdjuster.computeServiceHostOomAdjLSP(this, host, client, now, false);
    public ActivityServiceConnectionsHolder<ConnectionRecord> getActivity() {
        return activity;
    }

    @Override
    public boolean canAffectCapabilities() {
        return hasFlag(Context.BIND_INCLUDE_CAPABILITIES
                | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS);
    public long getServiceLastActivityTimeMillis() {
        return binding.service.lastActivity;
    }

    @Override
    public int cpuTimeTransmissionType() {
        if (mOngoingCalls) {
            return CPU_TIME_TRANSMISSION_NORMAL;
        }
        if (hasFlag(Context.BIND_ALLOW_FREEZE)) {
            return CPU_TIME_TRANSMISSION_NONE;
        }
        return hasFlag(Context.BIND_SIMULATE_ALLOW_FREEZE) ? CPU_TIME_TRANSMISSION_LEGACY
                : CPU_TIME_TRANSMISSION_NORMAL;
    }

    public long getFlags() {
        return flags;
    }

    public boolean hasFlag(final int flag) {
        return (flags & Integer.toUnsignedLong(flag)) != 0;
    }

    public boolean hasFlag(final long flag) {
        return (flags & flag) != 0;
    }

    public boolean notHasFlag(final int flag) {
        return !hasFlag(flag);
    }

    public boolean notHasFlag(final long flag) {
        return !hasFlag(flag);
    public ComponentName getServiceInstanceName() {
        return binding.service.instanceName;
    }

    public void startAssociationIfNeeded() {
@@ -219,6 +180,7 @@ final class ConnectionRecord implements OomAdjusterImpl.Connection{
        }
    }

    @Override
    public void trackProcState(int procState, int seq) {
        if (association != null) {
            synchronized (mProcStatsLock) {
@@ -244,7 +206,7 @@ final class ConnectionRecord implements OomAdjusterImpl.Connection{
        sb.append(binding.client.mPid);
        sb.append("->");
        sb.append(binding.service.shortInstanceName);
        sb.append(" flags=0x" + Long.toHexString(flags));
        sb.append(" flags=0x" + Long.toHexString(getFlags()));
        sb.append('}');
        return sb.toString();
    }
@@ -328,7 +290,7 @@ final class ConnectionRecord implements OomAdjusterImpl.Connection{
        sb.append(binding.service.shortInstanceName);
        sb.append(":@");
        sb.append(Integer.toHexString(System.identityHashCode(conn.asBinder())));
        sb.append(" flags=0x" + Long.toHexString(flags));
        sb.append(" flags=0x" + Long.toHexString(getFlags()));
        sb.append('}');
        return stringName = sb.toString();
    }
@@ -343,7 +305,7 @@ final class ConnectionRecord implements OomAdjusterImpl.Connection{
            proto.write(ConnectionRecordProto.CLIENT_PID, binding.client.mPid);
        }
        ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, ConnectionRecordProto.FLAGS,
                flags, BIND_ORIG_ENUMS, BIND_PROTO_ENUMS);
                getFlags(), BIND_ORIG_ENUMS, BIND_PROTO_ENUMS);
        if (serviceDead) {
            proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.DEAD);
        }
+2 −1
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.ServiceThread;
import com.android.server.am.psc.ActiveUidsInternal;
import com.android.server.am.psc.ConnectionRecordInternal;
import com.android.server.am.psc.PlatformCompatCache;
import com.android.server.am.psc.PlatformCompatCache.CachedCompatChangeId;
import com.android.server.am.psc.ProcessRecordInternal;
@@ -1989,7 +1990,7 @@ public abstract class OomAdjuster {
     * Computes the impact on {@code app} the service connections from {@code client} has.
     */
    @GuardedBy({"mService", "mProcLock"})
    public abstract boolean computeServiceHostOomAdjLSP(ConnectionRecord cr,
    public abstract boolean computeServiceHostOomAdjLSP(ConnectionRecordInternal cr,
            ProcessRecordInternal app, ProcessRecordInternal client, long now, boolean dryRun);

    /**
+7 −6
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.ServiceThread;
import com.android.server.am.psc.ActiveUidsInternal;
import com.android.server.am.psc.ConnectionRecordInternal;
import com.android.server.am.psc.ProcessRecordInternal;
import com.android.server.am.psc.UidRecordInternal;
import com.android.server.wm.ActivityServiceConnectionsHolder;
@@ -1848,8 +1849,8 @@ public class OomAdjusterImpl extends OomAdjuster {

    @GuardedBy({"mService", "mProcLock"})
    @Override
    public boolean computeServiceHostOomAdjLSP(ConnectionRecord cr, ProcessRecordInternal app,
            ProcessRecordInternal client, long now, boolean dryRun) {
    public boolean computeServiceHostOomAdjLSP(ConnectionRecordInternal cr,
            ProcessRecordInternal app, ProcessRecordInternal client, long now, boolean dryRun) {
        if (app.isPendingFinishAttach()) {
            // We've set the attaching process state in the computeInitialOomAdjLSP. Skip it here.
            return false;
@@ -1986,7 +1987,7 @@ public class OomAdjusterImpl extends OomAdjuster {
                    clientAdj = adj;
                    clientProcState = procState;
                } else {
                    if (now >= (cr.binding.service.lastActivity
                    if (now >= (cr.getServiceLastActivityTimeMillis()
                            + mConstants.MAX_SERVICE_INACTIVITY)) {
                        // This service has not seen activity within
                        // recent memory, so allow it to drop to the
@@ -2180,7 +2181,7 @@ public class OomAdjusterImpl extends OomAdjuster {
                app.setAdjTypeCode(ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE);
                app.setAdjSource(client);
                app.setAdjSourceProcState(clientProcState);
                app.setAdjTarget(cr.binding.service.instanceName);
                app.setAdjTarget(cr.getServiceInstanceName());
                if (reportDebugMsgs) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
                            + ": " + app + ", due to " + client
@@ -2224,7 +2225,7 @@ public class OomAdjusterImpl extends OomAdjuster {
                app.setAdjType("cch-as-act");
            }
        }
        final ActivityServiceConnectionsHolder a = cr.activity;
        final ActivityServiceConnectionsHolder a = cr.getActivity();
        if (cr.hasFlag(Context.BIND_ADJUST_WITH_ACTIVITY)) {
            if (a != null && adj > FOREGROUND_APP_ADJ
                    && a.isActivityVisible()) {
@@ -2245,7 +2246,7 @@ public class OomAdjusterImpl extends OomAdjuster {
                    app.setAdjTypeCode(ActivityManager.RunningAppProcessInfo.REASON_SERVICE_IN_USE);
                    app.setAdjSource(a);
                    app.setAdjSourceProcState(procState);
                    app.setAdjTarget(cr.binding.service.instanceName);
                    app.setAdjTarget(cr.getServiceInstanceName());
                    if (reportDebugMsgs) {
                        reportOomAdjMessageLocked(TAG_OOM_ADJ,
                                "Raise to service w/activity: " + app);
+132 −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 com.android.server.am.psc;

import android.content.ComponentName;
import android.content.Context;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;

import com.android.server.am.OomAdjuster;
import com.android.server.am.OomAdjusterImpl;
import com.android.server.wm.ActivityServiceConnectionsHolder;

/**
 * An abstract base class encapsulating common internal properties and state for a single binding
 * to a service.
 */
@RavenwoodKeepWholeClass
public abstract class ConnectionRecordInternal implements OomAdjusterImpl.Connection {
    /** The service binding operation. */
    private final long mFlags;
    /** Whether there are currently ongoing transactions over this service connection. */
    private boolean mOngoingCalls;

    /** Returns the {@link ActivityServiceConnectionsHolder} associated with this connection. */
    public abstract ActivityServiceConnectionsHolder getActivity();

    /**
     * Returns the last activity time of the service associated with this connection,
     * in milliseconds.
     * TODO(b/425766486): Remove it once ConnectionRecordInternal could access ServiceRecord.
     */
    public abstract long getServiceLastActivityTimeMillis();

    /**
     * Returns the {@link ComponentName} of the service instance that this connection is bound to.
     * TODO(b/425766486): Remove it once ConnectionRecordInternal could access ServiceRecord.
     */
    public abstract ComponentName getServiceInstanceName();

    /** Tracks the current process state and sequence number for association management. */
    public abstract void trackProcState(int procState, int seq);

    public ConnectionRecordInternal(long flags) {
        this.mFlags = flags;
    }

    public long getFlags() {
        return mFlags;
    }

    /**
     * Checks if any of specific flags (int) is set for this connection.
     * Because the bind flags are bitwise flags, we can check for multiple flags by
     * bitwise-ORing them together (e.g., {@code hasFlag(FLAG1 | FLAG2)}). In this
     * case, the method returns true if *any* of the specified flags are present.
     */
    public boolean hasFlag(final int flag) {
        return hasFlag(Integer.toUnsignedLong(flag));
    }

    /**
     * Checks if any of specific flags (long) is set for this connection.
     * Because the bind flags are bitwise flags, we can check for multiple flags by
     * bitwise-ORing them together (e.g., {@code hasFlag(FLAG1 | FLAG2)}). In this
     * case, the method returns true if *any* of the specified flags are present.
     */
    public boolean hasFlag(final long flag) {
        return (mFlags & flag) != 0;
    }

    /** Checks if all of the specific flags (int) are NOT set for this connection. */
    public boolean notHasFlag(final int flag) {
        return !hasFlag(flag);
    }

    /** Checks if all of the specific flag (long) are NOT set for this connection. */
    public boolean notHasFlag(final long flag) {
        return !hasFlag(flag);
    }

    public boolean getOngoingCalls() {
        return mOngoingCalls;
    }

    /** Sets the ongoing calls status for this connection. Returns true if the status is changed. */
    public boolean setOngoingCalls(boolean ongoingCalls) {
        if (mOngoingCalls != ongoingCalls) {
            mOngoingCalls = ongoingCalls;
            return true;
        }
        return false;
    }

    @Override
    public void computeHostOomAdjLSP(OomAdjuster oomAdjuster, ProcessRecordInternal host,
            ProcessRecordInternal client, long now, ProcessRecordInternal topApp, boolean doingAll,
            int oomAdjReason, int cachedAdj) {
        oomAdjuster.computeServiceHostOomAdjLSP(this, host, client, now, false);
    }

    @Override
    public boolean canAffectCapabilities() {
        return hasFlag(Context.BIND_INCLUDE_CAPABILITIES
                | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS);
    }

    @Override
    public int cpuTimeTransmissionType() {
        if (mOngoingCalls) {
            return CPU_TIME_TRANSMISSION_NORMAL;
        }
        if (hasFlag(Context.BIND_ALLOW_FREEZE)) {
            return CPU_TIME_TRANSMISSION_NONE;
        }
        return hasFlag(Context.BIND_SIMULATE_ALLOW_FREEZE) ? CPU_TIME_TRANSMISSION_LEGACY
                : CPU_TIME_TRANSMISSION_NORMAL;
    }
}