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

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

Merge "Add history to VDM dumpsys" into main

parents c7bd0f9a fc3624a5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,5 +26,6 @@ java_library_static {
    ],
    static_libs: [
        "ukey2_jni",
        "virtualdevice_flags_lib",
    ],
}
+7 −0
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
    private final VirtualDeviceManagerService mService;
    private final PendingTrampolineCallback mPendingTrampolineCallback;
    private final int mOwnerUid;
    private final VirtualDeviceLog mVirtualDeviceLog;
    private final String mOwnerPackageName;
    private int mDeviceId;
    private @Nullable String mPersistentDeviceId;
@@ -197,6 +198,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            Context context,
            AssociationInfo associationInfo,
            VirtualDeviceManagerService service,
            VirtualDeviceLog virtualDeviceLog,
            IBinder token,
            AttributionSource attributionSource,
            int deviceId,
@@ -210,6 +212,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
                context,
                associationInfo,
                service,
                virtualDeviceLog,
                token,
                attributionSource,
                deviceId,
@@ -228,6 +231,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            Context context,
            AssociationInfo associationInfo,
            VirtualDeviceManagerService service,
            VirtualDeviceLog virtualDeviceLog,
            IBinder token,
            AttributionSource attributionSource,
            int deviceId,
@@ -240,6 +244,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            VirtualDeviceParams params,
            DisplayManagerGlobal displayManager) {
        super(PermissionEnforcer.fromContext(context));
        mVirtualDeviceLog = virtualDeviceLog;
        mOwnerPackageName = attributionSource.getPackageName();
        UserHandle ownerUserHandle = UserHandle.getUserHandleForUid(attributionSource.getUid());
        mContext = context.createContextAsUser(ownerUserHandle, 0);
@@ -271,6 +276,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        mVirtualDeviceLog.logCreated(deviceId, mOwnerUid);
    }

    @VisibleForTesting
@@ -405,6 +411,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        super.close_enforcePermission();
        // Remove about-to-be-closed virtual device from the service before butchering it.
        boolean removed = mService.removeVirtualDevice(mDeviceId);
        mVirtualDeviceLog.logClosed(mDeviceId, mOwnerUid);
        mDeviceId = Context.DEVICE_ID_INVALID;

        // Device is already closed.
+152 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.companion.virtual;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.util.SparseArray;

import java.io.PrintWriter;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayDeque;

final class VirtualDeviceLog {
    public static int TYPE_CREATED = 0x0;
    public static int TYPE_CLOSED = 0x1;

    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern(
            "MM-dd HH:mm:ss.SSS").withZone(ZoneId.systemDefault());
    private static final int MAX_ENTRIES = 16;

    private final Context mContext;
    private final ArrayDeque<LogEntry> mLogEntries = new ArrayDeque<>();

    VirtualDeviceLog(Context context) {
        mContext = context;
    }

