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

Commit 05f4d2d6 authored by David Riley's avatar David Riley
Browse files

Add test API to retrieve service connections for test verification.

This will allow tests to verify the current AMS state without having to
resort to parsing dumpsys output.

Bug: 424003130
Flag: TEST_ONLY
Test: atest android.app.cts.service.ServiceTest
Change-Id: I2dde02e0aba3667c7b1e209106ca0a989d87921f
parent 93e85658
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ package android.app {
    method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener);
    method public void alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName);
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public int[] getDisplayIdsForStartingVisibleBackgroundUsers();
    method @NonNull public java.util.List<android.app.ActivityManager.ConnectionInfo> getRunningServiceConnections(@NonNull android.content.ComponentName);
    method public long getTotalRam();
    method @NonNull @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int[] getUidFrozenState(@NonNull int[]);
    method @RequiresPermission(allOf={android.Manifest.permission.PACKAGE_USAGE_STATS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}, conditional=true) public int getUidProcessCapabilities(int);
@@ -174,6 +175,16 @@ package android.app {
    field public static final int STOP_USER_ON_SWITCH_TRUE = 1; // 0x1
  }

  public static final class ActivityManager.ConnectionInfo implements android.os.Parcelable {
    ctor public ActivityManager.ConnectionInfo(long, @NonNull String, @NonNull String);
    method public int describeContents();
    method public long getFlags();
    method @NonNull public String getPackageName();
    method @NonNull public String getProcessName();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.ActivityManager.ConnectionInfo> CREATOR;
  }

  public static class ActivityManager.RunningAppProcessInfo implements android.os.Parcelable {
    field public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170; // 0xaa
  }
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

parcelable ActivityManager.ConnectionInfo;
parcelable ActivityManager.MemoryInfo;
parcelable ActivityManager.PendingIntentInfo;
parcelable ActivityManager.ProcessErrorStateInfo;
+101 −0
Original line number Diff line number Diff line
@@ -3444,6 +3444,91 @@ public class ActivityManager {
        }
    }

    /** @hide */
    @TestApi
    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
    public static final class ConnectionInfo implements Parcelable {
        /**
         * Bind service flags.
         */
        private final long mFlags;

        /**
         * Client process name.
         */
        private final @NonNull String mProcessName;

        /**
         * Client package name.
         */
        private final @NonNull String mPackageName;

        @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
        /** @hide */
        public ConnectionInfo(long flags,
                @NonNull String processName,
                @NonNull String packageName) {
            mFlags = flags;
            mProcessName = processName;
            mPackageName = packageName;
        }

        @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
        /** @hide */
        private ConnectionInfo(@NonNull Parcel source) {
            mFlags = source.readLong();
            mProcessName = source.readString8();
            mPackageName = source.readString8();
        }

        @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
        /** @hide */
        public static final @NonNull Creator<ConnectionInfo> CREATOR =
                new Creator<ConnectionInfo>() {
                    public ConnectionInfo createFromParcel(Parcel source) {
                        return new ConnectionInfo(source);
                    }
                    public ConnectionInfo[] newArray(int size) {
                        return new ConnectionInfo[size];
                    }
                };

        /**
         * Write parcel.
         * @hide
         */
        @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeLong(mFlags);
            dest.writeString8(mProcessName);
            dest.writeString8(mPackageName);
        }

        /**
         * Describe contents.
         * @hide
         */
        @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
        public int describeContents() {
            return 0;
        }

        @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
        public long getFlags() {
            return mFlags;
        }

        @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
        public @NonNull String getProcessName() {
            return mProcessName;
        }

        @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
        public @NonNull String getPackageName() {
            return mPackageName;
        }
    }

    /**
     * Returns a PendingIntent you can start to show a control panel for the
     * given running service.  If the service does not have a control panel,
@@ -3459,6 +3544,22 @@ public class ActivityManager {
        }
    }

    /**
     * Returns a list of ConnectionInfo for connections bound to a given service.
     * @hide
     */
    @TestApi
    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
    public @NonNull List<ConnectionInfo> getRunningServiceConnections(
            @NonNull ComponentName service) {
        Objects.requireNonNull(service);
        try {
            return getService().getRunningServiceConnections(service);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Information you can retrieve about the available memory through
     * {@link ActivityManager#getMemoryInfo}.
+1 −0
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ interface IActivityManager {
            in List<ContentProviderHolder> providers);
    boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta);
    PendingIntent getRunningServiceControlPanel(in ComponentName service);
    List<ActivityManager.ConnectionInfo> getRunningServiceConnections(in ComponentName service);
    ComponentName startService(in IApplicationThread caller, in Intent service,
            in String resolvedType, boolean requireForeground, in String callingPackage,
            in String callingFeatureId, int userId);
+37 −0
Original line number Diff line number Diff line
@@ -7659,6 +7659,43 @@ public final class ActiveServices {
        return null;
    }

    /**
     * Create a ConnectionInfo for test verification from a ConnectionRecord
     */
    ActivityManager.ConnectionInfo makeConnectionInfoLocked(ConnectionRecord r) {
        final ActivityManager.ConnectionInfo info =
                new ActivityManager.ConnectionInfo(r.getFlags(),
                                r.getClientProcessName(),
                                r.getClientPackageName());
        return info;
    }

    /**
     * Get a list of connections to a given service for test verification.
     */
    public List<ActivityManager.ConnectionInfo> getRunningServiceConnectionsLocked(
                    ComponentName name) {

        final int userId = UserHandle.getUserId(mAm.mInjector.getCallingUid());
        final ServiceRecord r = getServiceByNameLocked(name, userId);
        if (r == null) {
            return new ArrayList<ActivityManager.ConnectionInfo>();
        }

        final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
        final ArrayList<ActivityManager.ConnectionInfo> res =
                new ArrayList<ActivityManager.ConnectionInfo>(connections.size());
        for (int conni = 0; conni < connections.size(); conni++) {
            final ArrayList<ConnectionRecord> conn = connections.valueAt(conni);
            for (int i = 0; i < conn.size(); i++) {
                final ConnectionRecord cr = conn.get(i);
                res.add(makeConnectionInfoLocked(conn.get(i)));
            }
        }

        return res;
    }

    void serviceTimeout(ProcessRecord proc) {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceTimeout()");
Loading