Loading services/companion/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -26,5 +26,6 @@ java_library_static { ], static_libs: [ "ukey2_jni", "virtualdevice_flags_lib", ], } services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -197,6 +198,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub Context context, AssociationInfo associationInfo, VirtualDeviceManagerService service, VirtualDeviceLog virtualDeviceLog, IBinder token, AttributionSource attributionSource, int deviceId, Loading @@ -210,6 +212,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub context, associationInfo, service, virtualDeviceLog, token, attributionSource, deviceId, Loading @@ -228,6 +231,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub Context context, AssociationInfo associationInfo, VirtualDeviceManagerService service, VirtualDeviceLog virtualDeviceLog, IBinder token, AttributionSource attributionSource, int deviceId, Loading @@ -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); Loading Loading @@ -271,6 +276,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } mVirtualDeviceLog.logCreated(deviceId, mOwnerUid); } @VisibleForTesting Loading Loading @@ -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. Loading services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java 0 → 100644 +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; } } } } services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +6 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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(); Loading Loading @@ -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); } } Loading services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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(); } Loading Loading @@ -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, Loading services/companion/java/com/android/server/companion/virtual/Android.bp +1 −1 File changed.Contains only whitespace changes. Show changes Loading
services/companion/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -26,5 +26,6 @@ java_library_static { ], static_libs: [ "ukey2_jni", "virtualdevice_flags_lib", ], }
services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -197,6 +198,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub Context context, AssociationInfo associationInfo, VirtualDeviceManagerService service, VirtualDeviceLog virtualDeviceLog, IBinder token, AttributionSource attributionSource, int deviceId, Loading @@ -210,6 +212,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub context, associationInfo, service, virtualDeviceLog, token, attributionSource, deviceId, Loading @@ -228,6 +231,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub Context context, AssociationInfo associationInfo, VirtualDeviceManagerService service, VirtualDeviceLog virtualDeviceLog, IBinder token, AttributionSource attributionSource, int deviceId, Loading @@ -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); Loading Loading @@ -271,6 +276,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } mVirtualDeviceLog.logCreated(deviceId, mOwnerUid); } @VisibleForTesting Loading Loading @@ -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. Loading
services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java 0 → 100644 +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; } } } }
services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +6 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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(); Loading Loading @@ -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); } } Loading
services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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(); } Loading Loading @@ -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, Loading
services/companion/java/com/android/server/companion/virtual/Android.bp +1 −1 File changed.Contains only whitespace changes. Show changes