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

Commit 672d8a7a authored by Arthur Ishiguro's avatar Arthur Ishiguro
Browse files

Adds client info in ContextHubService dump

Example:
...
=================== CLIENTS ====================
[ContextHubClient endpointID: 0, contextHub: 0, package: android.uid.system:1000]
[ContextHubClient endpointID: 1, contextHub: 0, package: com.google.oslo]
[ContextHubClient endpointID: 2, contextHub: 0, package: com.google.oslo]
[ContextHubClient endpointID: 3, contextHub: 0, package: com.google.oslo]
[ContextHubClient endpointID: 4, contextHub: 0, package: com.google.oslo]
[ContextHubClient endpointID: 5, contextHub: 0, package: com.google.oslo]
[ContextHubClient endpointID: 6, contextHub: 0, package: com.google.oslo]
[ContextHubClient endpointID: 7, contextHub: 0, package: android.uid.systemui:10124]
[ContextHubClient endpointID: 8, contextHub: 0, intentCreatorPackage: com.google.android.apps.scone, nanoAppId: 0x476f6f676c001016]

Registration history:
12/03 14:58:17.410 - [ContextHubClient endpointID: 9, contextHub: 0, package: com.google.uid.shared:10113]
12/03 14:58:17.403 + [ContextHubClient endpointID: 9, contextHub: 0, package: com.google.uid.shared:10113]
12/03 14:58:10.295 + [ContextHubClient endpointID: 8, contextHub: 0, intentCreatorPackage: com.google.android.apps.scone, nanoAppId: 0x476f6f676c001016]
12/03 14:58:05.501 + [ContextHubClient endpointID: 7, contextHub: 0, package: android.uid.systemui:10124]
12/03 14:58:05.379 + [ContextHubClient endpointID: 6, contextHub: 0, package: com.google.oslo]
12/03 14:58:05.375 + [ContextHubClient endpointID: 5, contextHub: 0, package: com.google.oslo]
12/03 14:58:05.371 + [ContextHubClient endpointID: 4, contextHub: 0, package: com.google.oslo]
12/03 14:58:05.367 + [ContextHubClient endpointID: 3, contextHub: 0, package: com.google.oslo]
12/03 14:58:05.365 + [ContextHubClient endpointID: 2, contextHub: 0, package: com.google.oslo]
12/03 14:58:05.362 + [ContextHubClient endpointID: 1, contextHub: 0, package: com.google.oslo]
12/03 14:58:04.257 + [ContextHubClient endpointID: 0, contextHub: 0, package: android.uid.system:1000]

Bug: 121033022
Test: adb shell dumpsys contexthub
Change-Id: I33f49c1e8a144ea2818add0e0b4c52d1f5454b65
parent fceab665
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -29,10 +29,12 @@ import android.hardware.location.ContextHubTransaction;
import android.hardware.location.IContextHubClient;
import android.hardware.location.IContextHubClientCallback;
import android.hardware.location.NanoAppMessage;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;

/**
@@ -96,6 +98,16 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
     */
    private final PendingIntentRequest mPendingIntentRequest;

    /*
     * The host package associated with this client.
     */
    private final String mPackage;

    /*
     * True if a PendingIntent has been cancelled.
     */
    private AtomicBoolean mIsPendingIntentCancelled = new AtomicBoolean(false);

    /*
     * Helper class to manage registered PendingIntent requests from the client.
     */
@@ -110,11 +122,14 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
         */
        private long mNanoAppId;

        private boolean mValid = false;

        PendingIntentRequest() {}

        PendingIntentRequest(PendingIntent pendingIntent, long nanoAppId) {
            mPendingIntent = pendingIntent;
            mNanoAppId = nanoAppId;
            mValid = true;
        }

        public long getNanoAppId() {
@@ -132,6 +147,10 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
        public void clear() {
            mPendingIntent = null;
        }

        public boolean isValid() {
            return mValid;
        }
    }

    /* package */ ContextHubClientBroker(
@@ -145,6 +164,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
        mHostEndPointId = hostEndPointId;
        mCallbackInterface = callback;
        mPendingIntentRequest = new PendingIntentRequest();
        mPackage = mContext.getPackageManager().getNameForUid(Binder.getCallingUid());
    }

    /* package */ ContextHubClientBroker(
@@ -157,6 +177,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
        mAttachedContextHubInfo = contextHubInfo;
        mHostEndPointId = hostEndPointId;
        mPendingIntentRequest = new PendingIntentRequest(pendingIntent, nanoAppId);
        mPackage = pendingIntent.getCreatorPackage();
    }

    /**
@@ -312,6 +333,13 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
        }
    }

    /**
     * @return true if the client is a PendingIntent client that has been cancelled.
     */
    /* package */ boolean isPendingIntentCancelled() {
        return mIsPendingIntentCancelled.get();
    }

    /**
     * Helper function to invoke a specified client callback, if the connection is open.
     *
@@ -392,6 +420,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
                    Manifest.permission.LOCATION_HARDWARE /* requiredPermission */,
                    null /* options */);
        } catch (PendingIntent.CanceledException e) {
            mIsPendingIntentCancelled.set(true);
            // The PendingIntent is no longer valid
            Log.w(TAG, "PendingIntent has been canceled, unregistering from client"
                    + " (host endpoint ID " + mHostEndPointId + ")");
@@ -419,4 +448,20 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
            mRegistered = false;
        }
    }

    @Override
    public String toString() {
        String out = "[ContextHubClient ";
        out += "endpointID: " + getHostEndPointId() + ", ";
        out += "contextHub: " + getAttachedContextHubId() + ", ";
        if (mPendingIntentRequest.isValid()) {
            out += "intentCreatorPackage: " + mPackage + ", ";
            out += "nanoAppId: 0x" + Long.toHexString(mPendingIntentRequest.getNanoAppId());
        } else {
            out += "package: " + mPackage;
        }
        out += "]";

        return out;
    }
}
+106 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.location;

