Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 241e47ec authored by David Liu's avatar David Liu
Browse files

Log external api metrics usage

- log get preference api usage
- log set preference api usage
- log get preference metadata usage

Bug: 372980186
Test: atest
Flag: EXEMPT metrics logging only
Change-Id: I3320133647cc29c0c2cad0b708178537e6ba7577
parent ac7cf446
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ android_library {
        "androidx.annotation_annotation",
        "androidx.fragment_fragment",
        "androidx.preference_preference",
        "statslog-settingslib",
    ],
    kotlincflags: ["-Xjvm-default=all"],
}
@@ -35,3 +36,18 @@ java_library {
    sdk_version: "core_current",
    static_libs: ["libprotobuf-java-lite"],
}

genrule {
    name: "statslog-settingslib-java-gen",
    tools: ["stats-log-api-gen"],
    cmd: "$(location stats-log-api-gen) --java $(out) --module settings" +
        " --javaPackage com.android.settingslib.graph.instrumentation --javaClass SettingslibStatsLog",
    out: ["com/android/settingslib/graph/instrumentation/SettingslibStatsLog.java"],
}

java_library {
    name: "statslog-settingslib",
    srcs: [
        ":statslog-settingslib-java-gen",
    ],
}
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.settingslib.graph

import com.android.settingslib.graph.instrumentation.SettingslibStatsLog

interface ExtApiMetricsLogger {
    fun logReadPreference(caller: String?, preferenceCoordinate: PreferenceCoordinate, result: Int)
    fun logWritePreference(caller: String?, preferenceCoordinate: PreferenceCoordinate, result: Int)
    fun logGetPreferenceMetadata(caller: String?, result: Int)
}

object MetricsLogger : ExtApiMetricsLogger {
    override fun logReadPreference(caller: String?, preferenceCoordinate: PreferenceCoordinate, result: Int) {
        if (caller == null) return
        SettingslibStatsLog.write(
            SettingslibStatsLog.SETTINGS_EXTAPI_REPORTED,
            caller,
            preferenceCoordinate.loggingId(),
            SettingslibStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_READ,
            result,
            0,
        )
    }

    override fun logWritePreference(caller: String?, preferenceCoordinate: PreferenceCoordinate, result: Int) {
        if (caller == null) return
        SettingslibStatsLog.write(
            SettingslibStatsLog.SETTINGS_EXTAPI_REPORTED,
            caller,
            preferenceCoordinate.loggingId(),
            SettingslibStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_WRITE,
            result,
            0,
        )
    }

    override fun logGetPreferenceMetadata(caller: String?, result: Int) {
        if (caller == null) return
        SettingslibStatsLog.write(
            SettingslibStatsLog.SETTINGS_EXTAPI_REPORTED,
            caller,
            null,
            SettingslibStatsLog.SETTINGS_EXT_API_REPORTED__TYPE__ACTION_GET_METADATA,
            result,
            0,
        )
    }
}

fun PreferenceCoordinate.loggingId() = "$screenKey/$key"
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settingslib.graph

