Loading packages/SystemUI/res/layout/tile_service_request_dialog.xml +1 −2 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ android:layout_marginBottom="16dp" android:textDirection="locale" android:textAlignment="viewStart" android:textAppearance="@style/TextAppearance.PrivacyDialog" android:lineHeight="20sp" android:textAppearance="@style/TextAppearance.Dialog.Body" /> </LinearLayout> packages/SystemUI/res/values/styles.xml +0 −10 Original line number Diff line number Diff line Loading @@ -660,16 +660,6 @@ <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> </style> <!-- TileService request dialog --> <style name="TileRequestDialog" parent="Theme.SystemUI.QuickSettings.Dialog"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@drawable/qs_dialog_bg</item> <item name="android:windowIsFloating">true</item> <item name="android:backgroundDimEnabled">true</item> <item name="android:windowCloseOnTouchOutside">true</item> <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> </style> <!-- USB Contaminant dialog --> <style name ="USBContaminant" /> Loading packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt +2 −20 Original line number Diff line number Diff line Loading @@ -18,11 +18,8 @@ package com.android.systemui.qs.external import android.content.Context import android.graphics.drawable.Icon import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.WindowInsets import android.widget.TextView import com.android.systemui.R import com.android.systemui.plugins.qs.QSTile Loading @@ -38,25 +35,12 @@ import com.android.systemui.statusbar.phone.SystemUIDialog */ class TileRequestDialog( context: Context ) : SystemUIDialog(context, R.style.TileRequestDialog) { ) : SystemUIDialog(context) { companion object { internal val CONTENT_ID = R.id.content } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) window?.apply { attributes.fitInsetsTypes = attributes.fitInsetsTypes or WindowInsets.Type.statusBars() attributes.receiveInsetsIgnoringZOrder = true setLayout( context.resources .getDimensionPixelSize(R.dimen.qs_tile_service_request_dialog_width), WRAP_CONTENT ) } } /** * Set the data of the tile to add, to show the user. */ Loading @@ -76,9 +60,7 @@ class TileRequestDialog( context.resources.getDimensionPixelSize(R.dimen.qs_quick_tile_size) ) } val spacing = context.resources.getDimensionPixelSize( R.dimen.qs_tile_service_request_content_space ) val spacing = 0 setView(ll, spacing, spacing, spacing, spacing / 2) } Loading packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialogEventLogger.kt 0 → 100644 +116 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.systemui.qs.external import android.app.StatusBarManager import androidx.annotation.VisibleForTesting import com.android.internal.logging.InstanceId import com.android.internal.logging.InstanceIdSequence import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger import com.android.internal.logging.UiEventLoggerImpl class TileRequestDialogEventLogger @VisibleForTesting constructor( private val uiEventLogger: UiEventLogger, private val instanceIdSequence: InstanceIdSequence ) { companion object { const val MAX_INSTANCE_ID = 1 shl 20 } constructor() : this(UiEventLoggerImpl(), InstanceIdSequence(MAX_INSTANCE_ID)) /** * Obtain a new [InstanceId] to log a session for a dialog request. */ fun newInstanceId(): InstanceId = instanceIdSequence.newInstanceId() /** * Log that the dialog has been shown to the user for a tile in the given [packageName]. This * call should use a new [instanceId]. */ fun logDialogShown(packageName: String, instanceId: InstanceId) { uiEventLogger.logWithInstanceId( TileRequestDialogEvent.TILE_REQUEST_DIALOG_SHOWN, /* uid */ 0, packageName, instanceId ) } /** * Log the user response to the dialog being shown. Must follow a call to [logDialogShown] that * used the same [packageName] and [instanceId]. Only the following responses are valid: * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_DIALOG_DISMISSED] * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED] * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED] */ fun logUserResponse( @StatusBarManager.RequestResult response: Int, packageName: String, instanceId: InstanceId ) { val event = when (response) { StatusBarManager.TILE_ADD_REQUEST_RESULT_DIALOG_DISMISSED -> { TileRequestDialogEvent.TILE_REQUEST_DIALOG_DISMISSED } StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED -> { TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_NOT_ADDED } StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED -> { TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_ADDED } else -> { throw IllegalArgumentException("User response not valid: $response") } } uiEventLogger.logWithInstanceId(event, /* uid */ 0, packageName, instanceId) } /** * Log that the dialog will not be shown because the tile was already part of the active set. * Corresponds to a response of [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ALREADY_ADDED]. */ fun logTileAlreadyAdded(packageName: String, instanceId: InstanceId) { uiEventLogger.logWithInstanceId( TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_ALREADY_ADDED, /* uid */ 0, packageName, instanceId ) } } enum class TileRequestDialogEvent(private val _id: Int) : UiEventLogger.UiEventEnum { @UiEvent(doc = "Tile request dialog not shown because tile is already added.") TILE_REQUEST_DIALOG_TILE_ALREADY_ADDED(917), @UiEvent(doc = "Tile request dialog shown to user.") TILE_REQUEST_DIALOG_SHOWN(918), @UiEvent(doc = "User dismisses dialog without choosing an option.") TILE_REQUEST_DIALOG_DISMISSED(919), @UiEvent(doc = "User accepts adding tile from dialog.") TILE_REQUEST_DIALOG_TILE_ADDED(920), @UiEvent(doc = "User denies adding tile from dialog.") TILE_REQUEST_DIALOG_TILE_NOT_ADDED(921); override fun getId() = _id } No newline at end of file packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt +14 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ class TileServiceRequestController constructor( private val qsTileHost: QSTileHost, private val commandQueue: CommandQueue, private val commandRegistry: CommandRegistry, private val eventLogger: TileRequestDialogEventLogger, private val dialogCreator: () -> TileRequestDialog = { TileRequestDialog(qsTileHost.context) } ) { Loading Loading @@ -97,25 +98,31 @@ class TileServiceRequestController constructor( icon: Icon?, callback: Consumer<Int> ) { val instanceId = eventLogger.newInstanceId() val packageName = componentName.packageName if (isTileAlreadyAdded(componentName)) { callback.accept(TILE_ALREADY_ADDED) eventLogger.logTileAlreadyAdded(packageName, instanceId) return } val dialogResponse = Consumer<Int> { response -> if (response == ADD_TILE) { addTile(componentName) } dialogCanceller = null eventLogger.logUserResponse(response, packageName, instanceId) callback.accept(response) } val tileData = TileRequestDialog.TileData(appName, label, icon) createDialog(tileData, dialogResponse).also { dialog -> dialogCanceller = { if (componentName.packageName == it) { if (packageName == it) { dialog.cancel() } dialogCanceller = null } }.show() eventLogger.logDialogShown(packageName, instanceId) } private fun createDialog( Loading Loading @@ -168,7 +175,12 @@ class TileServiceRequestController constructor( private val commandRegistry: CommandRegistry ) { fun create(qsTileHost: QSTileHost): TileServiceRequestController { return TileServiceRequestController(qsTileHost, commandQueue, commandRegistry) return TileServiceRequestController( qsTileHost, commandQueue, commandRegistry, TileRequestDialogEventLogger() ) } } } No newline at end of file Loading
packages/SystemUI/res/layout/tile_service_request_dialog.xml +1 −2 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ android:layout_marginBottom="16dp" android:textDirection="locale" android:textAlignment="viewStart" android:textAppearance="@style/TextAppearance.PrivacyDialog" android:lineHeight="20sp" android:textAppearance="@style/TextAppearance.Dialog.Body" /> </LinearLayout>
packages/SystemUI/res/values/styles.xml +0 −10 Original line number Diff line number Diff line Loading @@ -660,16 +660,6 @@ <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> </style> <!-- TileService request dialog --> <style name="TileRequestDialog" parent="Theme.SystemUI.QuickSettings.Dialog"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@drawable/qs_dialog_bg</item> <item name="android:windowIsFloating">true</item> <item name="android:backgroundDimEnabled">true</item> <item name="android:windowCloseOnTouchOutside">true</item> <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> </style> <!-- USB Contaminant dialog --> <style name ="USBContaminant" /> Loading
packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt +2 −20 Original line number Diff line number Diff line Loading @@ -18,11 +18,8 @@ package com.android.systemui.qs.external import android.content.Context import android.graphics.drawable.Icon import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.WindowInsets import android.widget.TextView import com.android.systemui.R import com.android.systemui.plugins.qs.QSTile Loading @@ -38,25 +35,12 @@ import com.android.systemui.statusbar.phone.SystemUIDialog */ class TileRequestDialog( context: Context ) : SystemUIDialog(context, R.style.TileRequestDialog) { ) : SystemUIDialog(context) { companion object { internal val CONTENT_ID = R.id.content } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) window?.apply { attributes.fitInsetsTypes = attributes.fitInsetsTypes or WindowInsets.Type.statusBars() attributes.receiveInsetsIgnoringZOrder = true setLayout( context.resources .getDimensionPixelSize(R.dimen.qs_tile_service_request_dialog_width), WRAP_CONTENT ) } } /** * Set the data of the tile to add, to show the user. */ Loading @@ -76,9 +60,7 @@ class TileRequestDialog( context.resources.getDimensionPixelSize(R.dimen.qs_quick_tile_size) ) } val spacing = context.resources.getDimensionPixelSize( R.dimen.qs_tile_service_request_content_space ) val spacing = 0 setView(ll, spacing, spacing, spacing, spacing / 2) } Loading
packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialogEventLogger.kt 0 → 100644 +116 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.systemui.qs.external import android.app.StatusBarManager import androidx.annotation.VisibleForTesting import com.android.internal.logging.InstanceId import com.android.internal.logging.InstanceIdSequence import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger import com.android.internal.logging.UiEventLoggerImpl class TileRequestDialogEventLogger @VisibleForTesting constructor( private val uiEventLogger: UiEventLogger, private val instanceIdSequence: InstanceIdSequence ) { companion object { const val MAX_INSTANCE_ID = 1 shl 20 } constructor() : this(UiEventLoggerImpl(), InstanceIdSequence(MAX_INSTANCE_ID)) /** * Obtain a new [InstanceId] to log a session for a dialog request. */ fun newInstanceId(): InstanceId = instanceIdSequence.newInstanceId() /** * Log that the dialog has been shown to the user for a tile in the given [packageName]. This * call should use a new [instanceId]. */ fun logDialogShown(packageName: String, instanceId: InstanceId) { uiEventLogger.logWithInstanceId( TileRequestDialogEvent.TILE_REQUEST_DIALOG_SHOWN, /* uid */ 0, packageName, instanceId ) } /** * Log the user response to the dialog being shown. Must follow a call to [logDialogShown] that * used the same [packageName] and [instanceId]. Only the following responses are valid: * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_DIALOG_DISMISSED] * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED] * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED] */ fun logUserResponse( @StatusBarManager.RequestResult response: Int, packageName: String, instanceId: InstanceId ) { val event = when (response) { StatusBarManager.TILE_ADD_REQUEST_RESULT_DIALOG_DISMISSED -> { TileRequestDialogEvent.TILE_REQUEST_DIALOG_DISMISSED } StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED -> { TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_NOT_ADDED } StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED -> { TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_ADDED } else -> { throw IllegalArgumentException("User response not valid: $response") } } uiEventLogger.logWithInstanceId(event, /* uid */ 0, packageName, instanceId) } /** * Log that the dialog will not be shown because the tile was already part of the active set. * Corresponds to a response of [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ALREADY_ADDED]. */ fun logTileAlreadyAdded(packageName: String, instanceId: InstanceId) { uiEventLogger.logWithInstanceId( TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_ALREADY_ADDED, /* uid */ 0, packageName, instanceId ) } } enum class TileRequestDialogEvent(private val _id: Int) : UiEventLogger.UiEventEnum { @UiEvent(doc = "Tile request dialog not shown because tile is already added.") TILE_REQUEST_DIALOG_TILE_ALREADY_ADDED(917), @UiEvent(doc = "Tile request dialog shown to user.") TILE_REQUEST_DIALOG_SHOWN(918), @UiEvent(doc = "User dismisses dialog without choosing an option.") TILE_REQUEST_DIALOG_DISMISSED(919), @UiEvent(doc = "User accepts adding tile from dialog.") TILE_REQUEST_DIALOG_TILE_ADDED(920), @UiEvent(doc = "User denies adding tile from dialog.") TILE_REQUEST_DIALOG_TILE_NOT_ADDED(921); override fun getId() = _id } No newline at end of file
packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt +14 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ class TileServiceRequestController constructor( private val qsTileHost: QSTileHost, private val commandQueue: CommandQueue, private val commandRegistry: CommandRegistry, private val eventLogger: TileRequestDialogEventLogger, private val dialogCreator: () -> TileRequestDialog = { TileRequestDialog(qsTileHost.context) } ) { Loading Loading @@ -97,25 +98,31 @@ class TileServiceRequestController constructor( icon: Icon?, callback: Consumer<Int> ) { val instanceId = eventLogger.newInstanceId() val packageName = componentName.packageName if (isTileAlreadyAdded(componentName)) { callback.accept(TILE_ALREADY_ADDED) eventLogger.logTileAlreadyAdded(packageName, instanceId) return } val dialogResponse = Consumer<Int> { response -> if (response == ADD_TILE) { addTile(componentName) } dialogCanceller = null eventLogger.logUserResponse(response, packageName, instanceId) callback.accept(response) } val tileData = TileRequestDialog.TileData(appName, label, icon) createDialog(tileData, dialogResponse).also { dialog -> dialogCanceller = { if (componentName.packageName == it) { if (packageName == it) { dialog.cancel() } dialogCanceller = null } }.show() eventLogger.logDialogShown(packageName, instanceId) } private fun createDialog( Loading Loading @@ -168,7 +175,12 @@ class TileServiceRequestController constructor( private val commandRegistry: CommandRegistry ) { fun create(qsTileHost: QSTileHost): TileServiceRequestController { return TileServiceRequestController(qsTileHost, commandQueue, commandRegistry) return TileServiceRequestController( qsTileHost, commandQueue, commandRegistry, TileRequestDialogEventLogger() ) } } } No newline at end of file