1 /*
2 * Copyright (C) 2025 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.settings.metrics
18
19 import android.app.settings.SettingsEnums
20 import android.content.Context
21 import com.android.settings.core.instrumentation.SettingsStatsLog
22 import com.android.settingslib.graph.PreferenceGetterErrorCode
23 import com.android.settingslib.graph.PreferenceSetterResult
24 import com.android.settingslib.metadata.PreferenceCoordinate
25 import com.android.settingslib.metadata.PreferenceMetadata
26 import com.android.settingslib.metadata.PreferenceRemoteOpMetricsLogger
27 import com.android.settingslib.metadata.PreferenceScreenMetadata
28
29 /** Metrics logger for settings remote operations. */
30 class SettingsRemoteOpMetricsLogger : PreferenceRemoteOpMetricsLogger {
31
logGetterApinull32 override fun logGetterApi(
33 context: Context,
34 callingUid: Int,
35 preferenceCoordinate: PreferenceCoordinate,
36 screen: PreferenceScreenMetadata?,
37 preference: PreferenceMetadata?,
38 errorCode: Int,
39 latencyMs: Long,
40 ) =
41 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_READ.log(
42 context,
43 callingUid,
44 preferenceCoordinate,
45 preference,
46 errorCode,
47 latencyMs,
48 Int::convertGetterErrorCode,
49 )
50
51 override fun logSetterApi(
52 context: Context,
53 callingUid: Int,
54 preferenceCoordinate: PreferenceCoordinate,
55 screen: PreferenceScreenMetadata?,
56 preference: PreferenceMetadata?,
57 errorCode: Int,
58 latencyMs: Long,
59 ) =
60 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_WRITE.log(
61 context,
62 callingUid,
63 preferenceCoordinate,
64 preference,
65 errorCode,
66 latencyMs,
67 Int::convertSetterErrorCode,
68 )
69
70 private fun Int.log(
71 context: Context,
72 callingUid: Int,
73 preferenceCoordinate: PreferenceCoordinate,
74 preference: PreferenceMetadata?,
75 errorCode: Int,
76 latencyMs: Long,
77 errorCodeToMetricsResult: (Int) -> Int,
78 ) {
79 if (preference is PreferenceActionMetricsProvider) {
80 SettingsStatsLog.write(
81 SettingsStatsLog.SETTINGS_EXTAPI_REPORTED,
82 context.packageNameOfUid(callingUid),
83 "",
84 this,
85 errorCodeToMetricsResult(errorCode),
86 latencyMs,
87 preference.preferenceActionMetrics,
88 )
89 } else {
90 SettingsStatsLog.write(
91 SettingsStatsLog.SETTINGS_EXTAPI_REPORTED,
92 context.packageNameOfUid(callingUid),
93 preferenceCoordinate.settingsId,
94 this,
95 errorCodeToMetricsResult(errorCode),
96 latencyMs,
97 SettingsEnums.ACTION_UNKNOWN,
98 )
99 }
100 }
101
logGraphApinull102 override fun logGraphApi(context: Context, callingUid: Int, success: Boolean, latencyMs: Long) {
103 val result =
104 if (success) {
105 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_OK
106 } else {
107 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INTERNAL_ERROR
108 }
109 SettingsStatsLog.write(
110 SettingsStatsLog.SETTINGS_EXTAPI_REPORTED,
111 context.packageNameOfUid(callingUid),
112 "",
113 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_GET_METADATA,
114 result,
115 latencyMs,
116 SettingsEnums.ACTION_UNKNOWN,
117 )
118 }
119 }
120
Contextnull121 private fun Context.packageNameOfUid(uid: Int) = packageManager.getNameForUid(uid) ?: ""
122
123 private val PreferenceCoordinate.settingsId: String
124 get() = "$screenKey/$key"
125
126 private fun Int.convertGetterErrorCode() =
127 when (this) {
128 PreferenceGetterErrorCode.OK ->
129 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_OK
130 PreferenceGetterErrorCode.NOT_FOUND ->
131 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNSUPPORTED
132 PreferenceGetterErrorCode.DISALLOW ->
133 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_DISALLOW
134 else -> SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INTERNAL_ERROR
135 }
136
convertSetterErrorCodenull137 private fun Int.convertSetterErrorCode() =
138 when (this) {
139 PreferenceSetterResult.OK -> SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_OK
140 PreferenceSetterResult.UNSUPPORTED ->
141 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNSUPPORTED
142 PreferenceSetterResult.DISABLED ->
143 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_DISABLED
144 PreferenceSetterResult.RESTRICTED ->
145 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_RESTRICTED
146 PreferenceSetterResult.UNAVAILABLE ->
147 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNAVAILABLE
148 PreferenceSetterResult.REQUIRE_APP_PERMISSION ->
149 SettingsStatsLog
150 .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_REQUIRE_APP_PERMISSION
151 PreferenceSetterResult.REQUIRE_USER_AGREEMENT ->
152 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_REQUIRE_USER_CONSENT
153 PreferenceSetterResult.DISALLOW ->
154 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_DISALLOW
155 PreferenceSetterResult.INVALID_REQUEST ->
156 SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INVALID_REQUEST
157 else -> SettingsStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INTERNAL_ERROR
158 }
159