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 android.os.profiling;
18 
19 import android.os.Bundle;
20 
21 import java.util.UUID;
22 
23 /**
24  * Represents a single in progress tracing session and all necessary data to manage and process it.
25  */
26 public final class TracingSession {
27 
28     public enum TracingState {
29         NOT_STARTED(0),
30         PROFILING_STARTED(1),
31         PROFILING_FINISHED(2),
32         REDACTED(3),
33         COPIED_FILE(4),
34         DISCARDED(5);
35 
36         private final int mValue;
37 
TracingState(int value)38         TracingState(int value) {
39             mValue = value;
40         }
41 
getValue()42         public int getValue() {
43             return mValue;
44         }
45     }
46 
47     private Process mActiveTrace;
48     private Process mActiveRedaction;
49     private Runnable mProcessResultRunnable;
50     private final int mProfilingType;
51     private final Bundle mParams;
52     private final String mAppFilePath;
53     private final int mUid;
54     private final String mPackageName;
55     private final String mTag;
56     private final long mKeyMostSigBits;
57     private final long mKeyLeastSigBits;
58     private String mKey = null;
59     private String mFileName;
60     private String mDestinationFileName = null;
61     private String mRedactedFileName = null;
62     private long mRedactionStartTimeMs;
63     private TracingState mState;
64     private int mRetryCount = 0;
65     private long mProfilingStartTimeMs;
66     private int mMaxProfilingTimeAllowedMs = 0;
67 
TracingSession(int profilingType, Bundle params, String appFilePath, int uid, String packageName, String tag, long keyMostSigBits, long keyLeastSigBits)68     public TracingSession(int profilingType, Bundle params, String appFilePath, int uid,
69                 String packageName, String tag, long keyMostSigBits, long keyLeastSigBits) {
70         mProfilingType = profilingType;
71         mParams = params;
72         mAppFilePath = appFilePath;
73         mUid = uid;
74         mPackageName = packageName;
75         mTag = tag;
76         mKeyMostSigBits = keyMostSigBits;
77         mKeyLeastSigBits = keyLeastSigBits;
78         mState = TracingState.NOT_STARTED;
79     }
80 
getConfigBytes()81     public byte[] getConfigBytes() throws IllegalArgumentException {
82         return Configs.generateConfigForRequest(mProfilingType, mParams, mPackageName);
83     }
84 
getPostProcessingScheduleDelayMs()85     public int getPostProcessingScheduleDelayMs() throws IllegalArgumentException {
86         return Configs.getInitialProfilingTimeMs(mProfilingType, mParams);
87     }
88 
89     /**
90      * Gets the maximum profiling time allowed for this TracingSession.
91      * @return maximum profiling time allowed in ms.
92      */
getMaxProfilingTimeAllowedMs()93     public int getMaxProfilingTimeAllowedMs() {
94         if (mMaxProfilingTimeAllowedMs != 0) {
95             return mMaxProfilingTimeAllowedMs;
96         }
97         mMaxProfilingTimeAllowedMs =
98                 Configs.getMaxProfilingTimeAllowedMs(mProfilingType, mParams);
99         return mMaxProfilingTimeAllowedMs;
100     }
101 
getKey()102     public String getKey() {
103         if (mKey == null) {
104             mKey = (new UUID(mKeyMostSigBits, mKeyLeastSigBits)).toString();
105         }
106         return mKey;
107     }
108 
setActiveTrace(Process activeTrace)109     public void setActiveTrace(Process activeTrace) {
110         mActiveTrace = activeTrace;
111     }
112 
setActiveRedaction(Process activeRedaction)113     public void setActiveRedaction(Process activeRedaction) {
114         mActiveRedaction = activeRedaction;
115     }
116 
setProcessResultRunnable(Runnable processResultRunnable)117     public void setProcessResultRunnable(Runnable processResultRunnable) {
118         mProcessResultRunnable = processResultRunnable;
119     }
120 
121     // The file set here will be the name of the file that perfetto creates regardless of the
122     // type of profiling that is being done.
setFileName(String fileName)123     public void setFileName(String fileName) {
124         mFileName = fileName;
125     }
126 
setRedactedFileName(String fileName)127     public void setRedactedFileName(String fileName) {
128         mRedactedFileName = fileName;
129     }
130 
setRedactionStartTimeMs(long startTime)131     public void setRedactionStartTimeMs(long startTime) {
132         mRedactionStartTimeMs = startTime;
133     }
134 
setRetryCount(int retryCount)135     public void setRetryCount(int retryCount) {
136         mRetryCount = retryCount;
137     }
138 
setState(TracingState state)139     public void setState(TracingState state) {
140         mState = state;
141     }
142 
143     /** Increase retry count by 1 */
incrementRetryCount()144     public void incrementRetryCount() {
145         mRetryCount += 1;
146     }
147 
setProfilingStartTimeMs(long startTime)148     public void setProfilingStartTimeMs(long startTime)  {
149         mProfilingStartTimeMs = startTime;
150     }
151 
getActiveTrace()152     public Process getActiveTrace() {
153         return mActiveTrace;
154     }
155 
getActiveRedaction()156     public Process getActiveRedaction() {
157         return mActiveRedaction;
158     }
159 
getProcessResultRunnable()160     public Runnable getProcessResultRunnable() {
161         return mProcessResultRunnable;
162     }
163 
getProfilingType()164     public int getProfilingType() {
165         return mProfilingType;
166     }
167 
getAppFilePath()168     public String getAppFilePath() {
169         return mAppFilePath;
170     }
171 
getUid()172     public int getUid() {
173         return mUid;
174     }
175 
getPackageName()176     public String getPackageName() {
177         return mPackageName;
178     }
179 
getTag()180     public String getTag() {
181         return mTag;
182     }
183 
getKeyMostSigBits()184     public long getKeyMostSigBits() {
185         return mKeyMostSigBits;
186     }
187 
getKeyLeastSigBits()188     public long getKeyLeastSigBits() {
189         return mKeyLeastSigBits;
190     }
191 
192     // This returns the name of the file that perfetto created during profiling.  If the profling
193     // type was a trace collection it will return the unredacted trace file name.
getFileName()194     public String getFileName() {
195         return mFileName;
196     }
197 
getRedactedFileName()198     public String getRedactedFileName() {
199         return mRedactedFileName;
200     }
201 
getRedactionStartTimeMs()202     public long getRedactionStartTimeMs() {
203         return mRedactionStartTimeMs;
204     }
205 
getProfilingStartTimeMs()206     public long getProfilingStartTimeMs() {
207         return mProfilingStartTimeMs;
208     }
209 
210     /**
211      * Returns the full path including name of the file being returned to the client.
212      * @param appRelativePath relative path to app storage.
213      * @return full file path and name of file.
214      */
getDestinationFileName(String appRelativePath)215     public String getDestinationFileName(String appRelativePath) {
216         if (mFileName == null) {
217             return null;
218         }
219         if (mDestinationFileName == null) {
220             mDestinationFileName = mAppFilePath + appRelativePath
221                     + ((this.getRedactedFileName() == null) ? mFileName : mRedactedFileName);
222         }
223         return mDestinationFileName;
224     }
225 
getState()226     public TracingState getState() {
227         return mState;
228     }
229 
getRetryCount()230     public int getRetryCount() {
231         return mRetryCount;
232     }
233 }
234