import android.annotation.IntDef;
import android.app.PendingIntent;
import android.content.Context;
import android.hardware.contexthub.V1_0.ContextHubMsg;
@@ -27,7 +28,12 @@ import android.hardware.location.NanoAppMessage;
import android.os.RemoteException;
import android.util.Log;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Calendar;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.function.Consumer;

/**
@@ -71,6 +77,79 @@ import java.util.function.Consumer;
     */
    private int mNextHostEndPointId = 0;

    /*
     * The list of previous registration records.
     */
    private static final int NUM_CLIENT_RECORDS = 20;
    private final ConcurrentLinkedEvictingDeque<RegistrationRecord> mRegistrationRecordDeque =
            new ConcurrentLinkedEvictingDeque<>(NUM_CLIENT_RECORDS);

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "ACTION_" }, value = {
            ACTION_REGISTERED,
            ACTION_UNREGISTERED,
            ACTION_CANCELLED,
    })
    public @interface Action {}
    public static final int ACTION_REGISTERED = 0;
    public static final int ACTION_UNREGISTERED = 1;
    public static final int ACTION_CANCELLED = 2;

    /**
     * Helper class to make a ConcurrentLinkedDeque fixed-size, evicting old entries when full.
     */
    private class ConcurrentLinkedEvictingDeque<E> extends ConcurrentLinkedDeque<E> {
        private int mSize;

        ConcurrentLinkedEvictingDeque(int size) {
            mSize = size;
        }

        @Override
        public boolean add(E elem) {
            synchronized (this) {
                if (size() == mSize) {
                    poll();
                }

                return super.add(elem);
            }
        }
    }

    /**
     * A container class to store a record of ContextHubClient registration.
     */
    private class RegistrationRecord {
        private final String mBroker;
        private final int mAction;
        private final String mDate;

        RegistrationRecord(String broker, @Action int action) {
            mBroker = broker;
            mAction = action;
            Calendar instance = Calendar.getInstance();
            mDate = String.format("%02d", instance.get(Calendar.MONTH) + 1) // Jan == 0
                + "/" + String.format("%02d", instance.get(Calendar.DAY_OF_MONTH))
                + " " + String.format("%02d", instance.get(Calendar.HOUR_OF_DAY))
                + ":" + String.format("%02d", instance.get(Calendar.MINUTE))
                + ":" + String.format("%02d", instance.get(Calendar.SECOND))
                + "." + String.format("%03d", instance.get(Calendar.MILLISECOND));
        }

        @Override
        public String toString() {
            String out = "";
            out += mDate + " ";
            out += mAction == ACTION_REGISTERED ? "+ " : "- ";
            out += mBroker;
            if (mAction == ACTION_CANCELLED) {
                out += " (cancelled)";
            }
            return out;
        }
    }

    /* package */ ContextHubClientManager(
            Context context, IContexthub contextHubProxy) {
        mContext = context;
@@ -96,6 +175,8 @@ import java.util.function.Consumer;
                    mContext, mContextHubProxy, this /* clientManager */, contextHubInfo,
                    hostEndPointId, clientCallback);
            mHostEndPointIdToClientMap.put(hostEndPointId, broker);
            mRegistrationRecordDeque.add(
                    new RegistrationRecord(broker.toString(), ACTION_REGISTERED));
        }

        try {
@@ -136,6 +217,8 @@ import java.util.function.Consumer;
                        hostEndPointId, pendingIntent, nanoAppId);
                mHostEndPointIdToClientMap.put(hostEndPointId, broker);
                registerString = "Registered";
                mRegistrationRecordDeque.add(
                        new RegistrationRecord(broker.toString(), ACTION_REGISTERED));
            }
        }

@@ -178,6 +261,13 @@ import java.util.function.Consumer;
     * @param hostEndPointId the host endpoint ID of the client that has died
     */
    /* package */ void unregisterClient(short hostEndPointId) {
        ContextHubClientBroker broker = mHostEndPointIdToClientMap.get(hostEndPointId);
        if (broker != null) {
            @Action int action =
                    broker.isPendingIntentCancelled() ? ACTION_CANCELLED : ACTION_UNREGISTERED;
            mRegistrationRecordDeque.add(new RegistrationRecord(broker.toString(), action));
        }

        if (mHostEndPointIdToClientMap.remove(hostEndPointId) != null) {
            Log.d(TAG, "Unregistered client with host endpoint ID " + hostEndPointId);
        } else {
@@ -285,4 +375,20 @@ import java.util.function.Consumer;

        return null;
    }

    @Override
    public String toString() {
        String out = "";
        for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) {
            out += broker + "\n";
        }

        out += "\nRegistration history:\n";
        Iterator<RegistrationRecord> it = mRegistrationRecordDeque.descendingIterator();
        while (it.hasNext()) {
            out += it.next() + "\n";
        }

        return out;
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -795,6 +795,10 @@ public class ContextHubService extends IContextHubService.Stub {
        // Dump nanoAppHash
        mNanoAppStateManager.foreachNanoAppInstanceInfo((info) -> pw.println(info));

        pw.println("");
        pw.println("=================== CLIENTS ====================");
        pw.println(mClientManager);

        // dump eventLog
    }