    void logCreated(int deviceId, int ownerUid) {
        final long token = Binder.clearCallingIdentity();
        try {
            if (!Flags.dumpHistory()) {
                return;
            }
            addEntry(new LogEntry(TYPE_CREATED, deviceId, System.currentTimeMillis(), ownerUid));
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    void logClosed(int deviceId, int ownerUid) {
        final long token = Binder.clearCallingIdentity();
        try {
            if (!Flags.dumpHistory()) {
                return;
            }
            addEntry(new LogEntry(TYPE_CLOSED, deviceId, System.currentTimeMillis(), ownerUid));
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    private void addEntry(LogEntry entry) {
        mLogEntries.push(entry);
        if (mLogEntries.size() > MAX_ENTRIES) {
            mLogEntries.removeLast();
        }
    }

    void dump(PrintWriter pw) {
        final long token = Binder.clearCallingIdentity();
        try {
            if (!Flags.dumpHistory()) {
                return;
            }
            pw.println("VirtualDevice Log:");
            UidToPackageNameCache packageNameCache = new UidToPackageNameCache(
                    mContext.getPackageManager());
            for (LogEntry logEntry : mLogEntries) {
                logEntry.dump(pw, "  ", packageNameCache);

            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    static class LogEntry {
        private final int mType;
        private final int mDeviceId;
        private final long mTimestamp;
        private final int mOwnerUid;

        LogEntry(int type, int deviceId, long timestamp, int ownerUid) {
            this.mType = type;
            this.mDeviceId = deviceId;
            this.mTimestamp = timestamp;
            this.mOwnerUid = ownerUid;
        }

        void dump(PrintWriter pw, String prefix, UidToPackageNameCache packageNameCache) {
            StringBuilder sb = new StringBuilder(prefix);
            sb.append(DATE_FORMAT.format(Instant.ofEpochMilli(mTimestamp)));
            sb.append(" - ");
            sb.append(mType == TYPE_CREATED ? "START" : "CLOSE");
            sb.append(" Device ID: ");
            sb.append(mDeviceId);
            sb.append(" ");
            sb.append(mOwnerUid);
            sb.append(" (");
            sb.append(packageNameCache.getPackageName(mOwnerUid));
            sb.append(")");
            pw.println(sb);
        }
    }

    private static class UidToPackageNameCache {
        private final PackageManager mPackageManager;
        private final SparseArray<String> mUidToPackagesCache = new SparseArray<>();

        public UidToPackageNameCache(PackageManager packageManager) {
            mPackageManager = packageManager;
        }

        String getPackageName(int ownerUid) {
            String[] packages;
            if (mUidToPackagesCache.contains(ownerUid)) {
                return mUidToPackagesCache.get(ownerUid);
            } else {
                packages = mPackageManager.getPackagesForUid(ownerUid);
                String packageName = "";
                if (packages != null && packages.length > 0) {
                    packageName = packages[0];
                    if (packages.length > 1) {
                        StringBuilder sb = new StringBuilder();
                        sb.append(packageName)
                                .append(",...");
                        packageName = sb.toString();
                    }
                }
                mUidToPackagesCache.put(ownerUid, packageName);
                return packageName;
            }
        }
    }
}
+6 −1
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ public class VirtualDeviceManagerService extends SystemService {
    private final Object mVirtualDeviceManagerLock = new Object();
    private final VirtualDeviceManagerImpl mImpl;
    private final VirtualDeviceManagerInternal mLocalService;
    private VirtualDeviceLog mVirtualDeviceLog = new VirtualDeviceLog(getContext());
    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private final PendingTrampolineMap mPendingTrampolines = new PendingTrampolineMap(mHandler);

@@ -344,9 +345,11 @@ public class VirtualDeviceManagerService extends SystemService {
            final Consumer<ArraySet<Integer>> runningAppsChangedCallback =
                    runningUids -> notifyRunningAppsChanged(deviceId, runningUids);
            VirtualDeviceImpl virtualDevice = new VirtualDeviceImpl(getContext(), associationInfo,
                    VirtualDeviceManagerService.this, token, attributionSource, deviceId,
                    VirtualDeviceManagerService.this, mVirtualDeviceLog, token, attributionSource,
                    deviceId,
                    cameraAccessController, mPendingTrampolineCallback, activityListener,
                    soundEffectListener, runningAppsChangedCallback, params);

            synchronized (mVirtualDeviceManagerLock) {
                if (mVirtualDevices.size() == 0) {
                    final long callindId = Binder.clearCallingIdentity();
@@ -521,6 +524,8 @@ public class VirtualDeviceManagerService extends SystemService {
            for (int i = 0; i < virtualDevicesSnapshot.size(); i++) {
                virtualDevicesSnapshot.get(i).dump(fd, fout, args);
            }

            mVirtualDeviceLog.dump(fout);
        }
    }

+3 −1
Original line number Diff line number Diff line
@@ -226,6 +226,7 @@ public class VirtualDeviceManagerServiceTest {
    private VirtualDeviceManagerService mVdms;
    private VirtualDeviceManagerInternal mLocalService;
    private VirtualDeviceManagerService.VirtualDeviceManagerImpl mVdm;
    private VirtualDeviceLog mVirtualDeviceLog;
    @Mock
    private InputController.NativeWrapper mNativeWrapperMock;
    @Mock
@@ -370,6 +371,7 @@ public class VirtualDeviceManagerServiceTest {
        mVdms = new VirtualDeviceManagerService(mContext);
        mLocalService = mVdms.getLocalServiceInstance();
        mVdm = mVdms.new VirtualDeviceManagerImpl();
        mVirtualDeviceLog = new VirtualDeviceLog(mContext);
        mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1);
        mSensorController = mDeviceImpl.getSensorControllerForTest();
    }
@@ -1730,7 +1732,7 @@ public class VirtualDeviceManagerServiceTest {
    private VirtualDeviceImpl createVirtualDevice(int virtualDeviceId, int ownerUid,
            VirtualDeviceParams params) {
        VirtualDeviceImpl virtualDeviceImpl = new VirtualDeviceImpl(mContext,
                mAssociationInfo, mVdms, new Binder(),
                mAssociationInfo, mVdms, mVirtualDeviceLog, new Binder(),
                new AttributionSource(ownerUid, "com.android.virtualdevice.test", "virtualdevice"),
                virtualDeviceId,
                mInputController, mCameraAccessController,
+1 −1

File changed.

Contains only whitespace changes.

Loading