1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.intentresolver.logging 18 19 import android.net.Uri 20 import android.util.HashedStringCache 21 import android.util.Log 22 import com.android.internal.logging.InstanceId 23 import javax.inject.Inject 24 25 private const val TAG = "EventLog" 26 private const val LOG = true 27 28 /** A fake EventLog. */ 29 class FakeEventLog @Inject constructor(private val instanceId: InstanceId) : EventLog { 30 31 var chooserActivityShown: ChooserActivityShown? = null 32 var actionSelected: ActionSelected? = null 33 var customActionSelected: CustomActionSelected? = null 34 var actionShareWithPreview: ActionShareWithPreview? = null 35 val shareTargetSelected: MutableList<ShareTargetSelected> = mutableListOf() 36 lognull37 private fun log(message: () -> Any?) { 38 if (LOG) { 39 Log.d(TAG, "[%04x] ".format(instanceId.id) + message()) 40 } 41 } 42 logChooserActivityShownnull43 override fun logChooserActivityShown( 44 isWorkProfile: Boolean, 45 targetMimeType: String?, 46 systemCost: Long 47 ) { 48 chooserActivityShown = ChooserActivityShown(isWorkProfile, targetMimeType, systemCost) 49 log { chooserActivityShown } 50 } 51 logShareStartednull52 override fun logShareStarted( 53 packageName: String?, 54 mimeType: String?, 55 appProvidedDirect: Int, 56 appProvidedApp: Int, 57 isWorkprofile: Boolean, 58 previewType: Int, 59 intent: String?, 60 customActionCount: Int, 61 modifyShareActionProvided: Boolean 62 ) { 63 log { 64 ShareStarted( 65 packageName, 66 mimeType, 67 appProvidedDirect, 68 appProvidedApp, 69 isWorkprofile, 70 previewType, 71 intent, 72 customActionCount, 73 modifyShareActionProvided 74 ) 75 } 76 } 77 logCustomActionSelectednull78 override fun logCustomActionSelected(positionPicked: Int) { 79 customActionSelected = CustomActionSelected(positionPicked) 80 log { "logCustomActionSelected(positionPicked=$positionPicked)" } 81 } 82 logShareTargetSelectednull83 override fun logShareTargetSelected( 84 targetType: Int, 85 packageName: String?, 86 positionPicked: Int, 87 directTargetAlsoRanked: Int, 88 numCallerProvided: Int, 89 directTargetHashed: HashedStringCache.HashResult?, 90 isPinned: Boolean, 91 successfullySelected: Boolean, 92 selectionCost: Long 93 ) { 94 shareTargetSelected.add( 95 ShareTargetSelected( 96 targetType, 97 packageName, 98 positionPicked, 99 directTargetAlsoRanked, 100 numCallerProvided, 101 directTargetHashed, 102 isPinned, 103 successfullySelected, 104 selectionCost 105 ) 106 ) 107 log { shareTargetSelected.last() } 108 shareTargetSelected.limitSize(10) 109 } 110 MutableListnull111 private fun MutableList<*>.limitSize(n: Int) { 112 while (size > n) { 113 removeFirst() 114 } 115 } 116 logDirectShareTargetReceivednull117 override fun logDirectShareTargetReceived(category: Int, latency: Int) { 118 log { "logDirectShareTargetReceived(category=$category, latency=$latency)" } 119 } 120 logActionShareWithPreviewnull121 override fun logActionShareWithPreview(previewType: Int) { 122 actionShareWithPreview = ActionShareWithPreview(previewType) 123 log { actionShareWithPreview } 124 } 125 logActionSelectednull126 override fun logActionSelected(targetType: Int) { 127 actionSelected = ActionSelected(targetType) 128 log { actionSelected } 129 } 130 logContentPreviewWarningnull131 override fun logContentPreviewWarning(uri: Uri?) { 132 log { "logContentPreviewWarning(uri=$uri)" } 133 } 134 logSharesheetTriggerednull135 override fun logSharesheetTriggered() { 136 log { "logSharesheetTriggered()" } 137 } 138 logSharesheetAppLoadCompletenull139 override fun logSharesheetAppLoadComplete() { 140 log { "logSharesheetAppLoadComplete()" } 141 } 142 logSharesheetDirectLoadCompletenull143 override fun logSharesheetDirectLoadComplete() { 144 log { "logSharesheetAppLoadComplete()" } 145 } 146 logSharesheetDirectLoadTimeoutnull147 override fun logSharesheetDirectLoadTimeout() { 148 log { "logSharesheetDirectLoadTimeout()" } 149 } 150 logSharesheetProfileChangednull151 override fun logSharesheetProfileChanged() { 152 log { "logSharesheetProfileChanged()" } 153 } 154 logSharesheetExpansionChangednull155 override fun logSharesheetExpansionChanged(isCollapsed: Boolean) { 156 log { "logSharesheetExpansionChanged(isCollapsed=$isCollapsed)" } 157 } 158 logSharesheetAppShareRankingTimeoutnull159 override fun logSharesheetAppShareRankingTimeout() { 160 log { "logSharesheetAppShareRankingTimeout()" } 161 } 162 logSharesheetEmptyDirectShareRownull163 override fun logSharesheetEmptyDirectShareRow() { 164 log { "logSharesheetEmptyDirectShareRow()" } 165 } 166 167 data class ActionSelected(val targetType: Int) 168 data class CustomActionSelected(val positionPicked: Int) 169 data class ActionShareWithPreview(val previewType: Int) 170 data class ChooserActivityShown( 171 val isWorkProfile: Boolean, 172 val targetMimeType: String?, 173 val systemCost: Long 174 ) 175 data class ShareStarted( 176 val packageName: String?, 177 val mimeType: String?, 178 val appProvidedDirect: Int, 179 val appProvidedApp: Int, 180 val isWorkprofile: Boolean, 181 val previewType: Int, 182 val intent: String?, 183 val customActionCount: Int, 184 val modifyShareActionProvided: Boolean 185 ) 186 data class ShareTargetSelected( 187 val targetType: Int, 188 val packageName: String?, 189 val positionPicked: Int, 190 val directTargetAlsoRanked: Int, 191 val numCallerProvided: Int, 192 val directTargetHashed: HashedStringCache.HashResult?, 193 val pinned: Boolean, 194 val successfullySelected: Boolean, 195 val selectionCost: Long 196 ) 197 } 198