blob: 25589f8e42cb2a67053ff3a5dda3ef2eb2e38329 [file] [log] [blame]
Jeff Hao1b012d32014-08-20 10:35:34 -07001/*
2 * Copyright (C) 2014 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
17package android.app;
18
19import android.os.Parcel;
Jeff Hao1b012d32014-08-20 10:35:34 -070020import android.os.ParcelFileDescriptor;
Andreas Gampe2b073a02017-06-22 17:28:57 -070021import android.os.Parcelable;
22import android.util.Slog;
Yi Jin148d7f42017-11-28 14:23:56 -080023import android.util.proto.ProtoOutputStream;
Andreas Gampe2b073a02017-06-22 17:28:57 -070024
25import java.io.IOException;
Andrii Kulian6b9d3a12017-11-16 14:36:36 -080026import java.util.Objects;
Jeff Hao1b012d32014-08-20 10:35:34 -070027
28/**
29 * System private API for passing profiler settings.
30 *
31 * {@hide}
32 */
33public class ProfilerInfo implements Parcelable {
34
Andreas Gampe2b073a02017-06-22 17:28:57 -070035 private static final String TAG = "ProfilerInfo";
36
Jeff Hao1b012d32014-08-20 10:35:34 -070037 /* Name of profile output file. */
38 public final String profileFile;
39
40 /* File descriptor for profile output file, can be null. */
41 public ParcelFileDescriptor profileFd;
42
43 /* Indicates sample profiling when nonzero, interval in microseconds. */
44 public final int samplingInterval;
45
46 /* Automatically stop the profiler when the app goes idle. */
47 public final boolean autoStopProfiler;
48
Andreas Gampe2b073a02017-06-22 17:28:57 -070049 /*
50 * Indicates whether to stream the profiling info to the out file continuously.
51 */
Shukang Zhou6ffd4f92017-01-25 16:07:57 -080052 public final boolean streamingOutput;
53
Andreas Gampe83085bb2017-06-26 17:54:11 -070054 /**
55 * Denotes an agent (and its parameters) to attach for profiling.
56 */
57 public final String agent;
58
Andreas Gampeab8a63b2018-01-05 13:55:15 -080059 /**
60 * Whether the {@link agent} should be attached early (before bind-application) or during
61 * bind-application. Agents attached prior to binding cannot be loaded from the app's APK
62 * directly and must be given as an absolute path (or available in the default LD_LIBRARY_PATH).
63 * Agents attached during bind-application will miss early setup (e.g., resource initialization
64 * and classloader generation), but are searched in the app's library search path.
65 */
66 public final boolean attachAgentDuringBind;
67
Shukang Zhou6ffd4f92017-01-25 16:07:57 -080068 public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop,
Andreas Gampeab8a63b2018-01-05 13:55:15 -080069 boolean streaming, String agent, boolean attachAgentDuringBind) {
Jeff Hao1b012d32014-08-20 10:35:34 -070070 profileFile = filename;
71 profileFd = fd;
72 samplingInterval = interval;
73 autoStopProfiler = autoStop;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -080074 streamingOutput = streaming;
Andreas Gampe83085bb2017-06-26 17:54:11 -070075 this.agent = agent;
Andreas Gampeab8a63b2018-01-05 13:55:15 -080076 this.attachAgentDuringBind = attachAgentDuringBind;
Jeff Hao1b012d32014-08-20 10:35:34 -070077 }
78
Andreas Gampe2b073a02017-06-22 17:28:57 -070079 public ProfilerInfo(ProfilerInfo in) {
80 profileFile = in.profileFile;
81 profileFd = in.profileFd;
82 samplingInterval = in.samplingInterval;
83 autoStopProfiler = in.autoStopProfiler;
84 streamingOutput = in.streamingOutput;
Andreas Gampe83085bb2017-06-26 17:54:11 -070085 agent = in.agent;
Andreas Gampeab8a63b2018-01-05 13:55:15 -080086 attachAgentDuringBind = in.attachAgentDuringBind;
Andreas Gampe2b073a02017-06-22 17:28:57 -070087 }
88
89 /**
Andreas Gampe5b495d52018-01-22 15:15:54 -080090 * Return a new ProfilerInfo instance, with fields populated from this object,
91 * and {@link agent} and {@link attachAgentDuringBind} as given.
92 */
93 public ProfilerInfo setAgent(String agent, boolean attachAgentDuringBind) {
94 return new ProfilerInfo(this.profileFile, this.profileFd, this.samplingInterval,
95 this.autoStopProfiler, this.streamingOutput, agent, attachAgentDuringBind);
96 }
97
98 /**
Andreas Gampe2b073a02017-06-22 17:28:57 -070099 * Close profileFd, if it is open. The field will be null after a call to this function.
100 */
101 public void closeFd() {
102 if (profileFd != null) {
103 try {
104 profileFd.close();
105 } catch (IOException e) {
106 Slog.w(TAG, "Failure closing profile fd", e);
107 }
108 profileFd = null;
109 }
110 }
111
112 @Override
Jeff Hao1b012d32014-08-20 10:35:34 -0700113 public int describeContents() {
114 if (profileFd != null) {
115 return profileFd.describeContents();
116 } else {
117 return 0;
118 }
119 }
120
Andreas Gampe2b073a02017-06-22 17:28:57 -0700121 @Override
Jeff Hao1b012d32014-08-20 10:35:34 -0700122 public void writeToParcel(Parcel out, int flags) {
123 out.writeString(profileFile);
124 if (profileFd != null) {
125 out.writeInt(1);
126 profileFd.writeToParcel(out, flags);
127 } else {
128 out.writeInt(0);
129 }
130 out.writeInt(samplingInterval);
131 out.writeInt(autoStopProfiler ? 1 : 0);
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800132 out.writeInt(streamingOutput ? 1 : 0);
Andreas Gampe83085bb2017-06-26 17:54:11 -0700133 out.writeString(agent);
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800134 out.writeBoolean(attachAgentDuringBind);
Jeff Hao1b012d32014-08-20 10:35:34 -0700135 }
136
Yi Jin148d7f42017-11-28 14:23:56 -0800137 /** @hide */
138 public void writeToProto(ProtoOutputStream proto, long fieldId) {
139 final long token = proto.start(fieldId);
140 proto.write(ProfilerInfoProto.PROFILE_FILE, profileFile);
141 if (profileFd != null) {
142 proto.write(ProfilerInfoProto.PROFILE_FD, profileFd.getFd());
143 }
144 proto.write(ProfilerInfoProto.SAMPLING_INTERVAL, samplingInterval);
145 proto.write(ProfilerInfoProto.AUTO_STOP_PROFILER, autoStopProfiler);
146 proto.write(ProfilerInfoProto.STREAMING_OUTPUT, streamingOutput);
147 proto.write(ProfilerInfoProto.AGENT, agent);
148 proto.end(token);
149 }
150
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700151 public static final @android.annotation.NonNull Parcelable.Creator<ProfilerInfo> CREATOR =
Jeff Hao1b012d32014-08-20 10:35:34 -0700152 new Parcelable.Creator<ProfilerInfo>() {
Andreas Gampe2b073a02017-06-22 17:28:57 -0700153 @Override
154 public ProfilerInfo createFromParcel(Parcel in) {
155 return new ProfilerInfo(in);
156 }
Jeff Hao1b012d32014-08-20 10:35:34 -0700157
Andreas Gampe2b073a02017-06-22 17:28:57 -0700158 @Override
159 public ProfilerInfo[] newArray(int size) {
160 return new ProfilerInfo[size];
161 }
162 };
Jeff Hao1b012d32014-08-20 10:35:34 -0700163
164 private ProfilerInfo(Parcel in) {
165 profileFile = in.readString();
166 profileFd = in.readInt() != 0 ? ParcelFileDescriptor.CREATOR.createFromParcel(in) : null;
167 samplingInterval = in.readInt();
168 autoStopProfiler = in.readInt() != 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800169 streamingOutput = in.readInt() != 0;
Andreas Gampe83085bb2017-06-26 17:54:11 -0700170 agent = in.readString();
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800171 attachAgentDuringBind = in.readBoolean();
Jeff Hao1b012d32014-08-20 10:35:34 -0700172 }
Andrii Kulian6b9d3a12017-11-16 14:36:36 -0800173
174 @Override
175 public boolean equals(Object o) {
176 if (this == o) {
177 return true;
178 }
179 if (o == null || getClass() != o.getClass()) {
180 return false;
181 }
182 final ProfilerInfo other = (ProfilerInfo) o;
183 // TODO: Also check #profileFd for equality.
184 return Objects.equals(profileFile, other.profileFile)
185 && autoStopProfiler == other.autoStopProfiler
186 && samplingInterval == other.samplingInterval
187 && streamingOutput == other.streamingOutput
188 && Objects.equals(agent, other.agent);
189 }
190
191 @Override
192 public int hashCode() {
193 int result = 17;
194 result = 31 * result + Objects.hashCode(profileFile);
195 result = 31 * result + samplingInterval;
196 result = 31 * result + (autoStopProfiler ? 1 : 0);
197 result = 31 * result + (streamingOutput ? 1 : 0);
198 result = 31 * result + Objects.hashCode(agent);
199 return result;
200 }
Jeff Hao1b012d32014-08-20 10:35:34 -0700201}