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

Commit 8e851be1 authored by Evan Chen's avatar Evan Chen
Browse files

Add Device Presence logging

Test: manually
Bug: 412345348
Flag: EXEMPT test fix
Change-Id: I7299cc0088601e3586d15480027408e4da76e859
parent 7a66fbda
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.content.Context.BLUETOOTH_SERVICE;
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;

import static com.android.server.companion.utils.MetricUtils.logDevicePresenceEvent;
import static com.android.server.companion.utils.PermissionsUtils.enforceCallerCanManageAssociationsForPackage;
import static com.android.server.companion.utils.PermissionsUtils.enforceCallerCanObserveDevicePresenceByUuid;

@@ -59,6 +60,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.CollectionUtils;
import com.android.server.companion.CompanionExemptionProcessor;
import com.android.server.companion.association.AssociationStore;
import com.android.server.companion.utils.MetricUtils;

import java.io.PrintWriter;
import java.util.ArrayList;
@@ -663,6 +665,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
        final int userId = association.getUserId();
        final String packageName = association.getPackageName();
        final DevicePresenceEvent event = new DevicePresenceEvent(associationId, eventType, null);
        final String deviceProfile = association.getDeviceProfile();

        if (eventType == EVENT_BLE_APPEARED) {
            synchronized (mBtDisconnectedDevices) {
@@ -694,7 +697,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
                }

                if (association.isSelfManaged() || added) {
                    notifyDevicePresenceEvent(userId, packageName, event);
                    notifyDevicePresenceEvent(userId, packageName, deviceProfile, event);
                    // Also send the legacy callback.
                    legacyNotifyDevicePresenceEvent(association, true);
                }
@@ -713,7 +716,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
                }

                if (association.isSelfManaged() || removed) {
                    notifyDevicePresenceEvent(userId, packageName, event);
                    notifyDevicePresenceEvent(userId, packageName, deviceProfile, event);
                    // Also send the legacy callback.
                    legacyNotifyDevicePresenceEvent(association, false);
                }
@@ -755,7 +758,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene

                bindApplicationIfNeeded(userId, packageName, false);

                notifyDevicePresenceEvent(userId, packageName, event);
                notifyDevicePresenceEvent(userId, packageName, MetricUtils.UUID, event);
                break;
            case EVENT_BT_DISCONNECTED:
                final boolean removed = mConnectedUuidDevices.remove(parcelUuid);
@@ -769,7 +772,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
                    return;
                }

                notifyDevicePresenceEvent(userId, packageName, event);
                notifyDevicePresenceEvent(userId, packageName, MetricUtils.UUID, event);

                if (!shouldBindPackage(userId, packageName)) {
                    mCompanionAppBinder.unbindCompanionApp(userId, packageName);
@@ -813,10 +816,12 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
     * Notify the device presence event to the app.
     */
    private void notifyDevicePresenceEvent(int userId, String packageName,
            DevicePresenceEvent event) {
            String deviceProfileOrUuid, DevicePresenceEvent event) {
        Slog.i(TAG,
                "notifyCompanionDevicePresenceEvent userId=[" + userId + "], packageName=["
                        + packageName + "], event=[" + event + "]...");
                "notifyCompanionDevicePresenceEvent userId=[" + userId + "],"
                        + "packageName=[" + packageName + "],"
                        + "deviceProfileOrUuid=[" + deviceProfileOrUuid + "],"
                        + "event=[" + event + "]...");

        final CompanionServiceConnector primaryServiceConnector =
                mCompanionAppBinder.getPrimaryServiceConnector(userId, packageName);
@@ -825,6 +830,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
            Slog.e(TAG, "Package is NOT bound.");
            return;
        }
        logDevicePresenceEvent(mContext, deviceProfileOrUuid, packageName, event.getEvent());

        primaryServiceConnector.postOnDevicePresenceEvent(event);
    }
