1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.util.imetracing;
import android.annotation.Nullable;
import android.app.ActivityThread;
import android.content.Context;
import android.inputmethodservice.AbstractInputMethodService;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
import android.view.inputmethod.InputMethodManager;
import com.android.internal.view.IInputMethodManager;
import java.io.PrintWriter;
/**
*
* An abstract class that declares the methods for ime trace related operations - enable trace,
* schedule trace and add new trace to buffer. Both the client and server side classes can use
* it by getting an implementation through {@link ImeTracing#getInstance()}.
*
* @hide
*/
public abstract class ImeTracing {
static final String TAG = "imeTracing";
public static final String PROTO_ARG = "--proto-com-android-imetracing";
/* Constants describing the component type that triggered a dump. */
public static final int IME_TRACING_FROM_CLIENT = 0;
public static final int IME_TRACING_FROM_IMS = 1;
public static final int IME_TRACING_FROM_IMMS = 2;
private static ImeTracing sInstance;
static boolean sEnabled = false;
IInputMethodManager mService;
protected boolean mDumpInProgress;
protected final Object mDumpInProgressLock = new Object();
ImeTracing() throws ServiceNotFoundException {
mService = IInputMethodManager.Stub.asInterface(
ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
}
/**
* Returns an instance of {@link ImeTracingServerImpl} when called from a server side class
* and an instance of {@link ImeTracingClientImpl} when called from a client side class.
* Useful to schedule a dump for next frame or save a dump when certain methods are called.
*
* @return Instance of one of the children classes of {@link ImeTracing}
*/
public static ImeTracing getInstance() {
if (sInstance == null) {
try {
sInstance = isSystemProcess()
? new ImeTracingServerImpl() : new ImeTracingClientImpl();
} catch (RemoteException | ServiceNotFoundException e) {
Log.e(TAG, "Exception while creating ImeTracing instance", e);
}
}
return sInstance;
}
/**
* Transmits the information from client or InputMethodService side to the server, in order to
* be stored persistently to the current IME tracing dump.
*
* @param protoDump client or service side information to be stored by the server
* @param source where the information is coming from, refer to {@see #IME_TRACING_FROM_CLIENT}
* and {@see #IME_TRACING_FROM_IMS}
* @param where
*/
public void sendToService(byte[] protoDump, int source, String where) throws RemoteException {
mService.startProtoDump(protoDump, source, where);
}
/**
* @param proto dump to be added to the buffer
*/
public abstract void addToBuffer(ProtoOutputStream proto, int source);
/**
* Starts a proto dump of the client side information.
*
* @param where Place where the trace was triggered.
* @param immInstance The {@link InputMethodManager} instance to dump.
* @param icProto {@link android.view.inputmethod.InputConnection} call data in proto format.
*/
public abstract void triggerClientDump(String where, InputMethodManager immInstance,
ProtoOutputStream icProto);
/**
* Starts a proto dump of the currently connected InputMethodService information.
*
* @param where Place where the trace was triggered.
* @param service The {@link android.inputmethodservice.InputMethodService} to be dumped.
* @param icProto {@link android.view.inputmethod.InputConnection} call data in proto format.
*/
public abstract void triggerServiceDump(String where, AbstractInputMethodService service,
ProtoOutputStream icProto);
/**
* Starts a proto dump of the InputMethodManagerService information.
*
* @param where Place where the trace was triggered.
*/
public abstract void triggerManagerServiceDump(String where);
/**
* Being called while taking a bugreport so that tracing files can be included in the bugreport
* when the IME tracing is running. Does nothing otherwise.
*
* @param pw Print writer
*/
public void saveForBugreport(@Nullable PrintWriter pw) {
// does nothing by default.
}
/**
* Sets whether ime tracing is enabled.
*
* @param enabled Tells whether ime tracing should be enabled or disabled.
*/
public void setEnabled(boolean enabled) {
sEnabled = enabled;
}
/**
* @return {@code true} if dumping is enabled, {@code false} otherwise.
*/
public boolean isEnabled() {
return sEnabled;
}
/**
* @return {@code true} if tracing is available, {@code false} otherwise.
*/
public boolean isAvailable() {
return mService != null;
}
/**
* Starts a new IME trace if one is not already started.
*
* @param pw Print writer
*/
public abstract void startTrace(@Nullable PrintWriter pw);
/**
* Stops the IME trace if one was previously started and writes the current buffers to disk.
*
* @param pw Print writer
*/
public abstract void stopTrace(@Nullable PrintWriter pw);
private static boolean isSystemProcess() {
return ActivityThread.isSystem();
}
protected void logAndPrintln(@Nullable PrintWriter pw, String msg) {
Log.i(TAG, msg);
if (pw != null) {
pw.println(msg);
pw.flush();
}
}
}
|