tp: add inputmethod parsing
- Extend WinscopeModule to parse inputmethod messages:
- InputMethodClients
- InputMethodManagerService
- InputMethodService
- Populate tables:
__intrinsic_inputmethod_clients
__intrinsic_inputmethod_manager_service
__intrinsic_inputmethod_service
- Add winscope.sql to stdlib to access instrinsic tables
Bug: 276433199
Test: ./tools/ninja -C out/linux_clang_release/ \
&& ./tools/diff_test_trace_processor.py \
--name-filter="InputMethod" \
./out/linux_clang_release/trace_processor_shell
Change-Id: I51376d8b4747efc6e03744b6ce44f37a9eb8cb1c
diff --git a/Android.bp b/Android.bp
index ae8225d..61dea9e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12997,6 +12997,7 @@
"src/trace_processor/perfetto_sql/stdlib/android/statsd.sql",
"src/trace_processor/perfetto_sql/stdlib/android/suspend.sql",
"src/trace_processor/perfetto_sql/stdlib/android/thread.sql",
+ "src/trace_processor/perfetto_sql/stdlib/android/winscope/inputmethod.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/**/*.sql",
"src/trace_processor/perfetto_sql/stdlib/common/args.sql",
"src/trace_processor/perfetto_sql/stdlib/common/counters.sql",
diff --git a/BUILD b/BUILD
index 5fac4da..1ec9ddd 100644
--- a/BUILD
+++ b/BUILD
@@ -2443,6 +2443,14 @@
],
)
+# GN target: //src/trace_processor/perfetto_sql/stdlib/android/winscope:winscope
+perfetto_filegroup(
+ name = "src_trace_processor_perfetto_sql_stdlib_android_winscope_winscope",
+ srcs = [
+ "src/trace_processor/perfetto_sql/stdlib/android/winscope/inputmethod.sql",
+ ],
+)
+
# GN target: //src/trace_processor/perfetto_sql/stdlib/android:android
perfetto_filegroup(
name = "src_trace_processor_perfetto_sql_stdlib_android_android",
@@ -2673,6 +2681,7 @@
":src_trace_processor_perfetto_sql_stdlib_android_auto_auto",
":src_trace_processor_perfetto_sql_stdlib_android_frames_frames",
":src_trace_processor_perfetto_sql_stdlib_android_startup_startup",
+ ":src_trace_processor_perfetto_sql_stdlib_android_winscope_winscope",
":src_trace_processor_perfetto_sql_stdlib_chrome_chrome_sql",
":src_trace_processor_perfetto_sql_stdlib_common_common",
":src_trace_processor_perfetto_sql_stdlib_counters_counters",
diff --git a/src/trace_processor/importers/common/args_tracker.h b/src/trace_processor/importers/common/args_tracker.h
index a83e5ef..964a6ad 100644
--- a/src/trace_processor/importers/common/args_tracker.h
+++ b/src/trace_processor/importers/common/args_tracker.h
@@ -119,6 +119,21 @@
return AddArgsTo(context_->storage->mutable_flow_table(), id);
}
+ BoundInserter AddArgsTo(tables::InputMethodClientsTable::Id id) {
+ return AddArgsTo(context_->storage->mutable_inputmethod_clients_table(),
+ id);
+ }
+
+ BoundInserter AddArgsTo(tables::InputMethodServiceTable::Id id) {
+ return AddArgsTo(context_->storage->mutable_inputmethod_service_table(),
+ id);
+ }
+
+ BoundInserter AddArgsTo(tables::InputMethodManagerServiceTable::Id id) {
+ return AddArgsTo(
+ context_->storage->mutable_inputmethod_manager_service_table(), id);
+ }
+
BoundInserter AddArgsTo(tables::MemorySnapshotNodeTable::Id id) {
return AddArgsTo(context_->storage->mutable_memory_snapshot_node_table(),
id);
diff --git a/src/trace_processor/importers/proto/winscope/BUILD.gn b/src/trace_processor/importers/proto/winscope/BUILD.gn
index f557b84..09b7b77 100644
--- a/src/trace_processor/importers/proto/winscope/BUILD.gn
+++ b/src/trace_processor/importers/proto/winscope/BUILD.gn
@@ -39,8 +39,9 @@
"../../../../../gn:default_deps",
"../../../../../protos/perfetto/trace:zero",
"../../../../../protos/perfetto/trace/android:zero",
- "../../../../../protos/perfetto/trace/android:winscope_regular_zero",
+ "../../../../../protos/perfetto/trace/android:winscope_common_zero",
"../../../../../protos/perfetto/trace/android:winscope_extensions_zero",
+ "../../../../../protos/perfetto/trace/android:winscope_regular_zero",
"../../../../../protos/perfetto/trace/interned_data:zero",
"../../../../../protos/perfetto/trace/profiling:zero",
"../../../../protozero",
diff --git a/src/trace_processor/importers/proto/winscope/winscope_module.cc b/src/trace_processor/importers/proto/winscope/winscope_module.cc
index a59e7eb..8d7e037 100644
--- a/src/trace_processor/importers/proto/winscope/winscope_module.cc
+++ b/src/trace_processor/importers/proto/winscope/winscope_module.cc
@@ -15,14 +15,21 @@
*/
#include "src/trace_processor/importers/proto/winscope/winscope_module.h"
+#include "protos/perfetto/trace/android/winscope_extensions.pbzero.h"
+#include "protos/perfetto/trace/android/winscope_extensions_impl.pbzero.h"
+#include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
+#include "src/trace_processor/importers/proto/winscope/winscope_args_parser.h"
namespace perfetto {
namespace trace_processor {
using perfetto::protos::pbzero::TracePacket;
+using perfetto::protos::pbzero::WinscopeExtensionsImpl;
WinscopeModule::WinscopeModule(TraceProcessorContext* context)
- : surfaceflinger_layers_parser_(context),
+ : context_{context},
+ args_parser_{pool_},
+ surfaceflinger_layers_parser_(context),
surfaceflinger_transactions_parser_(context),
shell_transitions_parser_(context),
protolog_parser_(context) {
@@ -34,6 +41,10 @@
RegisterForField(TracePacket::kShellHandlerMappingsFieldNumber, context);
RegisterForField(TracePacket::kProtologMessageFieldNumber, context);
RegisterForField(TracePacket::kProtologViewerConfigFieldNumber, context);
+ RegisterForField(TracePacket::kWinscopeExtensionsFieldNumber, context);
+
+ pool_.AddFromFileDescriptorSet(kWinscopeDescriptor.data(),
+ kWinscopeDescriptor.size());
}
void WinscopeModule::ParseTracePacketData(const TracePacket::Decoder& decoder,
@@ -64,6 +75,87 @@
protolog_parser_.ParseProtoLogViewerConfig(
decoder.protolog_viewer_config());
return;
+ case TracePacket::kWinscopeExtensionsFieldNumber:
+ ParseWinscopeExtensionsData(decoder.winscope_extensions(), timestamp);
+ return;
+ }
+}
+
+void WinscopeModule::ParseWinscopeExtensionsData(protozero::ConstBytes blob,
+ int64_t timestamp) {
+ WinscopeExtensionsImpl::Decoder decoder(blob.data, blob.size);
+
+ if (auto field =
+ decoder.Get(WinscopeExtensionsImpl::kInputmethodClientsFieldNumber);
+ field.valid()) {
+ ParseInputMethodClientsData(timestamp, field.as_bytes());
+ } else if (field = decoder.Get(
+ WinscopeExtensionsImpl::kInputmethodManagerServiceFieldNumber);
+ field.valid()) {
+ ParseInputMethodManagerServiceData(timestamp, field.as_bytes());
+ } else if (field = decoder.Get(
+ WinscopeExtensionsImpl::kInputmethodServiceFieldNumber);
+ field.valid()) {
+ ParseInputMethodServiceData(timestamp, field.as_bytes());
+ }
+}
+
+void WinscopeModule::ParseInputMethodClientsData(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ tables::InputMethodClientsTable::Row row;
+ row.ts = timestamp;
+ auto rowId =
+ context_->storage->mutable_inputmethod_clients_table()->Insert(row).id;
+
+ ArgsTracker tracker(context_);
+ auto inserter = tracker.AddArgsTo(rowId);
+ WinscopeArgsParser writer(inserter, *context_->storage.get());
+ base::Status status =
+ args_parser_.ParseMessage(blob, kInputMethodClientsProtoName,
+ nullptr /* parse all fields */, writer);
+ if (!status.ok()) {
+ context_->storage->IncrementStats(
+ stats::winscope_inputmethod_clients_parse_errors);
+ }
+}
+
+void WinscopeModule::ParseInputMethodManagerServiceData(
+ int64_t timestamp,
+ protozero::ConstBytes blob) {
+ tables::InputMethodManagerServiceTable::Row row;
+ row.ts = timestamp;
+ auto rowId = context_->storage->mutable_inputmethod_manager_service_table()
+ ->Insert(row)
+ .id;
+
+ ArgsTracker tracker(context_);
+ auto inserter = tracker.AddArgsTo(rowId);
+ WinscopeArgsParser writer(inserter, *context_->storage.get());
+ base::Status status =
+ args_parser_.ParseMessage(blob, kInputMethodManagerServiceProtoName,
+ nullptr /* parse all fields */, writer);
+ if (!status.ok()) {
+ context_->storage->IncrementStats(
+ stats::winscope_inputmethod_manager_service_parse_errors);
+ }
+}
+
+void WinscopeModule::ParseInputMethodServiceData(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ tables::InputMethodServiceTable::Row row;
+ row.ts = timestamp;
+ auto rowId =
+ context_->storage->mutable_inputmethod_service_table()->Insert(row).id;
+
+ ArgsTracker tracker(context_);
+ auto inserter = tracker.AddArgsTo(rowId);
+ WinscopeArgsParser writer(inserter, *context_->storage.get());
+ base::Status status =
+ args_parser_.ParseMessage(blob, kInputMethodServiceProtoName,
+ nullptr /* parse all fields */, writer);
+ if (!status.ok()) {
+ context_->storage->IncrementStats(
+ stats::winscope_inputmethod_service_parse_errors);
}
}
diff --git a/src/trace_processor/importers/proto/winscope/winscope_module.h b/src/trace_processor/importers/proto/winscope/winscope_module.h
index 6334411..c77fcb4 100644
--- a/src/trace_processor/importers/proto/winscope/winscope_module.h
+++ b/src/trace_processor/importers/proto/winscope/winscope_module.h
@@ -41,6 +41,27 @@
uint32_t field_id) override;
private:
+ void ParseWinscopeExtensionsData(protozero::ConstBytes blob,
+ int64_t timestamp);
+ void ParseInputMethodClientsData(int64_t timestamp,
+ protozero::ConstBytes blob);
+ void ParseInputMethodManagerServiceData(int64_t timestamp,
+ protozero::ConstBytes blob);
+ void ParseInputMethodServiceData(int64_t timestamp,
+ protozero::ConstBytes blob);
+
+ static constexpr auto* kInputMethodClientsProtoName =
+ ".perfetto.protos.InputMethodClientsTraceProto";
+ static constexpr auto* kInputMethodManagerServiceProtoName =
+ ".perfetto.protos.InputMethodManagerServiceTraceProto";
+
+ static constexpr auto* kInputMethodServiceProtoName =
+ ".perfetto.protos.InputMethodServiceTraceProto";
+
+ TraceProcessorContext* const context_;
+ DescriptorPool pool_;
+ util::ProtoToArgsParser args_parser_;
+
SurfaceFlingerLayersParser surfaceflinger_layers_parser_;
SurfaceFlingerTransactionsParser surfaceflinger_transactions_parser_;
ShellTransitionsParser shell_transitions_parser_;
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
index bd2f18d..feba87c 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
@@ -19,6 +19,7 @@
"auto",
"frames",
"startup",
+ "winscope",
]
sources = [
"anrs.sql",
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/winscope/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/android/winscope/BUILD.gn
new file mode 100644
index 0000000..93abe35
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/android/winscope/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright (C) 2024 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.
+
+import("../../../../../../gn/perfetto_sql.gni")
+
+perfetto_sql_source_set("winscope") {
+ sources = [
+ "inputmethod.sql",
+ ]
+}
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/winscope/inputmethod.sql b/src/trace_processor/perfetto_sql/stdlib/android/winscope/inputmethod.sql
new file mode 100644
index 0000000..15a4a8e
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/android/winscope/inputmethod.sql
@@ -0,0 +1,59 @@
+--
+-- Copyright 2024 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
+--
+-- https://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.
+
+-- Android inputmethod clients state dumps (from android.inputmethod data source).
+CREATE PERFETTO VIEW android_inputmethod_clients(
+ -- Dump id
+ id INT,
+ -- Timestamp when the dump was triggered
+ ts INT,
+ -- Extra args parsed from the proto message
+ arg_set_id INT
+) AS
+SELECT
+ id,
+ ts,
+ arg_set_id
+FROM __intrinsic_inputmethod_clients;
+
+-- Android inputmethod manager service state dumps (from android.inputmethod data source).
+CREATE PERFETTO VIEW android_inputmethod_manager_service(
+ -- Dump id
+ id INT,
+ -- Timestamp when the dump was triggered
+ ts INT,
+ -- Extra args parsed from the proto message
+ arg_set_id INT
+) AS
+SELECT
+ id,
+ ts,
+ arg_set_id
+FROM __intrinsic_inputmethod_manager_service;
+
+-- Android inputmethod service state dumps (from android.inputmethod data source).
+CREATE PERFETTO VIEW android_inputmethod_service(
+ -- Dump id
+ id INT,
+ -- Timestamp when the dump was triggered
+ ts INT,
+ -- Extra args parsed from the proto message
+ arg_set_id INT
+) AS
+SELECT
+ id,
+ ts,
+ arg_set_id
+FROM __intrinsic_inputmethod_service;
diff --git a/src/trace_processor/storage/stats.h b/src/trace_processor/storage/stats.h
index 7495cfc..0584d84 100644
--- a/src/trace_processor/storage/stats.h
+++ b/src/trace_processor/storage/stats.h
@@ -298,6 +298,21 @@
F(v8_unknown_code_type, kSingle, kError, kAnalysis, ""), \
F(v8_code_load_missing_code_range, kSingle, kError, kAnalysis, \
"V8 load had no code range or an empty one. Event ignored."), \
+ F(winscope_inputmethod_clients_parse_errors, \
+ kSingle, kInfo, kAnalysis, \
+ "InputMethod clients packet has unknown fields, which results in " \
+ "some arguments missing. You may need a newer version of trace " \
+ "processor to parse them."), \
+ F(winscope_inputmethod_manager_service_parse_errors, \
+ kSingle, kInfo, kAnalysis, \
+ "InputMethod manager service packet has unknown fields, which results " \
+ "in some arguments missing. You may need a newer version of trace " \
+ "processor to parse them."), \
+ F(winscope_inputmethod_service_parse_errors, \
+ kSingle, kInfo, kAnalysis, \
+ "InputMethod service packet has unknown fields, which results in " \
+ "some arguments missing. You may need a newer version of trace " \
+ "processor to parse them."), \
F(winscope_sf_layers_parse_errors, kSingle, kInfo, kAnalysis, \
"SurfaceFlinger layers snapshot has unknown fields, which results in " \
"some arguments missing. You may need a newer version of trace " \
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index 792ad4f..ff280e1 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -797,6 +797,29 @@
}
tables::JitFrameTable* mutable_jit_frame_table() { return &jit_frame_table_; }
+ const tables::InputMethodClientsTable& inputmethod_clients_table() const {
+ return inputmethod_clients_table_;
+ }
+ tables::InputMethodClientsTable* mutable_inputmethod_clients_table() {
+ return &inputmethod_clients_table_;
+ }
+
+ const tables::InputMethodManagerServiceTable&
+ inputmethod_manager_service_table() const {
+ return inputmethod_manager_service_table_;
+ }
+ tables::InputMethodManagerServiceTable*
+ mutable_inputmethod_manager_service_table() {
+ return &inputmethod_manager_service_table_;
+ }
+
+ const tables::InputMethodServiceTable& inputmethod_service_table() const {
+ return inputmethod_service_table_;
+ }
+ tables::InputMethodServiceTable* mutable_inputmethod_service_table() {
+ return &inputmethod_service_table_;
+ }
+
const tables::SurfaceFlingerLayersSnapshotTable&
surfaceflinger_layers_snapshot_table() const {
return surfaceflinger_layers_snapshot_table_;
@@ -1115,6 +1138,10 @@
tables::JitFrameTable jit_frame_table_{&string_pool_};
// Winscope tables
+ tables::InputMethodClientsTable inputmethod_clients_table_{&string_pool_};
+ tables::InputMethodManagerServiceTable inputmethod_manager_service_table_{
+ &string_pool_};
+ tables::InputMethodServiceTable inputmethod_service_table_{&string_pool_};
tables::SurfaceFlingerLayersSnapshotTable
surfaceflinger_layers_snapshot_table_{&string_pool_};
tables::SurfaceFlingerLayerTable surfaceflinger_layer_table_{&string_pool_};
diff --git a/src/trace_processor/tables/table_destructors.cc b/src/trace_processor/tables/table_destructors.cc
index eade18c..6093c83 100644
--- a/src/trace_processor/tables/table_destructors.cc
+++ b/src/trace_processor/tables/table_destructors.cc
@@ -136,6 +136,9 @@
V8RegexpCodeTable::~V8RegexpCodeTable() = default;
// winscope_tables_py.h
+InputMethodClientsTable::~InputMethodClientsTable() = default;
+InputMethodManagerServiceTable::~InputMethodManagerServiceTable() = default;
+InputMethodServiceTable::~InputMethodServiceTable() = default;
SurfaceFlingerLayersSnapshotTable::~SurfaceFlingerLayersSnapshotTable() =
default;
SurfaceFlingerLayerTable::~SurfaceFlingerLayerTable() = default;
diff --git a/src/trace_processor/tables/winscope_tables.py b/src/trace_processor/tables/winscope_tables.py
index 8a60e43..8c058aa 100644
--- a/src/trace_processor/tables/winscope_tables.py
+++ b/src/trace_processor/tables/winscope_tables.py
@@ -20,6 +20,54 @@
from python.generators.trace_processor_table.public import CppUint32
from python.generators.trace_processor_table.public import CppString
+INPUTMETHOD_CLIENTS_TABLE = Table(
+ python_module=__file__,
+ class_name='InputMethodClientsTable',
+ sql_name='__intrinsic_inputmethod_clients',
+ columns=[
+ C('ts', CppInt64()),
+ C('arg_set_id', CppUint32()),
+ ],
+ tabledoc=TableDoc(
+ doc='InputMethod clients',
+ group='Winscope',
+ columns={
+ 'ts': 'The timestamp the dump was triggered',
+ 'arg_set_id': 'Extra args parsed from the proto message',
+ }))
+
+INPUTMETHOD_MANAGER_SERVICE_TABLE = Table(
+ python_module=__file__,
+ class_name='InputMethodManagerServiceTable',
+ sql_name='__intrinsic_inputmethod_manager_service',
+ columns=[
+ C('ts', CppInt64()),
+ C('arg_set_id', CppUint32()),
+ ],
+ tabledoc=TableDoc(
+ doc='InputMethod manager service',
+ group='Winscope',
+ columns={
+ 'ts': 'The timestamp the dump was triggered',
+ 'arg_set_id': 'Extra args parsed from the proto message',
+ }))
+
+INPUTMETHOD_SERVICE_TABLE = Table(
+ python_module=__file__,
+ class_name='InputMethodServiceTable',
+ sql_name='__intrinsic_inputmethod_service',
+ columns=[
+ C('ts', CppInt64()),
+ C('arg_set_id', CppUint32()),
+ ],
+ tabledoc=TableDoc(
+ doc='InputMethod service',
+ group='Winscope',
+ columns={
+ 'ts': 'The timestamp the dump was triggered',
+ 'arg_set_id': 'Extra args parsed from the proto message',
+ }))
+
SURFACE_FLINGER_LAYERS_SNAPSHOT_TABLE = Table(
python_module=__file__,
class_name='SurfaceFlingerLayersSnapshotTable',
@@ -128,6 +176,9 @@
# Keep this list sorted.
ALL_TABLES = [
PROTOLOG_TABLE,
+ INPUTMETHOD_CLIENTS_TABLE,
+ INPUTMETHOD_MANAGER_SERVICE_TABLE,
+ INPUTMETHOD_SERVICE_TABLE,
SURFACE_FLINGER_LAYERS_SNAPSHOT_TABLE,
SURFACE_FLINGER_LAYER_TABLE,
SURFACE_FLINGER_TRANSACTIONS_TABLE,
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 991079a..bbbecac 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -873,6 +873,10 @@
RegisterStaticTable(storage->jit_code_table());
RegisterStaticTable(storage->jit_frame_table());
+ RegisterStaticTable(storage->inputmethod_clients_table());
+ RegisterStaticTable(storage->inputmethod_manager_service_table());
+ RegisterStaticTable(storage->inputmethod_service_table());
+
RegisterStaticTable(storage->surfaceflinger_layers_snapshot_table());
RegisterStaticTable(storage->surfaceflinger_layer_table());
RegisterStaticTable(storage->surfaceflinger_transactions_table());
diff --git a/test/trace_processor/diff_tests/include_index.py b/test/trace_processor/diff_tests/include_index.py
index cb82c55..dd8fade 100644
--- a/test/trace_processor/diff_tests/include_index.py
+++ b/test/trace_processor/diff_tests/include_index.py
@@ -50,6 +50,9 @@
from diff_tests.parser.android.tests import AndroidParser
from diff_tests.parser.android.tests_bugreport import AndroidBugreport
from diff_tests.parser.android.tests_games import AndroidGames
+from diff_tests.parser.android.tests_inputmethod_clients import InputMethodClients
+from diff_tests.parser.android.tests_inputmethod_manager_service import InputMethodManagerService
+from diff_tests.parser.android.tests_inputmethod_service import InputMethodService
from diff_tests.parser.android.tests_protolog import ProtoLog
from diff_tests.parser.android.tests_shell_transitions import ShellTransitions
from diff_tests.parser.android.tests_surfaceflinger_layers import SurfaceFlingerLayers
@@ -183,6 +186,12 @@
'SmokeComputeMetrics').fetch(),
*SmokeJson(index_path, 'parser/smoke', 'SmokeJson').fetch(),
*SmokeSchedEvents(index_path, 'parser/smoke', 'SmokeSchedEvents').fetch(),
+ *InputMethodClients(index_path, 'parser/android',
+ 'InputMethodClients').fetch(),
+ *InputMethodManagerService(index_path, 'parser/android',
+ 'InputMethodManagerService').fetch(),
+ *InputMethodService(index_path, 'parser/android',
+ 'InputMethodService').fetch(),
*SurfaceFlingerLayers(index_path, 'parser/android',
'SurfaceFlingerLayers').fetch(),
*SurfaceFlingerTransactions(index_path, 'parser/android',
diff --git a/test/trace_processor/diff_tests/parser/android/inputmethod_clients.textproto b/test/trace_processor/diff_tests/parser/android/inputmethod_clients.textproto
new file mode 100644
index 0000000..0d33da4
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/inputmethod_clients.textproto
@@ -0,0 +1,247 @@
+packet {
+ trusted_uid: 9999
+ clock_snapshot {
+ clocks {
+ clock_id: 6
+ timestamp: 118567353207
+ }
+ clocks {
+ clock_id: 2
+ timestamp: 1710943499588000057
+ }
+ clocks {
+ clock_id: 4
+ timestamp: 118562961198
+ }
+ clocks {
+ clock_id: 1
+ timestamp: 1710943499592392595
+ }
+ clocks {
+ clock_id: 3
+ timestamp: 118567353939
+ }
+ clocks {
+ clock_id: 5
+ timestamp: 118567354265
+ }
+ primary_trace_clock: BUILTIN_CLOCK_BOOTTIME
+ }
+ trusted_packet_sequence_id: 1
+}
+
+packet {
+ trusted_uid: 10254
+ timestamp: 119232512509
+ trusted_packet_sequence_id: 2
+ previous_packet_dropped: true
+ trusted_pid: 2798
+ first_packet_on_sequence: true
+ winscope_extensions {
+ [perfetto.protos.WinscopeExtensionsImpl.inputmethod_clients] {
+ where: "InputMethodManager#showSoftInput"
+ client {
+ input_method_manager {
+ cur_id: "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"
+ active: true
+ served_view: "com.google.android.apps.nexuslauncher.search.SearchEditText{ba34590 VFED..CL. .F....ID 0,0-688,151 #7f0a01e6 app:id/input aid=1073741824}"
+ next_served_view: "com.google.android.apps.nexuslauncher.search.SearchEditText{ba34590 VFED..CL. .F....ID 0,0-688,151 #7f0a01e6 app:id/input aid=1073741824}"
+ }
+ view_root_impl {
+ view: "com.android.internal.policy.DecorView{1cd90e0 V.E...... R.....ID 0,0-1080,2400 aid=0}[NexusLauncherActivity]"
+ app_visible: true
+ width: 1080
+ height: 2400
+ added: true
+ win_frame {
+ right: 1080
+ bottom: 2400
+ }
+ last_window_insets: "WindowInsets{\n statusBars=Insets{left=0, top=128, right=0, bottom=0} max=Insets{left=0, top=128, right=0, bottom=0} vis=true boundingRects=[Rect(0, 0 - 1080, 128)] maxBoundingRects=[Rect(0, 0 - 1080, 128)]\n navigationBars=Insets{left=0, top=0, right=0, bottom=63} max=Insets{left=0, top=0, right=0, bottom=63} vis=true boundingRects=[Rect(0, 2337 - 1080, 2400)] maxBoundingRects=[Rect(0, 2337 - 1080, 2400)]\n captionBar=null max=null vis=false boundingRects=null maxBoundingRects=null\n ime=null max=null vis=false boundingRects=null maxBoundingRects=null\n systemGestures=Insets{left=78, top=160, right=78, bottom=84} max=Insets{left=78, top=160, right=78, bottom=84} vis=true boundingRects=[Rect(0, 0 - 1080, 160), Rect(1002, 0 - 1080, 2400), Rect(0, 2316 - 1080, 2400), Rect(0, 0 - 78, 2400)] maxBoundingRects=[Rect(0, 0 - 1080, 160), Rect(1002, 0 - 1080, 2400), Rect(0, 2316 - 1080, 2400), Rect(0, 0 - 78, 2400)]\n mandatorySystemGestures=Insets{left=0, top=160, right=0, bottom=84} max=Insets{left=0, top=160, right=0, bottom=84} vis=true boundingRects=[Rect(0, 0 - 1080, 160), Rect(0, 2316 - 1080, 2400)] maxBoundingRects=[Rect(0, 0 - 1080, 160), Rect(0, 2316 - 1080, 2400)]\n tappableElement=Insets{left=0, top=128, right=0, bottom=0} max=Insets{left=0, top=128, right=0, bottom=0} vis=true boundingRects=[Rect(0, 0 - 1080, 128)] maxBoundingRects=[Rect(0, 0 - 1080, 128)]\n displayCutout=Insets{left=0, top=128, right=0, bottom=0} max=Insets{left=0, top=128, right=0, bottom=0} vis=true boundingRects=[Rect(0, 0 - 1080, 128)] maxBoundingRects=[Rect(0, 0 - 1080, 128)]\n windowDecor=null max=null vis=false boundingRects=null maxBoundingRects=null\n systemOverlays=null max=null vis=false boundingRects=null maxBoundingRects=null\n cutout=DisplayCutout{insets=Rect(0, 128 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(492, 0 - 610, 128), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]} cutoutPathParserInfo={CutoutPathParserInfo{displayWidth=1080 displayHeight=2400 physicalDisplayWidth=1080 physicalDisplayHeight=2400 density={2.625} cutoutSpec={M 507,64 a 33,33 0 1 0 66,0 33,33 0 1 0 -66,0 Z @left} rotation={0} scale={1.0} physicalPixelDisplaySizeRatio={1.0}}} sideOverrides={}}\n roundedCorners=RoundedCorners{[RoundedCorner{position=TopLeft, radius=28, center=Point(28, 28)}, RoundedCorner{position=TopRight, radius=28, center=Point(1052, 28)}, RoundedCorner{position=BottomRight, radius=28, center=Point(1052, 2372)}, RoundedCorner{position=BottomLeft, radius=28, center=Point(28, 2372)}]}\n privacyIndicatorBounds=PrivacyIndicatorBounds {static bounds=Rect(827, 0 - 1043, 128) rotation=0}\n displayShape=DisplayShape{ spec=-2047108559 displayWidth=1080 displayHeight=2400 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}\n forceConsumingTypes=\n suppressScrimTypes=navigationBars\n compatInsetsTypes=statusBars navigationBars captionBar displayCutout systemOverlays\n compatIgnoreVisibility=true\n systemWindowInsetsConsumed=false\n stableInsetsConsumed=false\n displayCutoutConsumed=false\n \n frameWidth=1080\n frameHeight=2400}"
+ soft_input_mode: "STATE_UNSPECIFIED|ADJUST_NOTHING|IS_FORWARD_NAVIGATION"
+ window_attributes {
+ type: 1
+ width: -1
+ height: -1
+ soft_input_mode: 48
+ format: TRANSPARENT
+ window_animations: 16974588
+ alpha: 1
+ screen_brightness: -1
+ button_brightness: -1
+ user_activity_timeout: -1
+ flags: 2173763840
+ private_flags: 268468800
+ subtree_system_ui_visibility_flags: 1792
+ behavior: 1
+ }
+ }
+ insets_controller {
+ state {
+ sources {
+ visible_frame {
+ top: 2274
+ right: 1080
+ bottom: 2400
+ }
+ type_number: 8
+ }
+ display_frame {
+ right: 1080
+ bottom: 2400
+ }
+ display_cutout {
+ insets {
+ top: 128
+ }
+ bound_top {
+ left: 492
+ right: 610
+ bottom: 128
+ }
+ side_overrides: -1
+ side_overrides: -1
+ side_overrides: -1
+ side_overrides: -1
+ }
+ }
+ }
+ ime_insets_source_consumer {
+ insets_source_consumer {
+ has_window_focus: true
+ is_requested_visible: true
+ source_control {
+ position {
+ y: 128
+ }
+ leash {
+ hash_code: 135479902
+ name: "Surface(name=cff3eb3 InputMethod)/@0xf85eda5 - animation-leash of insets_animation"
+ layerId: 105
+ }
+ type_number: 8
+ }
+ type_number: 8
+ }
+ }
+ editor_info {
+ input_type: 1
+ ime_options: 33554435
+ private_ime_options: "com.google.android.inputmethod.latin.appSupportsSmartComposeAndDel,com.google.android.inputmethod.latin.canary.appSupportsSmartComposeAndDel,com.google.android.inputmethod.latin.dev.appSupportsSmartComposeAndDel"
+ package_name: "com.google.android.apps.nexuslauncher"
+ field_id: 2131362278
+ }
+ ime_focus_controller {
+ has_ime_focus: true
+ }
+ }
+ }
+ }
+}
+
+packet {
+ trusted_uid: 10254
+ timestamp: 119237883196
+ trusted_packet_sequence_id: 2
+ trusted_pid: 2798
+
+ winscope_extensions {
+ [perfetto.protos.WinscopeExtensionsImpl.inputmethod_clients] {
+ where: "InputMethodManager#showSoftInput"
+ client {
+ input_method_manager {
+ cur_id: "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"
+ active: true
+ served_view: "com.google.android.apps.nexuslauncher.search.SearchEditText{ba34590 VFED..CL. .F....ID 0,0-688,151 #7f0a01e6 app:id/input aid=1073741824}"
+ next_served_view: "com.google.android.apps.nexuslauncher.search.SearchEditText{ba34590 VFED..CL. .F....ID 0,0-688,151 #7f0a01e6 app:id/input aid=1073741824}"
+ }
+ view_root_impl {
+ view: "com.android.internal.policy.DecorView{1cd90e0 V.E...... R.....ID 0,0-1080,2400 aid=0}[NexusLauncherActivity]"
+ app_visible: true
+ width: 1080
+ height: 2400
+ added: true
+ win_frame {
+ right: 1080
+ bottom: 2400
+ }
+ last_window_insets: "WindowInsets{\n statusBars=Insets{left=0, top=128, right=0, bottom=0} max=Insets{left=0, top=128, right=0, bottom=0} vis=true boundingRects=[Rect(0, 0 - 1080, 128)] maxBoundingRects=[Rect(0, 0 - 1080, 128)]\n navigationBars=Insets{left=0, top=0, right=0, bottom=63} max=Insets{left=0, top=0, right=0, bottom=63} vis=true boundingRects=[Rect(0, 2337 - 1080, 2400)] maxBoundingRects=[Rect(0, 2337 - 1080, 2400)]\n captionBar=null max=null vis=false boundingRects=null maxBoundingRects=null\n ime=null max=null vis=false boundingRects=null maxBoundingRects=null\n systemGestures=Insets{left=78, top=160, right=78, bottom=84} max=Insets{left=78, top=160, right=78, bottom=84} vis=true boundingRects=[Rect(0, 0 - 1080, 160), Rect(1002, 0 - 1080, 2400), Rect(0, 2316 - 1080, 2400), Rect(0, 0 - 78, 2400)] maxBoundingRects=[Rect(0, 0 - 1080, 160), Rect(1002, 0 - 1080, 2400), Rect(0, 2316 - 1080, 2400), Rect(0, 0 - 78, 2400)]\n mandatorySystemGestures=Insets{left=0, top=160, right=0, bottom=84} max=Insets{left=0, top=160, right=0, bottom=84} vis=true boundingRects=[Rect(0, 0 - 1080, 160), Rect(0, 2316 - 1080, 2400)] maxBoundingRects=[Rect(0, 0 - 1080, 160), Rect(0, 2316 - 1080, 2400)]\n tappableElement=Insets{left=0, top=128, right=0, bottom=0} max=Insets{left=0, top=128, right=0, bottom=0} vis=true boundingRects=[Rect(0, 0 - 1080, 128)] maxBoundingRects=[Rect(0, 0 - 1080, 128)]\n displayCutout=Insets{left=0, top=128, right=0, bottom=0} max=Insets{left=0, top=128, right=0, bottom=0} vis=true boundingRects=[Rect(0, 0 - 1080, 128)] maxBoundingRects=[Rect(0, 0 - 1080, 128)]\n windowDecor=null max=null vis=false boundingRects=null maxBoundingRects=null\n systemOverlays=null max=null vis=false boundingRects=null maxBoundingRects=null\n cutout=DisplayCutout{insets=Rect(0, 128 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(492, 0 - 610, 128), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]} cutoutPathParserInfo={CutoutPathParserInfo{displayWidth=1080 displayHeight=2400 physicalDisplayWidth=1080 physicalDisplayHeight=2400 density={2.625} cutoutSpec={M 507,64 a 33,33 0 1 0 66,0 33,33 0 1 0 -66,0 Z @left} rotation={0} scale={1.0} physicalPixelDisplaySizeRatio={1.0}}} sideOverrides={}}\n roundedCorners=RoundedCorners{[RoundedCorner{position=TopLeft, radius=28, center=Point(28, 28)}, RoundedCorner{position=TopRight, radius=28, center=Point(1052, 28)}, RoundedCorner{position=BottomRight, radius=28, center=Point(1052, 2372)}, RoundedCorner{position=BottomLeft, radius=28, center=Point(28, 2372)}]}\n privacyIndicatorBounds=PrivacyIndicatorBounds {static bounds=Rect(827, 0 - 1043, 128) rotation=0}\n displayShape=DisplayShape{ spec=-2047108559 displayWidth=1080 displayHeight=2400 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}\n forceConsumingTypes=\n suppressScrimTypes=navigationBars\n compatInsetsTypes=statusBars navigationBars captionBar displayCutout systemOverlays\n compatIgnoreVisibility=true\n systemWindowInsetsConsumed=false\n stableInsetsConsumed=false\n displayCutoutConsumed=false\n \n frameWidth=1080\n frameHeight=2400}"
+ soft_input_mode: "STATE_UNSPECIFIED|ADJUST_NOTHING|IS_FORWARD_NAVIGATION"
+ window_attributes {
+ type: 1
+ width: -1
+ height: -1
+ soft_input_mode: 48
+ format: TRANSPARENT
+ window_animations: 16974588
+ alpha: 1
+ screen_brightness: -1
+ button_brightness: -1
+ user_activity_timeout: -1
+ flags: 2173763840
+ private_flags: 268468800
+ subtree_system_ui_visibility_flags: 1792
+ behavior: 1
+ }
+ }
+ insets_controller {
+ state {
+ sources {
+ visible_frame {
+ top: 2274
+ right: 1080
+ bottom: 2400
+ }
+ type_number: 8
+ }
+ display_frame {
+ right: 1080
+ bottom: 2400
+ }
+ display_cutout {
+ insets {
+ top: 128
+ }
+ bound_top {
+ left: 492
+ right: 610
+ bottom: 128
+ }
+ side_overrides: -1
+ side_overrides: -1
+ side_overrides: -1
+ side_overrides: -1
+ }
+ }
+ }
+ ime_insets_source_consumer {
+ insets_source_consumer {
+ has_window_focus: true
+ source_control {
+ position {
+ y: 128
+ }
+ leash {
+ hash_code: 135479902
+ name: "Surface(name=cff3eb3 InputMethod)/@0xf85eda5 - animation-leash of insets_animation"
+ layerId: 105
+ }
+ type_number: 8
+ }
+ type_number: 8
+ }
+ }
+ editor_info {
+ input_type: 1
+ ime_options: 33554435
+ private_ime_options: "com.google.android.inputmethod.latin.appSupportsSmartComposeAndDel,com.google.android.inputmethod.latin.canary.appSupportsSmartComposeAndDel,com.google.android.inputmethod.latin.dev.appSupportsSmartComposeAndDel"
+ package_name: "com.google.android.apps.nexuslauncher"
+ field_id: 2131362278
+ }
+ ime_focus_controller {
+ has_ime_focus: true
+ }
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/diff_tests/parser/android/inputmethod_manager_service.textproto b/test/trace_processor/diff_tests/parser/android/inputmethod_manager_service.textproto
new file mode 100644
index 0000000..9626b31
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/inputmethod_manager_service.textproto
@@ -0,0 +1,97 @@
+packet {
+ clock_snapshot {
+ primary_trace_clock: BUILTIN_CLOCK_BOOTTIME
+ clocks {
+ clock_id: 6
+ timestamp: 39116317767
+ }
+ clocks {
+ clock_id: 2
+ timestamp: 1711013588124000018
+ }
+ clocks {
+ clock_id: 4
+ timestamp: 39115297096
+ }
+ clocks {
+ clock_id: 1
+ timestamp: 1711013588125020892
+ }
+ clocks {
+ clock_id: 3
+ timestamp: 39116318011
+ }
+ clocks {
+ clock_id: 5
+ timestamp: 39116318093
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 1
+}
+
+packet {
+ first_packet_on_sequence: true
+ timestamp: 39998329771
+ winscope_extensions {
+ [perfetto.protos.WinscopeExtensionsImpl.inputmethod_manager_service] {
+ where: "InputMethodManagerService#startInputOrWindowGainedFocus"
+ input_method_manager_service {
+ cur_method_id: "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"
+ cur_seq: 1
+ cur_client: "ClientState{6c16bdd mUid=10254 mPid=2790 mSelfReportedDisplayId=0}"
+ cur_focused_window_name: "a74954b com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity"
+ cur_focused_window_soft_input_mode: "STATE_UNSPECIFIED|ADJUST_NOTHING|IS_FORWARD_NAVIGATION"
+ last_ime_target_window_name: "a74954b com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity"
+ cur_focused_window_soft_input_mode: "STATE_UNSPECIFIED|ADJUST_NOTHING|IS_FORWARD_NAVIGATION"
+ cur_attribute {
+ package_name: "com.google.android.apps.nexuslauncher"
+ }
+ cur_id: "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"
+ cur_token: "android.os.Binder@3abdbc4"
+ system_ready: true
+ have_connection: true
+ bound_to_method: true
+ is_interactive: true
+ }
+ }
+ }
+ trusted_uid: 1000
+ trusted_packet_sequence_id: 4
+ trusted_pid: 1678
+ previous_packet_dropped: true
+}
+
+packet {
+ timestamp: 40003054136
+ winscope_extensions {
+ [perfetto.protos.WinscopeExtensionsImpl.inputmethod_manager_service] {
+ where: "InputMethodManagerService#showSoftInput"
+ input_method_manager_service {
+ cur_method_id: "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"
+ cur_seq: 2
+ cur_client: "ClientState{6c16bdd mUid=10254 mPid=2790 mSelfReportedDisplayId=0}"
+ cur_focused_window_name: "a74954b com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity"
+ cur_focused_window_soft_input_mode: "STATE_UNSPECIFIED|ADJUST_NOTHING|IS_FORWARD_NAVIGATION"
+ last_ime_target_window_name: "a74954b com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity"
+ cur_focused_window_soft_input_mode: "STATE_UNSPECIFIED|ADJUST_NOTHING|IS_FORWARD_NAVIGATION"
+ cur_attribute {
+ input_type: 1
+ ime_options: 33554435
+ private_ime_options: "com.google.android.inputmethod.latin.appSupportsSmartComposeAndDel,com.google.android.inputmethod.latin.canary.appSupportsSmartComposeAndDel,com.google.android.inputmethod.latin.dev.appSupportsSmartComposeAndDel"
+ package_name: "com.google.android.apps.nexuslauncher"
+ field_id: 2131362278
+ }
+ cur_id: "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"
+ cur_token: "android.os.Binder@3abdbc4"
+ system_ready: true
+ have_connection: true
+ bound_to_method: true
+ is_interactive: true
+ }
+ }
+ }
+ trusted_uid: 1000
+ trusted_packet_sequence_id: 4
+ trusted_pid: 1678
+}
diff --git a/test/trace_processor/diff_tests/parser/android/inputmethod_service.textproto b/test/trace_processor/diff_tests/parser/android/inputmethod_service.textproto
new file mode 100644
index 0000000..463913a
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/inputmethod_service.textproto
@@ -0,0 +1,94 @@
+packet {
+ trusted_uid: 9999
+ clock_snapshot {
+ clocks {
+ clock_id: 6
+ timestamp: 61175548939
+ }
+ clocks {
+ clock_id: 2
+ timestamp: 1710950518184000029
+ }
+ clocks {
+ clock_id: 4
+ timestamp: 61168655343
+ }
+ clocks {
+ clock_id: 1
+ timestamp: 1710950518190893869
+ }
+ clocks {
+ clock_id: 3
+ timestamp: 61175549223
+ }
+ clocks {
+ clock_id: 5
+ timestamp: 61175549468
+ }
+ primary_trace_clock: BUILTIN_CLOCK_BOOTTIME
+ }
+ trusted_packet_sequence_id: 1
+}
+
+packet {
+ trusted_uid: 10215
+ timestamp: 61829562285
+ trusted_packet_sequence_id: 4
+ previous_packet_dropped: true
+ trusted_pid: 4233
+ first_packet_on_sequence: true
+ winscope_extensions {
+ [perfetto.protos.WinscopeExtensionsImpl.inputmethod_service] {
+ where: "InputMethodService#doFinishInput"
+ input_method_service {
+ soft_input_window {
+ window_state: 2
+ }
+ configuration: "{1.0 ?mcc0mnc [en_US] ldltr sw411dp w411dp h842dp 420dpi nrml long hdr widecg port night finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1080, 2400) mAppBounds=Rect(0, 128 - 1080, 2337) mMaxBounds=Rect(0, 0 - 1080, 2400) mDisplayRotation=ROTATION_0 mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} s.11 fontWeightAdjustment=0}"
+ token: "android.os.BinderProxy@50043d1"
+ input_binding: "InputBinding{android.os.BinderProxy@cbb5415 / uid 10254 / pid 2812}"
+ input_started: true
+ input_editor_info {
+ package_name: "com.google.android.apps.nexuslauncher"
+ }
+ candidates_visibility: 4
+ last_computed_insets {
+ content_top_insets: 126
+ touchable_insets: 2
+ touchable_region: "SkRegion()"
+ }
+ settings_observer: "SettingsObserver{mShowImeWithHardKeyboard=1}"
+ }
+ }
+ }
+}
+
+packet {
+ trusted_uid: 10215
+ timestamp: 61831101307
+ trusted_packet_sequence_id: 4
+ trusted_pid: 4233
+ winscope_extensions {
+ [perfetto.protos.WinscopeExtensionsImpl.inputmethod_service] {
+ where: "InputMethodService#doStartInput"
+ input_method_service {
+ soft_input_window {
+ window_state: 2
+ }
+ configuration: "{1.0 ?mcc0mnc [en_US] ldltr sw411dp w411dp h842dp 420dpi nrml long hdr widecg port night finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1080, 2400) mAppBounds=Rect(0, 128 - 1080, 2337) mMaxBounds=Rect(0, 0 - 1080, 2400) mDisplayRotation=ROTATION_0 mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} s.11 fontWeightAdjustment=0}"
+ token: "android.os.BinderProxy@50043d1"
+ input_binding: "InputBinding{android.os.BinderProxy@cbb5415 / uid 10254 / pid 2812}"
+ input_editor_info {
+ package_name: "com.google.android.apps.nexuslauncher"
+ }
+ candidates_visibility: 4
+ last_computed_insets {
+ content_top_insets: 126
+ touchable_insets: 2
+ touchable_region: "SkRegion()"
+ }
+ settings_observer: "SettingsObserver{mShowImeWithHardKeyboard=1}"
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/diff_tests/parser/android/tests_inputmethod_clients.py b/test/trace_processor/diff_tests/parser/android/tests_inputmethod_clients.py
new file mode 100644
index 0000000..74b2760
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/tests_inputmethod_clients.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# Copyright (C) 2024 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 a
+#
+# 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.
+
+from python.generators.diff_tests.testing import Path
+from python.generators.diff_tests.testing import Csv
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class InputMethodClients(TestSuite):
+
+ def test_has_expected_rows(self):
+ return DiffTestBlueprint(
+ trace=Path('inputmethod_clients.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.inputmethod;
+ SELECT
+ id, ts
+ FROM
+ android_inputmethod_clients;
+ """,
+ out=Csv("""
+ "id","ts"
+ 0,119232512509
+ 1,119237883196
+ """))
+
+ def test_has_expected_args(self):
+ return DiffTestBlueprint(
+ trace=Path('inputmethod_clients.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.inputmethod;
+ SELECT
+ args.key, args.display_value
+ FROM
+ android_inputmethod_clients AS imc JOIN args ON imc.arg_set_id = args.arg_set_id
+ WHERE imc.id = 0
+ ORDER BY args.key
+ LIMIT 10;
+ """,
+ out=Csv("""
+ "key","display_value"
+ "client.editor_info.field_id","2131362278"
+ "client.editor_info.ime_options","33554435"
+ "client.editor_info.input_type","1"
+ "client.editor_info.package_name","com.google.android.apps.nexuslauncher"
+ "client.editor_info.private_ime_options","com.google.android.inputmethod.latin.appSupportsSmartComposeAndDel,com.google.android.inputmethod.latin.canary.appSupportsSmartComposeAndDel,com.google.android.inputmethod.latin.dev.appSupportsSmartComposeAndDel"
+ "client.ime_focus_controller.has_ime_focus","true"
+ "client.ime_insets_source_consumer.insets_source_consumer.has_window_focus","true"
+ "client.ime_insets_source_consumer.insets_source_consumer.is_requested_visible","true"
+ "client.ime_insets_source_consumer.insets_source_consumer.source_control.leash.hash_code","135479902"
+ "client.ime_insets_source_consumer.insets_source_consumer.source_control.leash.layerId","105"
+ """))
diff --git a/test/trace_processor/diff_tests/parser/android/tests_inputmethod_manager_service.py b/test/trace_processor/diff_tests/parser/android/tests_inputmethod_manager_service.py
new file mode 100644
index 0000000..612f5b8
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/tests_inputmethod_manager_service.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+# Copyright (C) 2024 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 a
+#
+# 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.
+
+from python.generators.diff_tests.testing import Path
+from python.generators.diff_tests.testing import Csv
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class InputMethodManagerService(TestSuite):
+
+ def test_has_expected_rows(self):
+ return DiffTestBlueprint(
+ trace=Path('inputmethod_manager_service.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.inputmethod;
+ SELECT
+ id, ts
+ FROM
+ android_inputmethod_manager_service;
+ """,
+ out=Csv("""
+ "id","ts"
+ 0,39998329771
+ 1,40003054136
+ """))
+
+ def test_has_expected_args(self):
+ return DiffTestBlueprint(
+ trace=Path('inputmethod_manager_service.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.inputmethod;
+ SELECT
+ args.key, args.display_value
+ FROM
+ android_inputmethod_manager_service AS imms JOIN args ON imms.arg_set_id = args.arg_set_id
+ WHERE imms.id = 0
+ ORDER BY args.key;
+ """,
+ out=Csv("""
+ "key","display_value"
+ "input_method_manager_service.bound_to_method","true"
+ "input_method_manager_service.cur_attribute.package_name","com.google.android.apps.nexuslauncher"
+ "input_method_manager_service.cur_client","ClientState{6c16bdd mUid=10254 mPid=2790 mSelfReportedDisplayId=0}"
+ "input_method_manager_service.cur_focused_window_name","a74954b com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity"
+ "input_method_manager_service.cur_focused_window_soft_input_mode","STATE_UNSPECIFIED|ADJUST_NOTHING|IS_FORWARD_NAVIGATION"
+ "input_method_manager_service.cur_id","com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"
+ "input_method_manager_service.cur_method_id","com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"
+ "input_method_manager_service.cur_seq","1"
+ "input_method_manager_service.cur_token","android.os.Binder@3abdbc4"
+ "input_method_manager_service.have_connection","true"
+ "input_method_manager_service.is_interactive","true"
+ "input_method_manager_service.last_ime_target_window_name","a74954b com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity"
+ "input_method_manager_service.system_ready","true"
+ "where","InputMethodManagerService#startInputOrWindowGainedFocus"
+ """))
diff --git a/test/trace_processor/diff_tests/parser/android/tests_inputmethod_service.py b/test/trace_processor/diff_tests/parser/android/tests_inputmethod_service.py
new file mode 100644
index 0000000..4ec909c
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/tests_inputmethod_service.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+# Copyright (C) 2024 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 a
+#
+# 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.
+
+from python.generators.diff_tests.testing import Path
+from python.generators.diff_tests.testing import Csv
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class InputMethodService(TestSuite):
+
+ def test_has_expected_rows(self):
+ return DiffTestBlueprint(
+ trace=Path('inputmethod_service.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.inputmethod;
+ SELECT
+ id, ts
+ FROM
+ android_inputmethod_service;
+ """,
+ out=Csv("""
+ "id","ts"
+ 0,61829562285
+ 1,61831101307
+ """))
+
+ def test_has_expected_args(self):
+ return DiffTestBlueprint(
+ trace=Path('inputmethod_service.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.inputmethod;
+ SELECT
+ args.key, args.display_value
+ FROM
+ android_inputmethod_service AS ims JOIN args ON ims.arg_set_id = args.arg_set_id
+ WHERE ims.id = 0
+ ORDER BY args.key;
+ """,
+ out=Csv("""
+ "key","display_value"
+ "input_method_service.candidates_visibility","4"
+ "input_method_service.configuration","{1.0 ?mcc0mnc [en_US] ldltr sw411dp w411dp h842dp 420dpi nrml long hdr widecg port night finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1080, 2400) mAppBounds=Rect(0, 128 - 1080, 2337) mMaxBounds=Rect(0, 0 - 1080, 2400) mDisplayRotation=ROTATION_0 mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} s.11 fontWeightAdjustment=0}"
+ "input_method_service.input_binding","InputBinding{android.os.BinderProxy@cbb5415 / uid 10254 / pid 2812}"
+ "input_method_service.input_editor_info.package_name","com.google.android.apps.nexuslauncher"
+ "input_method_service.input_started","true"
+ "input_method_service.last_computed_insets.content_top_insets","126"
+ "input_method_service.last_computed_insets.touchable_insets","2"
+ "input_method_service.last_computed_insets.touchable_region","SkRegion()"
+ "input_method_service.settings_observer","SettingsObserver{mShowImeWithHardKeyboard=1}"
+ "input_method_service.soft_input_window.window_state","2"
+ "input_method_service.token","android.os.BinderProxy@50043d1"
+ "where","InputMethodService#doFinishInput"
+ """))