1 /*
2  * Copyright (C) 2022 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 android.app.sdksandbox;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import com.android.internal.annotations.VisibleForTesting;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.util.Objects;
29 
30 /**
31  * To be used to send sandbox latency information via callback
32  *
33  * @hide
34  */
35 public final class SandboxLatencyInfo implements Parcelable {
36     @IntDef(
37             prefix = "METHOD_",
38             value = {
39                 METHOD_UNSPECIFIED,
40                 METHOD_LOAD_SDK,
41                 METHOD_REQUEST_SURFACE_PACKAGE,
42                 METHOD_GET_SANDBOXED_SDKS,
43                 METHOD_SYNC_DATA_FROM_CLIENT,
44                 METHOD_UNLOAD_SDK,
45                 METHOD_ADD_SDK_SANDBOX_LIFECYCLE_CALLBACK,
46                 METHOD_REMOVE_SDK_SANDBOX_LIFECYCLE_CALLBACK,
47                 METHOD_GET_SANDBOXED_SDKS_VIA_CONTROLLER,
48                 METHOD_REGISTER_APP_OWNED_SDK_SANDBOX_INTERFACE,
49                 METHOD_UNREGISTER_APP_OWNED_SDK_SANDBOX_INTERFACE,
50                 METHOD_GET_APP_OWNED_SDK_SANDBOX_INTERFACES,
51                 METHOD_LOAD_SDK_VIA_CONTROLLER,
52             })
53     @Retention(RetentionPolicy.SOURCE)
54     public @interface Method {}
55 
56     public static final int METHOD_UNSPECIFIED = 0;
57     public static final int METHOD_LOAD_SDK = 1;
58     public static final int METHOD_REQUEST_SURFACE_PACKAGE = 3;
59     public static final int METHOD_GET_SANDBOXED_SDKS = 5;
60     public static final int METHOD_SYNC_DATA_FROM_CLIENT = 6;
61     public static final int METHOD_UNLOAD_SDK = 7;
62     public static final int METHOD_ADD_SDK_SANDBOX_LIFECYCLE_CALLBACK = 8;
63     public static final int METHOD_REMOVE_SDK_SANDBOX_LIFECYCLE_CALLBACK = 9;
64     public static final int METHOD_GET_SANDBOXED_SDKS_VIA_CONTROLLER = 10;
65     public static final int METHOD_REGISTER_APP_OWNED_SDK_SANDBOX_INTERFACE = 11;
66     public static final int METHOD_UNREGISTER_APP_OWNED_SDK_SANDBOX_INTERFACE = 12;
67     public static final int METHOD_GET_APP_OWNED_SDK_SANDBOX_INTERFACES = 13;
68     public static final int METHOD_LOAD_SDK_VIA_CONTROLLER = 14;
69 
70     @IntDef(
71             prefix = "SANDBOX_STATUS_",
72             value = {
73                 SANDBOX_STATUS_SUCCESS,
74                 SANDBOX_STATUS_FAILED_AT_APP_TO_SYSTEM_SERVER,
75                 SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_APP_TO_SANDBOX,
76                 SANDBOX_STATUS_FAILED_AT_LOAD_SANDBOX,
77                 SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_TO_SANDBOX,
78                 SANDBOX_STATUS_FAILED_AT_SANDBOX,
79                 SANDBOX_STATUS_FAILED_AT_SDK,
80                 SANDBOX_STATUS_FAILED_AT_SANDBOX_TO_SYSTEM_SERVER,
81                 SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_SANDBOX_TO_APP,
82                 SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_TO_APP,
83             })
84     @Retention(RetentionPolicy.SOURCE)
85     public @interface SandboxStatus {}
86 
87     public static final int SANDBOX_STATUS_SUCCESS = 1;
88     public static final int SANDBOX_STATUS_FAILED_AT_APP_TO_SYSTEM_SERVER = 2;
89     public static final int SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_APP_TO_SANDBOX = 3;
90     public static final int SANDBOX_STATUS_FAILED_AT_LOAD_SANDBOX = 4;
91     public static final int SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_TO_SANDBOX = 5;
92     public static final int SANDBOX_STATUS_FAILED_AT_SANDBOX = 6;
93     public static final int SANDBOX_STATUS_FAILED_AT_SDK = 7;
94     public static final int SANDBOX_STATUS_FAILED_AT_SANDBOX_TO_SYSTEM_SERVER = 8;
95     public static final int SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_SANDBOX_TO_APP = 9;
96     public static final int SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_TO_APP = 10;
97 
98     @IntDef(
99             prefix = "RESULT_CODE_",
100             value = {
101                 RESULT_CODE_UNSPECIFIED,
102                 RESULT_CODE_LOAD_SDK_NOT_FOUND,
103                 RESULT_CODE_LOAD_SDK_ALREADY_LOADED,
104                 RESULT_CODE_LOAD_SDK_SDK_DEFINED_ERROR,
105                 RESULT_CODE_LOAD_SDK_SDK_SANDBOX_DISABLED,
106                 RESULT_CODE_LOAD_SDK_INTERNAL_ERROR,
107                 RESULT_CODE_SDK_SANDBOX_PROCESS_NOT_AVAILABLE
108             })
109     @Retention(RetentionPolicy.SOURCE)
110     public @interface ResultCode {}
111 
112     public static final int RESULT_CODE_UNSPECIFIED = 0;
113     public static final int RESULT_CODE_LOAD_SDK_NOT_FOUND = 1;
114     public static final int RESULT_CODE_LOAD_SDK_ALREADY_LOADED = 2;
115     public static final int RESULT_CODE_LOAD_SDK_SDK_DEFINED_ERROR = 3;
116     public static final int RESULT_CODE_LOAD_SDK_SDK_SANDBOX_DISABLED = 4;
117     public static final int RESULT_CODE_LOAD_SDK_INTERNAL_ERROR = 5;
118     public static final int RESULT_CODE_SDK_SANDBOX_PROCESS_NOT_AVAILABLE = 6;
119 
120     private final @Method int mMethod;
121     private long mTimeAppCalledSystemServer = -1;
122     private long mTimeSystemServerReceivedCallFromApp = -1;
123     private long mTimeLoadSandboxStarted = -1;
124     private long mTimeSandboxLoaded = -1;
125     private long mTimeSystemServerCallFinished = -1;
126     private long mTimeSandboxReceivedCallFromSystemServer = -1;
127     private long mTimeSandboxCalledSdk = -1;
128     private long mTimeSdkCallCompleted = -1;
129     private long mTimeSandboxCalledSystemServer = -1;
130     private long mTimeSystemServerReceivedCallFromSandbox = -1;
131     private long mTimeSystemServerCalledApp = -1;
132     private long mTimeAppReceivedCallFromSystemServer = -1;
133     private @SandboxStatus int mSandboxStatus = SANDBOX_STATUS_SUCCESS;
134     private @ResultCode int mResultCode = RESULT_CODE_UNSPECIFIED;
135 
136     public static final @NonNull Parcelable.Creator<SandboxLatencyInfo> CREATOR =
137             new Parcelable.Creator<SandboxLatencyInfo>() {
138                 public SandboxLatencyInfo createFromParcel(Parcel in) {
139                     return new SandboxLatencyInfo(in);
140                 }
141 
142                 public SandboxLatencyInfo[] newArray(int size) {
143                     return new SandboxLatencyInfo[size];
144                 }
145             };
146 
147     // TODO(b/297352617): add timeAppCalledSystemServer to the constructor.
SandboxLatencyInfo(@ethod int method)148     public SandboxLatencyInfo(@Method int method) {
149         mMethod = method;
150     }
151 
SandboxLatencyInfo()152     public SandboxLatencyInfo() {
153         mMethod = SandboxLatencyInfo.METHOD_UNSPECIFIED;
154     }
155 
SandboxLatencyInfo(Parcel in)156     private SandboxLatencyInfo(Parcel in) {
157         mMethod = in.readInt();
158         mTimeAppCalledSystemServer = in.readLong();
159         mTimeSystemServerReceivedCallFromApp = in.readLong();
160         mTimeLoadSandboxStarted = in.readLong();
161         mTimeSandboxLoaded = in.readLong();
162         mTimeSystemServerCallFinished = in.readLong();
163         mTimeSandboxReceivedCallFromSystemServer = in.readLong();
164         mTimeSandboxCalledSdk = in.readLong();
165         mTimeSdkCallCompleted = in.readLong();
166         mTimeSandboxCalledSystemServer = in.readLong();
167         mTimeSystemServerReceivedCallFromSandbox = in.readLong();
168         mTimeSystemServerCalledApp = in.readLong();
169         mTimeAppReceivedCallFromSystemServer = in.readLong();
170         mSandboxStatus = in.readInt();
171         mResultCode = in.readInt();
172     }
173 
174     @Override
equals(Object object)175     public boolean equals(Object object) {
176         if (this == object) return true;
177         if (!(object instanceof SandboxLatencyInfo)) return false;
178         SandboxLatencyInfo that = (SandboxLatencyInfo) object;
179         return mMethod == that.mMethod
180                 && mTimeAppCalledSystemServer == that.mTimeAppCalledSystemServer
181                 && mTimeSystemServerReceivedCallFromApp == that.mTimeSystemServerReceivedCallFromApp
182                 && mTimeLoadSandboxStarted == that.mTimeLoadSandboxStarted
183                 && mTimeSandboxLoaded == that.mTimeSandboxLoaded
184                 && mTimeSystemServerCallFinished == that.mTimeSystemServerCallFinished
185                 && mTimeSandboxReceivedCallFromSystemServer
186                         == that.mTimeSandboxReceivedCallFromSystemServer
187                 && mTimeSandboxCalledSdk == that.mTimeSandboxCalledSdk
188                 && mTimeSdkCallCompleted == that.mTimeSdkCallCompleted
189                 && mTimeSandboxCalledSystemServer == that.mTimeSandboxCalledSystemServer
190                 && mTimeSystemServerReceivedCallFromSandbox
191                         == that.mTimeSystemServerReceivedCallFromSandbox
192                 && mTimeSystemServerCalledApp == that.mTimeSystemServerCalledApp
193                 && mTimeAppReceivedCallFromSystemServer == that.mTimeAppReceivedCallFromSystemServer
194                 && mSandboxStatus == that.mSandboxStatus
195                 && mResultCode == that.mResultCode;
196     }
197 
198     @Override
hashCode()199     public int hashCode() {
200         return Objects.hash(
201                 mMethod,
202                 mTimeAppCalledSystemServer,
203                 mTimeSystemServerReceivedCallFromApp,
204                 mTimeLoadSandboxStarted,
205                 mTimeSandboxLoaded,
206                 mTimeSystemServerCallFinished,
207                 mTimeSandboxReceivedCallFromSystemServer,
208                 mTimeSandboxCalledSdk,
209                 mTimeSdkCallCompleted,
210                 mTimeSandboxCalledSystemServer,
211                 mTimeSystemServerReceivedCallFromSandbox,
212                 mTimeSystemServerCalledApp,
213                 mTimeAppReceivedCallFromSystemServer,
214                 mSandboxStatus,
215                 mResultCode);
216     }
217 
218     @Override
writeToParcel(@onNull Parcel out, int flags)219     public void writeToParcel(@NonNull Parcel out, int flags) {
220         out.writeInt(mMethod);
221         out.writeLong(mTimeAppCalledSystemServer);
222         out.writeLong(mTimeSystemServerReceivedCallFromApp);
223         out.writeLong(mTimeLoadSandboxStarted);
224         out.writeLong(mTimeSandboxLoaded);
225         out.writeLong(mTimeSystemServerCallFinished);
226         out.writeLong(mTimeSandboxReceivedCallFromSystemServer);
227         out.writeLong(mTimeSandboxCalledSdk);
228         out.writeLong(mTimeSdkCallCompleted);
229         out.writeLong(mTimeSandboxCalledSystemServer);
230         out.writeLong(mTimeSystemServerReceivedCallFromSandbox);
231         out.writeLong(mTimeSystemServerCalledApp);
232         out.writeLong(mTimeAppReceivedCallFromSystemServer);
233         out.writeInt(mSandboxStatus);
234         out.writeInt(mResultCode);
235     }
236 
237     @Override
describeContents()238     public int describeContents() {
239         return 0;
240     }
241 
getMethod()242     public @Method int getMethod() {
243         return mMethod;
244     }
245 
setTimeAppCalledSystemServer(long timeAppCalledSystemServer)246     public void setTimeAppCalledSystemServer(long timeAppCalledSystemServer) {
247         mTimeAppCalledSystemServer = timeAppCalledSystemServer;
248     }
249 
setTimeSystemServerReceivedCallFromApp(long timeSystemServerReceivedCallFromApp)250     public void setTimeSystemServerReceivedCallFromApp(long timeSystemServerReceivedCallFromApp) {
251         mTimeSystemServerReceivedCallFromApp = timeSystemServerReceivedCallFromApp;
252     }
253 
setTimeLoadSandboxStarted(long timeLoadSandboxStarted)254     public void setTimeLoadSandboxStarted(long timeLoadSandboxStarted) {
255         mTimeLoadSandboxStarted = timeLoadSandboxStarted;
256     }
257 
setTimeSandboxLoaded(long timeSandboxLoaded)258     public void setTimeSandboxLoaded(long timeSandboxLoaded) {
259         mTimeSandboxLoaded = timeSandboxLoaded;
260     }
261 
getTimeSystemServerCallFinished()262     public long getTimeSystemServerCallFinished() {
263         return mTimeSystemServerCallFinished;
264     }
265 
setTimeSystemServerCallFinished(long timeSystemServerCallFinished)266     public void setTimeSystemServerCallFinished(long timeSystemServerCallFinished) {
267         mTimeSystemServerCallFinished = timeSystemServerCallFinished;
268     }
269 
setTimeSandboxReceivedCallFromSystemServer( long timeSandboxReceivedCallFromSystemServer)270     public void setTimeSandboxReceivedCallFromSystemServer(
271             long timeSandboxReceivedCallFromSystemServer) {
272         mTimeSandboxReceivedCallFromSystemServer = timeSandboxReceivedCallFromSystemServer;
273     }
274 
setTimeSandboxCalledSdk(long timeSandboxCalledSdk)275     public void setTimeSandboxCalledSdk(long timeSandboxCalledSdk) {
276         mTimeSandboxCalledSdk = timeSandboxCalledSdk;
277     }
278 
setTimeSdkCallCompleted(long timeSdkCallCompleted)279     public void setTimeSdkCallCompleted(long timeSdkCallCompleted) {
280         mTimeSdkCallCompleted = timeSdkCallCompleted;
281     }
282 
getTimeSandboxCalledSystemServer()283     public long getTimeSandboxCalledSystemServer() {
284         return mTimeSandboxCalledSystemServer;
285     }
286 
setTimeSandboxCalledSystemServer(long timeSandboxCalledSystemServer)287     public void setTimeSandboxCalledSystemServer(long timeSandboxCalledSystemServer) {
288         mTimeSandboxCalledSystemServer = timeSandboxCalledSystemServer;
289     }
290 
setTimeSystemServerReceivedCallFromSandbox( long timeSystemServerReceivedCallFromSandbox)291     public void setTimeSystemServerReceivedCallFromSandbox(
292             long timeSystemServerReceivedCallFromSandbox) {
293         mTimeSystemServerReceivedCallFromSandbox = timeSystemServerReceivedCallFromSandbox;
294     }
295 
setTimeSystemServerCalledApp(long timeSystemServerCalledApp)296     public void setTimeSystemServerCalledApp(long timeSystemServerCalledApp) {
297         mTimeSystemServerCalledApp = timeSystemServerCalledApp;
298     }
299 
setTimeAppReceivedCallFromSystemServer(long timeAppReceivedCallFromSystemServer)300     public void setTimeAppReceivedCallFromSystemServer(long timeAppReceivedCallFromSystemServer) {
301         mTimeAppReceivedCallFromSystemServer = timeAppReceivedCallFromSystemServer;
302     }
303 
setSandboxStatus(@andboxStatus int sandboxStatus)304     public void setSandboxStatus(@SandboxStatus int sandboxStatus) {
305         mSandboxStatus = sandboxStatus;
306     }
307 
setResultCode(@esultCode int resultCode)308     public void setResultCode(@ResultCode int resultCode) {
309         mResultCode = resultCode;
310     }
311 
312     /** Returns latency of the IPC call from App call to System Server. */
getAppToSystemServerLatency()313     public int getAppToSystemServerLatency() {
314         return getLatency(mTimeAppCalledSystemServer, mTimeSystemServerReceivedCallFromApp);
315     }
316 
317     /** Returns latency of the System Server stage of the call that was received from App. */
getSystemServerAppToSandboxLatency()318     public int getSystemServerAppToSandboxLatency() {
319         int systemServerAppToSandboxLatency =
320                 getLatency(mTimeSystemServerReceivedCallFromApp, mTimeSystemServerCallFinished);
321         int loadSandboxLatency = getLoadSandboxLatency();
322         return loadSandboxLatency == -1
323                 ? systemServerAppToSandboxLatency
324                 : systemServerAppToSandboxLatency - loadSandboxLatency;
325     }
326 
327     /** Returns latency of the LoadSandbox stage of the call. */
getLoadSandboxLatency()328     public int getLoadSandboxLatency() {
329         return getLatency(mTimeLoadSandboxStarted, mTimeSandboxLoaded);
330     }
331 
332     /** Returns latency of the IPC call from System Server to Sandbox. */
getSystemServerToSandboxLatency()333     public int getSystemServerToSandboxLatency() {
334         return getLatency(mTimeSystemServerCallFinished, mTimeSandboxReceivedCallFromSystemServer);
335     }
336 
337     /** Returns latency of the Sandbox stage of the call. */
getSandboxLatency()338     public int getSandboxLatency() {
339         int sandboxLatency =
340                 getLatency(
341                         mTimeSandboxReceivedCallFromSystemServer, mTimeSandboxCalledSystemServer);
342         int sdkLatency = getSdkLatency();
343         if (sdkLatency != -1) {
344             sandboxLatency -= sdkLatency;
345         }
346         return sandboxLatency;
347     }
348 
349     /** Returns latency of the SDK stage of the call. */
getSdkLatency()350     public int getSdkLatency() {
351         return getLatency(mTimeSandboxCalledSdk, mTimeSdkCallCompleted);
352     }
353 
354     /** Returns latency of the Sandbox call to System Server. */
getSandboxToSystemServerLatency()355     public int getSandboxToSystemServerLatency() {
356         return getLatency(mTimeSandboxCalledSystemServer, mTimeSystemServerReceivedCallFromSandbox);
357     }
358 
359     /** Returns latency of the System Server stage of the call that was received from Sandbox. */
getSystemServerSandboxToAppLatency()360     public int getSystemServerSandboxToAppLatency() {
361         return getLatency(mTimeSystemServerReceivedCallFromSandbox, mTimeSystemServerCalledApp);
362     }
363 
364     /** Returns latency of the IPC call from System Server to App. */
getSystemServerToAppLatency()365     public int getSystemServerToAppLatency() {
366         return getLatency(mTimeSystemServerCalledApp, mTimeAppReceivedCallFromSystemServer);
367     }
368 
369     /**
370      * Returns total latency of the API call. Call finish time is defined depending on the API
371      * called.
372      */
getTotalCallLatency()373     public int getTotalCallLatency() {
374         return getLatency(mTimeAppCalledSystemServer, getTotalCallFinishTime());
375     }
376 
isSuccessfulAtAppToSystemServer()377     public boolean isSuccessfulAtAppToSystemServer() {
378         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_APP_TO_SYSTEM_SERVER;
379     }
380 
isSuccessfulAtSystemServerAppToSandbox()381     public boolean isSuccessfulAtSystemServerAppToSandbox() {
382         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_APP_TO_SANDBOX;
383     }
384 
isSuccessfulAtLoadSandbox()385     public boolean isSuccessfulAtLoadSandbox() {
386         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_LOAD_SANDBOX;
387     }
388 
isSuccessfulAtSystemServerToSandbox()389     public boolean isSuccessfulAtSystemServerToSandbox() {
390         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_TO_SANDBOX;
391     }
392 
isSuccessfulAtSdk()393     public boolean isSuccessfulAtSdk() {
394         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_SDK;
395     }
396 
isSuccessfulAtSandbox()397     public boolean isSuccessfulAtSandbox() {
398         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_SANDBOX;
399     }
400 
isSuccessfulAtSandboxToSystemServer()401     public boolean isSuccessfulAtSandboxToSystemServer() {
402         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_SANDBOX_TO_SYSTEM_SERVER;
403     }
404 
isSuccessfulAtSystemServerSandboxToApp()405     public boolean isSuccessfulAtSystemServerSandboxToApp() {
406         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_SANDBOX_TO_APP;
407     }
408 
isSuccessfulAtSystemServerToApp()409     public boolean isSuccessfulAtSystemServerToApp() {
410         return mSandboxStatus != SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_TO_APP;
411     }
412 
isTotalCallSuccessful()413     public boolean isTotalCallSuccessful() {
414         return mSandboxStatus == SANDBOX_STATUS_SUCCESS;
415     }
416 
getResultCode()417     public @ResultCode int getResultCode() {
418         return mResultCode;
419     }
420 
421     @VisibleForTesting
getTimeAppCalledSystemServer()422     public long getTimeAppCalledSystemServer() {
423         return mTimeAppCalledSystemServer;
424     }
425 
426     @VisibleForTesting
getTimeAppReceivedCallFromSystemServer()427     public long getTimeAppReceivedCallFromSystemServer() {
428         return mTimeAppReceivedCallFromSystemServer;
429     }
430 
getTotalCallFinishTime()431     private long getTotalCallFinishTime() {
432         switch (mMethod) {
433             case METHOD_LOAD_SDK:
434             case METHOD_LOAD_SDK_VIA_CONTROLLER:
435             case METHOD_REQUEST_SURFACE_PACKAGE:
436                 return mTimeAppReceivedCallFromSystemServer;
437             case METHOD_GET_SANDBOXED_SDKS:
438             case METHOD_GET_SANDBOXED_SDKS_VIA_CONTROLLER:
439             case METHOD_REGISTER_APP_OWNED_SDK_SANDBOX_INTERFACE:
440             case METHOD_UNREGISTER_APP_OWNED_SDK_SANDBOX_INTERFACE:
441             case METHOD_GET_APP_OWNED_SDK_SANDBOX_INTERFACES:
442             case METHOD_ADD_SDK_SANDBOX_LIFECYCLE_CALLBACK:
443             case METHOD_REMOVE_SDK_SANDBOX_LIFECYCLE_CALLBACK:
444                 return mTimeSystemServerCallFinished;
445                 // TODO(b/243367105): change finish time for the method once latency for all stages
446                 // is logged.
447             case METHOD_SYNC_DATA_FROM_CLIENT:
448                 return mTimeSystemServerReceivedCallFromApp;
449             case METHOD_UNLOAD_SDK:
450                 return mTimeSystemServerCalledApp;
451             default:
452                 return -1;
453         }
454     }
455 
getLatency(long timeEventStarted, long timeEventFinished)456     private int getLatency(long timeEventStarted, long timeEventFinished) {
457         if (timeEventStarted != -1 && timeEventFinished != -1) {
458             return ((int) (timeEventFinished - timeEventStarted));
459         }
460         return -1;
461     }
462 }
463