Loading packages/SystemUI/src/com/android/systemui/appops/AppOpItem.java +5 −5 Original line number Diff line number Diff line Loading @@ -24,15 +24,15 @@ public class AppOpItem { private int mCode; private int mUid; private String mPackageName; private long mTimeStarted; private long mTimeStartedElapsed; private StringBuilder mState; private boolean mIsDisabled; public AppOpItem(int code, int uid, String packageName, long timeStarted) { public AppOpItem(int code, int uid, String packageName, long timeStartedElapsed) { this.mCode = code; this.mUid = uid; this.mPackageName = packageName; this.mTimeStarted = timeStarted; this.mTimeStartedElapsed = timeStartedElapsed; mState = new StringBuilder() .append("AppOpItem(") .append("Op code=").append(code).append(", ") Loading @@ -53,8 +53,8 @@ public class AppOpItem { return mPackageName; } public long getTimeStarted() { return mTimeStarted; public long getTimeStartedElapsed() { return mTimeStartedElapsed; } public void setDisabled(boolean misDisabled) { Loading packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +7 −5 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dump.DumpManager; import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController; import com.android.systemui.util.Assert; import com.android.systemui.util.time.SystemClock; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -83,8 +84,8 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon private final AppOpsManager mAppOps; private final AudioManager mAudioManager; private final LocationManager mLocationManager; private final PackageManager mPackageManager; private final IndividualSensorPrivacyController mSensorPrivacyController; private final SystemClock mClock; // mLocationProviderPackages are cached and updated only occasionally private static final long LOCATION_PROVIDER_UPDATE_FREQUENCY_MS = 30000; Loading Loading @@ -126,7 +127,8 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon PermissionFlagsCache cache, AudioManager audioManager, IndividualSensorPrivacyController sensorPrivacyController, BroadcastDispatcher dispatcher BroadcastDispatcher dispatcher, SystemClock clock ) { mDispatcher = dispatcher; mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); Loading @@ -142,8 +144,8 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon || mSensorPrivacyController.isSensorBlocked(MICROPHONE); mCameraDisabled = mSensorPrivacyController.isSensorBlocked(CAMERA); mLocationManager = context.getSystemService(LocationManager.class); mPackageManager = context.getPackageManager(); mContext = context; mClock = clock; dumpManager.registerDumpable(TAG, this); } Loading Loading @@ -252,7 +254,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon synchronized (mActiveItems) { AppOpItem item = getAppOpItemLocked(mActiveItems, code, uid, packageName); if (item == null && active) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime()); if (code == AppOpsManager.OP_RECORD_AUDIO) { item.setDisabled(isAnyRecordingPausedLocked(uid)); } else if (code == AppOpsManager.OP_CAMERA) { Loading Loading @@ -294,7 +296,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon synchronized (mNotedItems) { item = getAppOpItemLocked(mNotedItems, code, uid, packageName); if (item == null) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime()); mNotedItems.add(item); if (DEBUG) Log.w(TAG, "Added item: " + item.toString()); createdNew = true; Loading packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +8 −2 Original line number Diff line number Diff line Loading @@ -50,8 +50,14 @@ enum class PrivacyType( fun getIcon(context: Context) = context.resources.getDrawable(iconId, context.theme) } data class PrivacyItem(val privacyType: PrivacyType, val application: PrivacyApplication) { fun toLog(): String = "(${privacyType.logName}, ${application.packageName}(${application.uid}))" private const val UNKNOWN_TIMESTAMP = -1L data class PrivacyItem( val privacyType: PrivacyType, val application: PrivacyApplication, val timeStampElapsed: Long = UNKNOWN_TIMESTAMP ) { val log = "(${privacyType.logName}, ${application.packageName}(${application.uid}), " + "$timeStampElapsed)" } data class PrivacyApplication(val packageName: String, val uid: Int) packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +34 −55 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.systemui.privacy.logging.PrivacyLogger import com.android.systemui.settings.UserTracker import com.android.systemui.util.DeviceConfigProxy import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.time.SystemClock import java.io.FileDescriptor import java.io.PrintWriter import java.lang.ref.WeakReference Loading @@ -50,6 +51,7 @@ class PrivacyItemController @Inject constructor( private val deviceConfigProxy: DeviceConfigProxy, private val userTracker: UserTracker, private val logger: PrivacyLogger, private val systemClock: SystemClock, dumpManager: DumpManager ) : Dumpable { Loading @@ -70,10 +72,9 @@ class PrivacyItemController @Inject constructor( const val TAG = "PrivacyItemController" private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED private const val LOCATION = SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_ENABLED private const val DEFAULT_ALL_INDICATORS = false private const val DEFAULT_MIC_CAMERA = true private const val DEFAULT_LOCATION = false const val TIME_TO_HOLD_INDICATORS = 5000L @VisibleForTesting const val TIME_TO_HOLD_INDICATORS = 5000L } @VisibleForTesting Loading @@ -95,8 +96,8 @@ class PrivacyItemController @Inject constructor( private var listening = false private val callbacks = mutableListOf<WeakReference<Callback>>() private val internalUiExecutor = MyExecutor(uiExecutor) private var holdingIndicators = false private var holdIndicatorsCancelled: Runnable? = null private var holdingRunnableCanceler: Runnable? = null private val notifyChanges = Runnable { val list = privacyList Loading @@ -108,11 +109,6 @@ class PrivacyItemController @Inject constructor( uiExecutor.execute(notifyChanges) } private val stopHoldingAndNotifyChanges = Runnable { updatePrivacyList(true) uiExecutor.execute(notifyChanges) } var micCameraAvailable = isMicCameraEnabled() private set var locationAvailable = isLocationEnabled() Loading Loading @@ -189,14 +185,6 @@ class PrivacyItemController @Inject constructor( userTracker.addCallback(userTrackerCallback, bgExecutor) } private fun setHoldTimer() { holdIndicatorsCancelled?.run() holdingIndicators = true holdIndicatorsCancelled = bgExecutor.executeDelayed({ stopHoldingAndNotifyChanges.run() }, TIME_TO_HOLD_INDICATORS) } private fun update(updateUsers: Boolean) { bgExecutor.execute { if (updateUsers) { Loading Loading @@ -261,14 +249,12 @@ class PrivacyItemController @Inject constructor( removeCallback(WeakReference(callback)) } private fun updatePrivacyList(stopHolding: Boolean = false) { private fun updatePrivacyList() { holdingRunnableCanceler?.run()?.also { holdingRunnableCanceler = null } if (!listening) { privacyList = emptyList() if (holdingIndicators) { holdIndicatorsCancelled?.run() logger.cancelIndicatorsHold() holdingIndicators = false } return } val list = appOpsController.getActiveAppOpsForUser(UserHandle.USER_ALL).filter { Loading @@ -276,43 +262,36 @@ class PrivacyItemController @Inject constructor( it.code == AppOpsManager.OP_PHONE_CALL_MICROPHONE || it.code == AppOpsManager.OP_PHONE_CALL_CAMERA }.mapNotNull { toPrivacyItem(it) }.distinct() processNewList(list, stopHolding) privacyList = processNewList(list) } /** * The controller will only go from indicators to no indicators (and notify its listeners), if * [TIME_TO_HOLD_INDICATORS] has passed since it received an empty list from [AppOpsController]. * Figure out which items have not been around for long enough and put them back in the list. * * Also schedule when we should check again to remove expired items. Because we always retrieve * the current list, we have the latest info. * * If holding the last list (in the [TIME_TO_HOLD_INDICATORS] period) and a new non-empty list * is retrieved from [AppOpsController], it will stop holding and notify about the new list. * @param list map of list retrieved from [AppOpsController]. * @return a list that may have added items that should be kept for some time. */ private fun processNewList(list: List<PrivacyItem>, stopHolding: Boolean) { if (list.isNotEmpty()) { // The new elements is not empty, so regardless of whether we are holding or not, we // clear the holding flag and cancel the delayed runnable. if (holdingIndicators) { holdIndicatorsCancelled?.run() logger.cancelIndicatorsHold() holdingIndicators = false } logger.logUpdatedPrivacyItemsList( list.joinToString(separator = ", ", transform = PrivacyItem::toLog)) privacyList = list } else if (holdingIndicators && stopHolding) { // We are holding indicators, received an empty list and were told to stop holding. logger.finishIndicatorsHold() logger.logUpdatedPrivacyItemsList("") holdingIndicators = false privacyList = list } else if (holdingIndicators && !stopHolding) { // Empty list while we are holding. Ignore } else if (!holdingIndicators && privacyList.isNotEmpty()) { // We are not holding, we were showing some indicators but now we should show nothing. // Start holding. logger.startIndicatorsHold(TIME_TO_HOLD_INDICATORS) setHoldTimer() } // Else. We are not holding, we were not showing anything and the new list is empty. Ignore. private fun processNewList(list: List<PrivacyItem>): List<PrivacyItem> { logger.logRetrievedPrivacyItemsList(list) // Anything earlier than this timestamp can be removed val removeBeforeTime = systemClock.elapsedRealtime() - TIME_TO_HOLD_INDICATORS val mustKeep = privacyList.filter { it.timeStampElapsed > removeBeforeTime && it !in list } // There are items we must keep because they haven't been around for enough time. if (mustKeep.isNotEmpty()) { logger.logPrivacyItemsToHold(mustKeep) val earliestTime = mustKeep.minByOrNull { it.timeStampElapsed }!!.timeStampElapsed // Update the list again when the earliest item should be removed. val delay = earliestTime - removeBeforeTime logger.logPrivacyItemsUpdateScheduled(delay) holdingRunnableCanceler = bgExecutor.executeDelayed(updateListAndNotifyChanges, delay) } return list + mustKeep } private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { Loading @@ -329,7 +308,7 @@ class PrivacyItemController @Inject constructor( return null } val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid) return PrivacyItem(type, app) return PrivacyItem(type, app, appOpItem.timeStartedElapsed) } interface Callback { Loading packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt +21 −16 Original line number Diff line number Diff line Loading @@ -22,10 +22,13 @@ import com.android.systemui.log.LogLevel import com.android.systemui.log.LogMessage import com.android.systemui.log.dagger.PrivacyLog import com.android.systemui.privacy.PrivacyDialog import com.android.systemui.privacy.PrivacyItem import java.text.SimpleDateFormat import java.util.Locale import javax.inject.Inject private const val TAG = "PrivacyLog" private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US) class PrivacyLogger @Inject constructor( @PrivacyLog private val buffer: LogBuffer ) { Loading @@ -41,31 +44,29 @@ class PrivacyLogger @Inject constructor( }) } fun logUpdatedPrivacyItemsList(listAsString: String) { fun logRetrievedPrivacyItemsList(list: List<PrivacyItem>) { log(LogLevel.INFO, { str1 = listAsString str1 = listToString(list) }, { "Updated list: $str1" "Retrieved list to process: $str1" }) } fun startIndicatorsHold(time: Long) { fun logPrivacyItemsToHold(list: List<PrivacyItem>) { log(LogLevel.DEBUG, { int1 = time.toInt() / 1000 str1 = listToString(list) }, { "Starting privacy indicators hold for $int1 seconds" }) } fun cancelIndicatorsHold() { log(LogLevel.VERBOSE, {}, { "Cancel privacy indicators hold" "Holding items: $str1" }) } fun finishIndicatorsHold() { log(LogLevel.DEBUG, {}, { "Finish privacy indicators hold" fun logPrivacyItemsUpdateScheduled(delay: Long) { log(LogLevel.INFO, { val scheduledFor = System.currentTimeMillis() + delay val formattedTimestamp = DATE_FORMAT.format(scheduledFor) str1 = formattedTimestamp }, { "Updating items scheduled for $str1" }) } Loading Loading @@ -130,6 +131,10 @@ class PrivacyLogger @Inject constructor( }) } private fun listToString(list: List<PrivacyItem>): String { return list.joinToString(separator = ", ", transform = PrivacyItem::log) } private inline fun log( logLevel: LogLevel, initializer: LogMessage.() -> Unit, Loading Loading
packages/SystemUI/src/com/android/systemui/appops/AppOpItem.java +5 −5 Original line number Diff line number Diff line Loading @@ -24,15 +24,15 @@ public class AppOpItem { private int mCode; private int mUid; private String mPackageName; private long mTimeStarted; private long mTimeStartedElapsed; private StringBuilder mState; private boolean mIsDisabled; public AppOpItem(int code, int uid, String packageName, long timeStarted) { public AppOpItem(int code, int uid, String packageName, long timeStartedElapsed) { this.mCode = code; this.mUid = uid; this.mPackageName = packageName; this.mTimeStarted = timeStarted; this.mTimeStartedElapsed = timeStartedElapsed; mState = new StringBuilder() .append("AppOpItem(") .append("Op code=").append(code).append(", ") Loading @@ -53,8 +53,8 @@ public class AppOpItem { return mPackageName; } public long getTimeStarted() { return mTimeStarted; public long getTimeStartedElapsed() { return mTimeStartedElapsed; } public void setDisabled(boolean misDisabled) { Loading
packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +7 −5 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dump.DumpManager; import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController; import com.android.systemui.util.Assert; import com.android.systemui.util.time.SystemClock; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -83,8 +84,8 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon private final AppOpsManager mAppOps; private final AudioManager mAudioManager; private final LocationManager mLocationManager; private final PackageManager mPackageManager; private final IndividualSensorPrivacyController mSensorPrivacyController; private final SystemClock mClock; // mLocationProviderPackages are cached and updated only occasionally private static final long LOCATION_PROVIDER_UPDATE_FREQUENCY_MS = 30000; Loading Loading @@ -126,7 +127,8 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon PermissionFlagsCache cache, AudioManager audioManager, IndividualSensorPrivacyController sensorPrivacyController, BroadcastDispatcher dispatcher BroadcastDispatcher dispatcher, SystemClock clock ) { mDispatcher = dispatcher; mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); Loading @@ -142,8 +144,8 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon || mSensorPrivacyController.isSensorBlocked(MICROPHONE); mCameraDisabled = mSensorPrivacyController.isSensorBlocked(CAMERA); mLocationManager = context.getSystemService(LocationManager.class); mPackageManager = context.getPackageManager(); mContext = context; mClock = clock; dumpManager.registerDumpable(TAG, this); } Loading Loading @@ -252,7 +254,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon synchronized (mActiveItems) { AppOpItem item = getAppOpItemLocked(mActiveItems, code, uid, packageName); if (item == null && active) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime()); if (code == AppOpsManager.OP_RECORD_AUDIO) { item.setDisabled(isAnyRecordingPausedLocked(uid)); } else if (code == AppOpsManager.OP_CAMERA) { Loading Loading @@ -294,7 +296,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon synchronized (mNotedItems) { item = getAppOpItemLocked(mNotedItems, code, uid, packageName); if (item == null) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime()); mNotedItems.add(item); if (DEBUG) Log.w(TAG, "Added item: " + item.toString()); createdNew = true; Loading
packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +8 −2 Original line number Diff line number Diff line Loading @@ -50,8 +50,14 @@ enum class PrivacyType( fun getIcon(context: Context) = context.resources.getDrawable(iconId, context.theme) } data class PrivacyItem(val privacyType: PrivacyType, val application: PrivacyApplication) { fun toLog(): String = "(${privacyType.logName}, ${application.packageName}(${application.uid}))" private const val UNKNOWN_TIMESTAMP = -1L data class PrivacyItem( val privacyType: PrivacyType, val application: PrivacyApplication, val timeStampElapsed: Long = UNKNOWN_TIMESTAMP ) { val log = "(${privacyType.logName}, ${application.packageName}(${application.uid}), " + "$timeStampElapsed)" } data class PrivacyApplication(val packageName: String, val uid: Int)
packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +34 −55 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.systemui.privacy.logging.PrivacyLogger import com.android.systemui.settings.UserTracker import com.android.systemui.util.DeviceConfigProxy import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.time.SystemClock import java.io.FileDescriptor import java.io.PrintWriter import java.lang.ref.WeakReference Loading @@ -50,6 +51,7 @@ class PrivacyItemController @Inject constructor( private val deviceConfigProxy: DeviceConfigProxy, private val userTracker: UserTracker, private val logger: PrivacyLogger, private val systemClock: SystemClock, dumpManager: DumpManager ) : Dumpable { Loading @@ -70,10 +72,9 @@ class PrivacyItemController @Inject constructor( const val TAG = "PrivacyItemController" private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED private const val LOCATION = SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_ENABLED private const val DEFAULT_ALL_INDICATORS = false private const val DEFAULT_MIC_CAMERA = true private const val DEFAULT_LOCATION = false const val TIME_TO_HOLD_INDICATORS = 5000L @VisibleForTesting const val TIME_TO_HOLD_INDICATORS = 5000L } @VisibleForTesting Loading @@ -95,8 +96,8 @@ class PrivacyItemController @Inject constructor( private var listening = false private val callbacks = mutableListOf<WeakReference<Callback>>() private val internalUiExecutor = MyExecutor(uiExecutor) private var holdingIndicators = false private var holdIndicatorsCancelled: Runnable? = null private var holdingRunnableCanceler: Runnable? = null private val notifyChanges = Runnable { val list = privacyList Loading @@ -108,11 +109,6 @@ class PrivacyItemController @Inject constructor( uiExecutor.execute(notifyChanges) } private val stopHoldingAndNotifyChanges = Runnable { updatePrivacyList(true) uiExecutor.execute(notifyChanges) } var micCameraAvailable = isMicCameraEnabled() private set var locationAvailable = isLocationEnabled() Loading Loading @@ -189,14 +185,6 @@ class PrivacyItemController @Inject constructor( userTracker.addCallback(userTrackerCallback, bgExecutor) } private fun setHoldTimer() { holdIndicatorsCancelled?.run() holdingIndicators = true holdIndicatorsCancelled = bgExecutor.executeDelayed({ stopHoldingAndNotifyChanges.run() }, TIME_TO_HOLD_INDICATORS) } private fun update(updateUsers: Boolean) { bgExecutor.execute { if (updateUsers) { Loading Loading @@ -261,14 +249,12 @@ class PrivacyItemController @Inject constructor( removeCallback(WeakReference(callback)) } private fun updatePrivacyList(stopHolding: Boolean = false) { private fun updatePrivacyList() { holdingRunnableCanceler?.run()?.also { holdingRunnableCanceler = null } if (!listening) { privacyList = emptyList() if (holdingIndicators) { holdIndicatorsCancelled?.run() logger.cancelIndicatorsHold() holdingIndicators = false } return } val list = appOpsController.getActiveAppOpsForUser(UserHandle.USER_ALL).filter { Loading @@ -276,43 +262,36 @@ class PrivacyItemController @Inject constructor( it.code == AppOpsManager.OP_PHONE_CALL_MICROPHONE || it.code == AppOpsManager.OP_PHONE_CALL_CAMERA }.mapNotNull { toPrivacyItem(it) }.distinct() processNewList(list, stopHolding) privacyList = processNewList(list) } /** * The controller will only go from indicators to no indicators (and notify its listeners), if * [TIME_TO_HOLD_INDICATORS] has passed since it received an empty list from [AppOpsController]. * Figure out which items have not been around for long enough and put them back in the list. * * Also schedule when we should check again to remove expired items. Because we always retrieve * the current list, we have the latest info. * * If holding the last list (in the [TIME_TO_HOLD_INDICATORS] period) and a new non-empty list * is retrieved from [AppOpsController], it will stop holding and notify about the new list. * @param list map of list retrieved from [AppOpsController]. * @return a list that may have added items that should be kept for some time. */ private fun processNewList(list: List<PrivacyItem>, stopHolding: Boolean) { if (list.isNotEmpty()) { // The new elements is not empty, so regardless of whether we are holding or not, we // clear the holding flag and cancel the delayed runnable. if (holdingIndicators) { holdIndicatorsCancelled?.run() logger.cancelIndicatorsHold() holdingIndicators = false } logger.logUpdatedPrivacyItemsList( list.joinToString(separator = ", ", transform = PrivacyItem::toLog)) privacyList = list } else if (holdingIndicators && stopHolding) { // We are holding indicators, received an empty list and were told to stop holding. logger.finishIndicatorsHold() logger.logUpdatedPrivacyItemsList("") holdingIndicators = false privacyList = list } else if (holdingIndicators && !stopHolding) { // Empty list while we are holding. Ignore } else if (!holdingIndicators && privacyList.isNotEmpty()) { // We are not holding, we were showing some indicators but now we should show nothing. // Start holding. logger.startIndicatorsHold(TIME_TO_HOLD_INDICATORS) setHoldTimer() } // Else. We are not holding, we were not showing anything and the new list is empty. Ignore. private fun processNewList(list: List<PrivacyItem>): List<PrivacyItem> { logger.logRetrievedPrivacyItemsList(list) // Anything earlier than this timestamp can be removed val removeBeforeTime = systemClock.elapsedRealtime() - TIME_TO_HOLD_INDICATORS val mustKeep = privacyList.filter { it.timeStampElapsed > removeBeforeTime && it !in list } // There are items we must keep because they haven't been around for enough time. if (mustKeep.isNotEmpty()) { logger.logPrivacyItemsToHold(mustKeep) val earliestTime = mustKeep.minByOrNull { it.timeStampElapsed }!!.timeStampElapsed // Update the list again when the earliest item should be removed. val delay = earliestTime - removeBeforeTime logger.logPrivacyItemsUpdateScheduled(delay) holdingRunnableCanceler = bgExecutor.executeDelayed(updateListAndNotifyChanges, delay) } return list + mustKeep } private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { Loading @@ -329,7 +308,7 @@ class PrivacyItemController @Inject constructor( return null } val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid) return PrivacyItem(type, app) return PrivacyItem(type, app, appOpItem.timeStartedElapsed) } interface Callback { Loading
packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt +21 −16 Original line number Diff line number Diff line Loading @@ -22,10 +22,13 @@ import com.android.systemui.log.LogLevel import com.android.systemui.log.LogMessage import com.android.systemui.log.dagger.PrivacyLog import com.android.systemui.privacy.PrivacyDialog import com.android.systemui.privacy.PrivacyItem import java.text.SimpleDateFormat import java.util.Locale import javax.inject.Inject private const val TAG = "PrivacyLog" private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US) class PrivacyLogger @Inject constructor( @PrivacyLog private val buffer: LogBuffer ) { Loading @@ -41,31 +44,29 @@ class PrivacyLogger @Inject constructor( }) } fun logUpdatedPrivacyItemsList(listAsString: String) { fun logRetrievedPrivacyItemsList(list: List<PrivacyItem>) { log(LogLevel.INFO, { str1 = listAsString str1 = listToString(list) }, { "Updated list: $str1" "Retrieved list to process: $str1" }) } fun startIndicatorsHold(time: Long) { fun logPrivacyItemsToHold(list: List<PrivacyItem>) { log(LogLevel.DEBUG, { int1 = time.toInt() / 1000 str1 = listToString(list) }, { "Starting privacy indicators hold for $int1 seconds" }) } fun cancelIndicatorsHold() { log(LogLevel.VERBOSE, {}, { "Cancel privacy indicators hold" "Holding items: $str1" }) } fun finishIndicatorsHold() { log(LogLevel.DEBUG, {}, { "Finish privacy indicators hold" fun logPrivacyItemsUpdateScheduled(delay: Long) { log(LogLevel.INFO, { val scheduledFor = System.currentTimeMillis() + delay val formattedTimestamp = DATE_FORMAT.format(scheduledFor) str1 = formattedTimestamp }, { "Updating items scheduled for $str1" }) } Loading Loading @@ -130,6 +131,10 @@ class PrivacyLogger @Inject constructor( }) } private fun listToString(list: List<PrivacyItem>): String { return list.joinToString(separator = ", ", transform = PrivacyItem::log) } private inline fun log( logLevel: LogLevel, initializer: LogMessage.() -> Unit, Loading