+115 −41
Original line number Diff line number Diff line
@@ -24,6 +24,12 @@ import static android.companion.AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_
import static android.companion.AssociationRequest.DEVICE_PROFILE_VIRTUAL_DEVICE;
import static android.companion.AssociationRequest.DEVICE_PROFILE_WATCH;
import static android.companion.AssociationRequest.DEVICE_PROFILE_WEARABLE_SENSING;
import static android.companion.DevicePresenceEvent.EVENT_BLE_APPEARED;
import static android.companion.DevicePresenceEvent.EVENT_BLE_DISAPPEARED;
import static android.companion.DevicePresenceEvent.EVENT_BT_CONNECTED;
import static android.companion.DevicePresenceEvent.EVENT_BT_DISCONNECTED;
import static android.companion.DevicePresenceEvent.EVENT_SELF_MANAGED_APPEARED;
import static android.companion.DevicePresenceEvent.EVENT_SELF_MANAGED_DISAPPEARED;

import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION;
import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__ACTION__CREATED;
@@ -37,55 +43,102 @@ import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION
import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_VIRTUAL_DEVICE;
import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_WATCH;
import static com.android.internal.util.FrameworkStatsLog.CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_WEARABLE_SENSING;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_BLE_APPEARED;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_BLE_DISAPPEARED;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_BT_CONNECTED;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_BT_DISCONNECTED;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_SELF_MANAGED_APPEARED;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_SELF_MANAGED_DISAPPEARED;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_APP_STREAMING;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_AUTO_PROJECTION;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_COMPUTER;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_GLASSES;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_NULL;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_UUID;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_VIRTUAL_DEVICE;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_WATCH;
import static com.android.internal.util.FrameworkStatsLog.DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_WEARABLE_SENSING;
import static com.android.internal.util.FrameworkStatsLog.write;
import static com.android.server.companion.utils.PackageUtils.PACKAGE_NOT_FOUND;
import static com.android.server.companion.utils.PackageUtils.getUidFromPackageName;

import static java.util.Collections.unmodifiableMap;

import android.util.ArrayMap;
import android.content.Context;

import java.util.Map;

public final class MetricUtils {
    /**
     * A String to indicate device presence base on UUID.
     */
    public static final String UUID = "UUID";

    /**
     * A String to indicate the device profile is null.
     */
    private static final String DEVICE_PROFILE_NULL = "null";