import android.app.Application
import android.os.Bundle
import com.android.settingslib.graph.instrumentation.SettingslibStatsLog
import com.android.settingslib.graph.proto.PreferenceGraphProto
import com.android.settingslib.ipc.ApiHandler
import com.android.settingslib.ipc.MessageCodec
@@ -42,6 +43,10 @@ abstract class GetPreferenceGraphApiHandler(
        callingUid: Int,
        request: GetPreferenceGraphRequest,
    ): PreferenceGraphProto {
        MetricsLogger.logGetPreferenceMetadata(
            application.packageManager.getNameForUid(callingUid),
            SettingslibStatsLog.SETTINGS_EXT_API_REPORTED__RESULT__RESULT_OK
        )
        val builder = PreferenceGraphBuilder.of(application, callingPid, callingUid, request)
        if (request.screenKeys.isEmpty()) {
            for (key in PreferenceScreenRegistry.preferenceScreens.keys) {
+26 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settingslib.graph

import android.app.Application
import androidx.annotation.IntDef
import com.android.settingslib.graph.instrumentation.SettingslibStatsLog
import com.android.settingslib.graph.proto.PreferenceProto
import com.android.settingslib.ipc.ApiDescriptor
import com.android.settingslib.ipc.ApiHandler
@@ -97,6 +98,7 @@ class PreferenceGetterApiHandler(
        val errors = mutableMapOf<PreferenceCoordinate, Int>()
        val preferences = mutableMapOf<PreferenceCoordinate, PreferenceProto>()
        val flags = request.flags
        val callerPackage = application.packageManager.getNameForUid(callingUid)
        for ((screenKey, coordinates) in request.preferences.groupBy { it.screenKey }) {
            val screenMetadata = PreferenceScreenRegistry[screenKey]
            if (screenMetadata == null) {
@@ -116,6 +118,12 @@ class PreferenceGetterApiHandler(
                val node = nodes[coordinate.key]
                if (node == null) {
                    errors[coordinate] = PreferenceGetterErrorCode.NOT_FOUND
                    MetricsLogger.logReadPreference(
                        callerPackage,
                        coordinate,
                        SettingslibStatsLog
                            .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNAVAILABLE,
                    )
                    continue
                }
                val metadata = node.metadata
@@ -131,11 +139,29 @@ class PreferenceGetterApiHandler(
                        )
                    if (flags == PreferenceGetterFlags.VALUE && !preferenceProto.hasValue()) {
                        errors[coordinate] = PreferenceGetterErrorCode.DISALLOW
                        MetricsLogger.logReadPreference(
                            callerPackage,
                            coordinate,
                            SettingslibStatsLog
                                .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_DISALLOW,
                        )
                    } else {
                        preferences[coordinate] = preferenceProto
                        MetricsLogger.logReadPreference(
                            callerPackage,
                            coordinate,
                            SettingslibStatsLog
                                .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_OK,
                        )
                    }
                } catch (e: Exception) {
                    errors[coordinate] = PreferenceGetterErrorCode.INTERNAL_ERROR
                    MetricsLogger.logReadPreference(
                        callerPackage,
                        coordinate,
                        SettingslibStatsLog
                            .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_INTERNAL_ERROR,
                    )
                }
            }
        }
+36 −5
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.os.Bundle
import androidx.annotation.IntDef
import com.android.settingslib.graph.instrumentation.SettingslibStatsLog
import com.android.settingslib.graph.proto.PreferenceValueProto
import com.android.settingslib.ipc.ApiDescriptor
import com.android.settingslib.ipc.ApiHandler
@@ -115,15 +116,45 @@ class PreferenceSetterApiHandler(
        val screenMetadata =
            PreferenceScreenRegistry[request.screenKey] ?: return PreferenceSetterResult.UNSUPPORTED
        val key = request.key
        val metadata =
            screenMetadata.getPreferenceHierarchy(application).find(key)
                ?: return PreferenceSetterResult.UNSUPPORTED
        if (metadata !is PersistentPreference<*>) return PreferenceSetterResult.UNSUPPORTED
        if (!metadata.isEnabled(application)) return PreferenceSetterResult.DISABLED
        val callerPackage = application.packageManager.getNameForUid(callingUid)
        val preferenceCoordinate = with(request) {
            PreferenceCoordinate(screenKey = screenKey, key = key)
        }
        val metadata = screenMetadata.getPreferenceHierarchy(application).find(key)
        if (metadata == null || metadata !is PersistentPreference<*>) {
            MetricsLogger.logWritePreference(
                callerPackage,
                preferenceCoordinate,
                SettingslibStatsLog
                    .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNSUPPORTED,
            )
            return PreferenceSetterResult.UNSUPPORTED
        }
        if (!metadata.isEnabled(application)) {
            MetricsLogger.logWritePreference(
                callerPackage,
                preferenceCoordinate,
                SettingslibStatsLog
                    .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_DISABLED,
            )
            return PreferenceSetterResult.DISABLED
        }
        if (metadata is PreferenceRestrictionProvider && metadata.isRestricted(application)) {
            MetricsLogger.logWritePreference(
                callerPackage,
                preferenceCoordinate,
                SettingslibStatsLog
                    .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_RESTRICTED,
            )
            return PreferenceSetterResult.RESTRICTED
        }
        if (metadata is PreferenceAvailabilityProvider && !metadata.isAvailable(application)) {
            MetricsLogger.logWritePreference(
                callerPackage,
                preferenceCoordinate,
                SettingslibStatsLog
                    .SETTINGS_EXT_API_REPORTED__RESULT__RESULT_FAILURE_UNAVAILABLE,
            )
            return PreferenceSetterResult.UNAVAILABLE
        }