1 /*
2  * Copyright (C) 2018 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.am;
18 
19 import android.app.WaitResult;
20 import android.os.SystemClock;
21 import android.os.Trace;
22 import android.util.SparseArray;
23 
24 /**
25  * Tracks launch time of apps to be reported by {@link WaitResult}. Note that this is slightly
26  * different from {@link ActivityMetricsLogger}, but should eventually merged with it.
27  */
28 class LaunchTimeTracker {
29 
30     private final SparseArray<Entry> mWindowingModeLaunchTime = new SparseArray<>();
31 
setLaunchTime(ActivityRecord r)32     void setLaunchTime(ActivityRecord r) {
33         Entry entry = mWindowingModeLaunchTime.get(r.getWindowingMode());
34         if (entry == null){
35             entry = new Entry();
36             mWindowingModeLaunchTime.append(r.getWindowingMode(), entry);
37         }
38         entry.setLaunchTime(r);
39     }
40 
stopFullyDrawnTraceIfNeeded(int windowingMode)41     void stopFullyDrawnTraceIfNeeded(int windowingMode) {
42         final Entry entry = mWindowingModeLaunchTime.get(windowingMode);
43         if (entry == null) {
44             return;
45         }
46         entry.stopFullyDrawnTraceIfNeeded();
47     }
48 
getEntry(int windowingMode)49     Entry getEntry(int windowingMode) {
50         return mWindowingModeLaunchTime.get(windowingMode);
51     }
52 
53     static class Entry {
54 
55         long mLaunchStartTime;
56         long mFullyDrawnStartTime;
57 
setLaunchTime(ActivityRecord r)58         void setLaunchTime(ActivityRecord r) {
59             if (r.displayStartTime == 0) {
60                 r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
61                 if (mLaunchStartTime == 0) {
62                     startLaunchTraces(r.packageName);
63                     mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
64                 }
65             } else if (mLaunchStartTime == 0) {
66                 startLaunchTraces(r.packageName);
67                 mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
68             }
69         }
70 
startLaunchTraces(String packageName)71         private void startLaunchTraces(String packageName) {
72             if (mFullyDrawnStartTime != 0)  {
73                 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
74             }
75             Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
76             Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
77         }
78 
stopFullyDrawnTraceIfNeeded()79         private void stopFullyDrawnTraceIfNeeded() {
80             if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
81                 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
82                 mFullyDrawnStartTime = 0;
83             }
84         }
85     }
86 }
87