    private static final Map<String, Integer> METRIC_DEVICE_PROFILE;
    static {
        final Map<String, Integer> map = new ArrayMap<>();
        map.put(null, CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_NULL);
        map.put(
    private static final Map<String, Integer> ASSOCIATION_ACTION_DEVICE_PROFILE = Map.of(
            DEVICE_PROFILE_NULL,
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_NULL,
            DEVICE_PROFILE_WATCH,
                CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_WATCH
        );
        map.put(
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_WATCH,
            DEVICE_PROFILE_APP_STREAMING,
                CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_APP_STREAMING
        );
        map.put(
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_APP_STREAMING,
            DEVICE_PROFILE_AUTOMOTIVE_PROJECTION,
                CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_AUTO_PROJECTION
        );
        map.put(
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_AUTO_PROJECTION,
            DEVICE_PROFILE_COMPUTER,
                CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_COMPUTER
        );
        map.put(
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_COMPUTER,
            DEVICE_PROFILE_GLASSES,
                CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_GLASSES
        );
        map.put(
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_GLASSES,
            DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
                CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_NEARBY_DEVICE_STREAMING
        );
        map.put(
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
            DEVICE_PROFILE_VIRTUAL_DEVICE,
                CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_VIRTUAL_DEVICE
        );
        map.put(
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_VIRTUAL_DEVICE,
            DEVICE_PROFILE_WEARABLE_SENSING,
            CDM_ASSOCIATION_ACTION__DEVICE_PROFILE__DEVICE_PROFILE_WEARABLE_SENSING
    );

        METRIC_DEVICE_PROFILE = unmodifiableMap(map);
    }
    private static final Map<String, Integer> DEVICE_PRESENCE_CHANGED_DEVICE_PROFILE = Map.of(
            DEVICE_PROFILE_NULL,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_NULL,
            UUID,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_UUID,
            DEVICE_PROFILE_WATCH,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_WATCH,
            DEVICE_PROFILE_APP_STREAMING,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_APP_STREAMING,
            DEVICE_PROFILE_AUTOMOTIVE_PROJECTION,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_AUTO_PROJECTION,
            DEVICE_PROFILE_COMPUTER,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_COMPUTER,
            DEVICE_PROFILE_GLASSES,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_GLASSES,
            DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_APP_STREAMING,
            DEVICE_PROFILE_VIRTUAL_DEVICE,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_VIRTUAL_DEVICE,
            DEVICE_PROFILE_WEARABLE_SENSING,
            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_WEARABLE_SENSING
        );

    private static final Map<Integer, Integer> DEVICE_PRESENCE_CHANGED_EVENT = Map.of(
            EVENT_BLE_APPEARED,
            DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_BLE_APPEARED,
            EVENT_BLE_DISAPPEARED,
            DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_BLE_DISAPPEARED,
            EVENT_BT_CONNECTED,
            DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_BT_CONNECTED,
            EVENT_BT_DISCONNECTED,
            DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_BT_DISCONNECTED,
            EVENT_SELF_MANAGED_APPEARED,
            DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_SELF_MANAGED_APPEARED,
            EVENT_SELF_MANAGED_DISAPPEARED,
            DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_SELF_MANAGED_DISAPPEARED
    );

    /**
     * Log association creation
@@ -93,7 +146,8 @@ public final class MetricUtils {
    public static void logCreateAssociation(String profile) {
        write(CDM_ASSOCIATION_ACTION,
                CDM_ASSOCIATION_ACTION__ACTION__CREATED,
                METRIC_DEVICE_PROFILE.get(profile));
                ASSOCIATION_ACTION_DEVICE_PROFILE.get(
                        profile == null ? DEVICE_PROFILE_NULL : profile));
    }

    /**
@@ -102,6 +156,26 @@ public final class MetricUtils {
    public static void logRemoveAssociation(String profile) {
        write(CDM_ASSOCIATION_ACTION,
                CDM_ASSOCIATION_ACTION__ACTION__REMOVED,
                METRIC_DEVICE_PROFILE.get(profile));
                ASSOCIATION_ACTION_DEVICE_PROFILE.get(
                        profile == null ? DEVICE_PROFILE_NULL : profile));
    }

    /**
     * Log device presence event changed.
     */
    public static void logDevicePresenceEvent(Context context, String deviceProfileOrUuid,
            String packageName, int event) {
        int uid = getUidFromPackageName(context, packageName);
        if (uid != PACKAGE_NOT_FOUND) {
            write(
                    DEVICE_PRESENCE_CHANGED,
                    uid,
                    DEVICE_PRESENCE_CHANGED_DEVICE_PROFILE.getOrDefault(
                            deviceProfileOrUuid == null ? DEVICE_PROFILE_NULL : deviceProfileOrUuid,
                            DEVICE_PRESENCE_CHANGED__DEVICE_PRESENCE_STATUS__NOTIFY_UNKNOWN),
                    DEVICE_PRESENCE_CHANGED_EVENT.getOrDefault(event,
                            DEVICE_PRESENCE_CHANGED__DEVICE_PROFILE__DEVICE_PROFILE_UNKNOWN)
            );
        }
    }
}
+16 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.companion.CompanionDeviceService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -64,6 +65,7 @@ import java.util.Set;
 */
public final class PackageUtils {

    public static final int PACKAGE_NOT_FOUND = -1;
    private static final String TAG = "CDM_PackageUtils";

    private static final Intent COMPANION_SERVICE_INTENT =
@@ -264,4 +266,18 @@ public final class PackageUtils {
            return mode == AppOpsManager.MODE_ALLOWED || mode == AppOpsManager.MODE_DEFAULT;
        }
    }

    /**
     * Get UID from a packageName. Return -1 if the package is not found.
     */
    public static int getUidFromPackageName(Context context, String packageName) {
        PackageManager packageManager = context.getPackageManager();
        try {
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
            return applicationInfo.uid;
        } catch (PackageManager.NameNotFoundException e) {
            Slog.w(TAG, packageName + " is not found");
            return PACKAGE_NOT_FOUND;
        }
    }
}