• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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.server.ranging.metrics;
18 
19 import static android.ranging.RangingConfig.RANGING_SESSION_RAW;
20 
21 import android.content.AttributionSource;
22 import android.ranging.RangingConfig;
23 import android.ranging.RangingPreference;
24 import android.ranging.SessionHandle;
25 
26 import com.android.server.ranging.RangingInjector;
27 import com.android.server.ranging.RangingTechnology;
28 import com.android.server.ranging.RangingUtils.InternalReason;
29 import com.android.server.ranging.RangingUtils.StateMachine;
30 
31 public class SessionMetricsLogger {
32     private final SessionHandle mSessionHandle;
33     private final @RangingPreference.DeviceRole int mDeviceRole;
34     private final @RangingConfig.RangingSessionType int mSessionType;
35     private final StateMachine<State> mStateMachine;
36     private final AttributionSource mAttributionSource;
37     private final RangingInjector mInjector;
38 
39     private long mLastStateChangeTimestampMs;
40 
startLogging( SessionHandle sessionHandle, @RangingPreference.DeviceRole int deviceRole, @RangingConfig.RangingSessionType int sessionType, AttributionSource attributionSource, RangingInjector injector )41     public static SessionMetricsLogger startLogging(
42             SessionHandle sessionHandle,
43             @RangingPreference.DeviceRole int deviceRole,
44             @RangingConfig.RangingSessionType int sessionType,
45             AttributionSource attributionSource,
46             RangingInjector injector
47     ) {
48         return new SessionMetricsLogger(sessionHandle, deviceRole, sessionType, attributionSource,
49                 injector);
50     }
51 
SessionMetricsLogger( SessionHandle sessionHandle, @RangingPreference.DeviceRole int deviceRole, @RangingConfig.RangingSessionType int sessionType, AttributionSource attributionSource, RangingInjector injector )52     private SessionMetricsLogger(
53             SessionHandle sessionHandle,
54             @RangingPreference.DeviceRole int deviceRole,
55             @RangingConfig.RangingSessionType int sessionType,
56             AttributionSource attributionSource,
57             RangingInjector injector
58     ) {
59         mSessionHandle = sessionHandle;
60         mDeviceRole = deviceRole;
61         mSessionType = sessionType;
62         mStateMachine = new StateMachine<>(
63                 sessionType == RANGING_SESSION_RAW
64                         ? State.STARTING
65                         : State.OOB);
66         mLastStateChangeTimestampMs = System.currentTimeMillis();
67         mAttributionSource = attributionSource;
68         mInjector = injector;
69     }
70 
logSessionConfigured(int numPeers)71     public synchronized void logSessionConfigured(int numPeers) {
72         RangingStatsLog.write(
73                 RangingStatsLog.RANGING_SESSION_CONFIGURED,
74                 mSessionHandle.hashCode(),
75                 mStateMachine.getState() == State.OOB
76                         ? System.currentTimeMillis() - mLastStateChangeTimestampMs
77                         : 0,
78                 coerceUnknownEnumValueToZero(mSessionType, 2),
79                 coerceUnknownEnumValueToZero(mDeviceRole, 2),
80                 numPeers,
81                 mAttributionSource.getUid());
82         mLastStateChangeTimestampMs = System.currentTimeMillis();
83         mStateMachine.setState(State.STARTING);
84     }
85 
logSessionStarted()86     public synchronized void logSessionStarted() {
87         RangingStatsLog.write(
88                 RangingStatsLog.RANGING_SESSION_STARTED,
89                 mSessionHandle.hashCode(),
90                 mAttributionSource.getUid(),
91                 System.currentTimeMillis() - mLastStateChangeTimestampMs,
92                 mInjector.isPrivilegedApp(
93                         mAttributionSource.getUid(),
94                         mAttributionSource.getPackageName()));
95         mLastStateChangeTimestampMs = System.currentTimeMillis();
96         mStateMachine.setState(State.RANGING);
97     }
98 
logTechnologyStarted(RangingTechnology technology, int numPeers)99     public synchronized void logTechnologyStarted(RangingTechnology technology, int numPeers) {
100         RangingStatsLog.write(
101                 RangingStatsLog.RANGING_TECHNOLOGY_STARTED,
102                 mSessionHandle.hashCode(),
103                 coerceUnknownEnumValueToZero(
104                         technology.getValue(), RangingTechnology.TECHNOLOGIES.size()),
105                 numPeers,
106                 mAttributionSource.getUid());
107     }
108 
logTechnologyStopped( RangingTechnology technology, int numPeers, @InternalReason int reason )109     public synchronized void logTechnologyStopped(
110             RangingTechnology technology, int numPeers, @InternalReason int reason
111     ) {
112         RangingStatsLog.write(
113                 RangingStatsLog.RANGING_TECHNOLOGY_STOPPED,
114                 mSessionHandle.hashCode(),
115                 coerceUnknownEnumValueToZero(
116                         technology.getValue(), RangingTechnology.TECHNOLOGIES.size()),
117                 coerceUnknownEnumValueToZero(
118                         mStateMachine.getState().toInt(), State.values().length),
119                 reason,
120                 numPeers,
121                 mAttributionSource.getUid());
122     }
123 
logSessionClosed(@nternalReason int reason)124     public synchronized void logSessionClosed(@InternalReason int reason) {
125         RangingStatsLog.write(
126                 RangingStatsLog.RANGING_SESSION_CLOSED,
127                 mSessionHandle.hashCode(),
128                 coerceUnknownEnumValueToZero(
129                         mStateMachine.getState().toInt(), State.values().length),
130                 System.currentTimeMillis() - mLastStateChangeTimestampMs,
131                 reason,
132                 mAttributionSource.getUid());
133         mLastStateChangeTimestampMs = System.currentTimeMillis();
134     }
135 
coerceUnknownEnumValueToZero(int enumValue, int numEnumValues)136     private int coerceUnknownEnumValueToZero(int enumValue, int numEnumValues) {
137         if (enumValue >= numEnumValues) {
138             return 0;
139         } else {
140             return enumValue + 1;
141         }
142     }
143 
144     private enum State {
145         OOB(0),
146         STARTING(1),
147         RANGING(2);
148 
149         private final int mValue;
150 
State(int value)151         State(int value) {
152             mValue = value;
153         }
154 
toInt()155         public final int toInt() {
156             return mValue;
157         }
158     }
159 }
160