• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.server.appfunctions;
18 
19 import static com.android.server.appfunctions.AppFunctionExecutors.LOGGING_THREAD_EXECUTOR;
20 
21 import android.annotation.NonNull;
22 import android.app.appfunctions.ExecuteAppFunctionAidlRequest;
23 import android.app.appfunctions.ExecuteAppFunctionResponse;
24 import android.content.Context;
25 import android.content.pm.PackageManager;
26 import android.os.SystemClock;
27 import android.util.Slog;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 
31 import java.util.Objects;
32 import java.util.concurrent.Executor;
33 
34 /** Wraps AppFunctionsStatsLog. */
35 public class AppFunctionsLoggerWrapper {
36     private static final String TAG = AppFunctionsLoggerWrapper.class.getSimpleName();
37 
38     @VisibleForTesting static final int SUCCESS_RESPONSE_CODE = -1;
39 
40     private final PackageManager mPackageManager;
41     private final Executor mLoggingExecutor;
42     private final AppFunctionsLoggerClock mLoggerClock;
43 
AppFunctionsLoggerWrapper(@onNull Context context)44     AppFunctionsLoggerWrapper(@NonNull Context context) {
45         this(context.getPackageManager(), LOGGING_THREAD_EXECUTOR, SystemClock::elapsedRealtime);
46     }
47 
48     @VisibleForTesting
AppFunctionsLoggerWrapper( @onNull PackageManager packageManager, @NonNull Executor executor, AppFunctionsLoggerClock loggerClock)49     AppFunctionsLoggerWrapper(
50             @NonNull PackageManager packageManager,
51             @NonNull Executor executor,
52             AppFunctionsLoggerClock loggerClock) {
53         mLoggingExecutor = Objects.requireNonNull(executor);
54         mPackageManager = Objects.requireNonNull(packageManager);
55         mLoggerClock = loggerClock;
56     }
57 
logAppFunctionSuccess( ExecuteAppFunctionAidlRequest request, ExecuteAppFunctionResponse response, int callingUid, long executionStartTimeMillis)58     void logAppFunctionSuccess(
59             ExecuteAppFunctionAidlRequest request,
60             ExecuteAppFunctionResponse response,
61             int callingUid,
62             long executionStartTimeMillis) {
63         logAppFunctionsRequestReported(
64                 request,
65                 SUCCESS_RESPONSE_CODE,
66                 response.getResponseDataSize(),
67                 callingUid,
68                 executionStartTimeMillis);
69     }
70 
logAppFunctionError( ExecuteAppFunctionAidlRequest request, int errorCode, int callingUid, long executionStartTimeMillis)71     void logAppFunctionError(
72             ExecuteAppFunctionAidlRequest request,
73             int errorCode,
74             int callingUid,
75             long executionStartTimeMillis) {
76         logAppFunctionsRequestReported(
77                 request,
78                 errorCode,
79                 /* responseSizeBytes= */ 0,
80                 callingUid,
81                 executionStartTimeMillis);
82     }
83 
logAppFunctionsRequestReported( ExecuteAppFunctionAidlRequest request, int errorCode, int responseSizeBytes, int callingUid, long executionStartTimeMillis)84     private void logAppFunctionsRequestReported(
85             ExecuteAppFunctionAidlRequest request,
86             int errorCode,
87             int responseSizeBytes,
88             int callingUid,
89             long executionStartTimeMillis) {
90         final long e2eRequestLatencyMillis =
91                 mLoggerClock.getCurrentTimeMillis() - request.getRequestTime();
92         final long requestOverheadMillis =
93                 executionStartTimeMillis > 0
94                         ? (executionStartTimeMillis - request.getRequestTime())
95                         : e2eRequestLatencyMillis;
96         mLoggingExecutor.execute(
97                 () ->
98                         AppFunctionsStatsLog.write(
99                                 AppFunctionsStatsLog.APP_FUNCTIONS_REQUEST_REPORTED,
100                                 /* callerPackageUid= */ callingUid,
101                                 /* targetPackageUid= */ getPackageUid(
102                                         request.getClientRequest().getTargetPackageName()),
103                                 /* errorCode= */ errorCode,
104                                 /* requestSizeBytes= */ request.getClientRequest()
105                                         .getRequestDataSize(),
106                                 /* responseSizeBytes= */ responseSizeBytes,
107                                 /* requestDurationMs= */ e2eRequestLatencyMillis,
108                                 /* requestOverheadMs= */ requestOverheadMillis));
109     }
110 
getPackageUid(String packageName)111     private int getPackageUid(String packageName) {
112         try {
113             return mPackageManager.getPackageUid(packageName, 0);
114         } catch (PackageManager.NameNotFoundException e) {
115             Slog.e(TAG, "Package uid not found for " + packageName);
116         }
117         return 0;
118     }
119 
120     /** Wraps a custom clock for easier testing. */
121     interface AppFunctionsLoggerClock {
getCurrentTimeMillis()122         long getCurrentTimeMillis();
123     }
124 }
125