diff options
31 files changed, 718 insertions, 100 deletions
diff --git a/cmds/incident_helper/IncidentHelper.cpp b/cmds/incident_helper/IncidentHelper.cpp index 664c48f75f9f..fba5e662b7c1 100644 --- a/cmds/incident_helper/IncidentHelper.cpp +++ b/cmds/incident_helper/IncidentHelper.cpp @@ -29,8 +29,37 @@ using namespace android::base; using namespace android::os; +using namespace google::protobuf; using namespace std; +static bool +SetTableField(::google::protobuf::Message* message, string field_name, string field_value) { + const Descriptor* descriptor = message->GetDescriptor(); + const Reflection* reflection = message->GetReflection(); + + const FieldDescriptor* field = descriptor->FindFieldByName(field_name); + switch (field->type()) { + case FieldDescriptor::TYPE_STRING: + reflection->SetString(message, field, field_value); + return true; + case FieldDescriptor::TYPE_INT64: + reflection->SetInt64(message, field, atol(field_value.c_str())); + return true; + case FieldDescriptor::TYPE_UINT64: + reflection->SetUInt64(message, field, atol(field_value.c_str())); + return true; + case FieldDescriptor::TYPE_INT32: + reflection->SetInt32(message, field, atoi(field_value.c_str())); + return true; + case FieldDescriptor::TYPE_UINT32: + reflection->SetUInt32(message, field, atoi(field_value.c_str())); + return true; + default: + // Add new scalar types + return false; + } +} + // ================================================================================ status_t ReverseParser::Parse(const int in, const int out) const { @@ -51,31 +80,6 @@ status_t ReverseParser::Parse(const int in, const int out) const // ================================================================================ static const string KERNEL_WAKEUP_LINE_DELIMITER = "\t"; -static void SetWakeupSourceField(WakeupSourceProto* source, string name, string value) { - if (name == "name") { - source->set_name(value.c_str()); - } else if (name == "active_count") { - source->set_active_count(atoi(value.c_str())); - } else if (name == "event_count") { - source->set_event_count(atoi(value.c_str())); - } else if (name == "wakeup_count") { - source->set_wakeup_count(atoi(value.c_str())); - } else if (name == "expire_count") { - source->set_expire_count(atoi(value.c_str())); - } else if (name == "active_count") { - source->set_active_since(atol(value.c_str())); - } else if (name == "total_time") { - source->set_total_time(atol(value.c_str())); - } else if (name == "max_time") { - source->set_max_time(atol(value.c_str())); - } else if (name == "last_change") { - source->set_last_change(atol(value.c_str())); - } else if (name == "prevent_suspend_time") { - source->set_prevent_suspend_time(atol(value.c_str())); - } - // add new fields -} - status_t KernelWakesParser::Parse(const int in, const int out) const { Reader reader(in); string line; @@ -90,12 +94,12 @@ status_t KernelWakesParser::Parse(const int in, const int out) const { if (line.empty()) continue; // parse head line if (nline++ == 0) { - split(line, header, KERNEL_WAKEUP_LINE_DELIMITER); + header = parseHeader(line, KERNEL_WAKEUP_LINE_DELIMITER); continue; } // parse for each record, the line delimiter is \t only! - split(line, record, KERNEL_WAKEUP_LINE_DELIMITER); + record = parseRecord(line, KERNEL_WAKEUP_LINE_DELIMITER); if (record.size() != header.size()) { // TODO: log this to incident report! @@ -105,7 +109,10 @@ status_t KernelWakesParser::Parse(const int in, const int out) const { WakeupSourceProto* source = proto.add_wakeup_sources(); for (int i=0; i<(int)record.size(); i++) { - SetWakeupSourceField(source, header[i], record[i]); + if (!SetTableField(source, header[i], record[i])) { + fprintf(stderr, "[%s]Line %d has bad value %s of %s\n", + this->name.string(), nline, header[i].c_str(), record[i].c_str()); + } } } @@ -123,32 +130,6 @@ status_t KernelWakesParser::Parse(const int in, const int out) const { } // ================================================================================ -// Remove K for numeric fields -static void SetProcessField(ProcessProto* process, string name, string value) { - ssize_t len = value.size(); - if (name == "PID") { - process->set_pid(atoi(value.c_str())); - } else if (name == "Vss") { - process->set_vss(atol(value.substr(0, len - 1).c_str())); - } else if (name == "Rss") { - process->set_rss(atol(value.substr(0, len - 1).c_str())); - } else if (name == "Pss") { - process->set_pss(atol(value.substr(0, len - 1).c_str())); - } else if (name == "Uss") { - process->set_uss(atol(value.substr(0, len - 1).c_str())); - } else if (name == "Swap") { - process->set_swap(atol(value.substr(0, len - 1).c_str())); - } else if (name == "PSwap") { - process->set_pswap(atol(value.substr(0, len - 1).c_str())); - } else if (name == "USwap") { - process->set_uswap(atol(value.substr(0, len - 1).c_str())); - } else if (name == "ZSwap") { - process->set_zswap(atol(value.substr(0, len - 1).c_str())); - } else if (name == "cmdline") { - process->set_cmdline(value); - } -} - status_t ProcrankParser::Parse(const int in, const int out) const { Reader reader(in); string line, content; @@ -164,22 +145,22 @@ status_t ProcrankParser::Parse(const int in, const int out) const { // parse head line if (nline++ == 0) { - split(line, header); + header = parseHeader(line); continue; } - split(line, record); + record = parseRecord(line); if (record.size() != header.size()) { if (record[record.size() - 1] == "TOTAL") { // TOTAL record ProcessProto* total = proto.mutable_summary()->mutable_total(); for (int i=1; i<=(int)record.size(); i++) { - SetProcessField(total, header[header.size() - i], record[record.size() - i]); + SetTableField(total, header[header.size() - i], record[record.size() - i]); } } else if (record[0] == "ZRAM:") { - split(line, record, ":"); + record = parseRecord(line, ":"); proto.mutable_summary()->mutable_zram()->set_raw_text(record[1]); } else if (record[0] == "RAM:") { - split(line, record, ":"); + record = parseRecord(line, ":"); proto.mutable_summary()->mutable_ram()->set_raw_text(record[1]); } else { fprintf(stderr, "[%s]Line %d has missing fields\n%s\n", this->name.string(), nline, @@ -190,7 +171,10 @@ status_t ProcrankParser::Parse(const int in, const int out) const { ProcessProto* process = proto.add_processes(); for (int i=0; i<(int)record.size(); i++) { - SetProcessField(process, header[i], record[i]); + if (!SetTableField(process, header[i], record[i])) { + fprintf(stderr, "[%s]Line %d has bad value %s of %s\n", + this->name.string(), nline, header[i].c_str(), record[i].c_str()); + } } } diff --git a/cmds/incident_helper/ih_util.cpp b/cmds/incident_helper/ih_util.cpp index bbb625f28c48..b2fda23ac391 100644 --- a/cmds/incident_helper/ih_util.cpp +++ b/cmds/incident_helper/ih_util.cpp @@ -23,16 +23,24 @@ const ssize_t BUFFER_SIZE = 16 * 1024; // 4KB -std::string trim(const std::string& s, const std::string& whitespace) { - const auto head = s.find_first_not_of(whitespace); + +static std::string trim(const std::string& s) { + const auto head = s.find_first_not_of(DEFAULT_WHITESPACE); if (head == std::string::npos) return ""; - const auto tail = s.find_last_not_of(whitespace); + const auto tail = s.find_last_not_of(DEFAULT_WHITESPACE); return s.substr(head, tail - head + 1); } +static std::string trimHeader(const std::string& s) { + std::string res = trim(s); + std::transform(res.begin(), res.end(), res.begin(), ::tolower); + return res; +} + // This is similiar to Split in android-base/file.h, but it won't add empty string -void split(const std::string& line, std::vector<std::string>& words, const std::string& delimiters) { +static void split(const std::string& line, std::vector<std::string>& words, + const trans_func& func, const std::string& delimiters) { words.clear(); // clear the buffer before split size_t base = 0; @@ -40,7 +48,7 @@ void split(const std::string& line, std::vector<std::string>& words, const std:: while (true) { found = line.find_first_of(delimiters, base); if (found != base) { - std::string word = trim(line.substr(base, found - base)); + std::string word = (*func) (line.substr(base, found - base)); if (!word.empty()) { words.push_back(word); } @@ -50,13 +58,18 @@ void split(const std::string& line, std::vector<std::string>& words, const std:: } } -bool assertHeaders(const char* expected[], const std::vector<std::string>& actual) { - for (size_t i = 0; i < actual.size(); i++) { - if (expected[i] == NULL || std::string(expected[i]) != actual[i]) { - return false; - } - } - return true; +header_t parseHeader(const std::string& line, const std::string& delimiters) { + header_t header; + trans_func f = &trimHeader; + split(line, header, f, delimiters); + return header; +} + +record_t parseRecord(const std::string& line, const std::string& delimiters) { + record_t record; + trans_func f = &trim; + split(line, record, f, delimiters); + return record; } Reader::Reader(const int fd) : Reader(fd, BUFFER_SIZE) {}; diff --git a/cmds/incident_helper/ih_util.h b/cmds/incident_helper/ih_util.h index 9e0c18ee7498..5598eed8d824 100644 --- a/cmds/incident_helper/ih_util.h +++ b/cmds/incident_helper/ih_util.h @@ -23,16 +23,13 @@ typedef std::vector<std::string> header_t; typedef std::vector<std::string> record_t; +typedef std::string (*trans_func) (const std::string&); const char DEFAULT_NEWLINE = '\n'; const std::string DEFAULT_WHITESPACE = " \t"; -std::string trim(const std::string& s, const std::string& whitespace = DEFAULT_WHITESPACE); - -void split(const std::string& line, std::vector<std::string>& words, - const std::string& delimiters = DEFAULT_WHITESPACE); - -bool assertHeaders(const char* expected[], const std::vector<std::string>& actual); +header_t parseHeader(const std::string& line, const std::string& delimiters = DEFAULT_WHITESPACE); +record_t parseRecord(const std::string& line, const std::string& delimiters = DEFAULT_WHITESPACE); /** * Reader class reads data from given fd in streaming fashion. diff --git a/cmds/incident_helper/tests/ih_util_test.cpp b/cmds/incident_helper/tests/ih_util_test.cpp index 5158e0a285bc..3b9ed403b77a 100644 --- a/cmds/incident_helper/tests/ih_util_test.cpp +++ b/cmds/incident_helper/tests/ih_util_test.cpp @@ -26,25 +26,38 @@ using namespace android::base; using namespace std; using ::testing::StrEq; -TEST(IhUtilTest, Trim) { - EXPECT_THAT(trim(" \t 100 00\toooh \t wqrw "), StrEq("100 00\toooh \t wqrw")); - EXPECT_THAT(trim(" \t 100 00\toooh \t wqrw ", " "), StrEq("\t 100 00\toooh \t wqrw")); +TEST(IhUtilTest, ParseHeader) { + header_t result, expected; + result = parseHeader(" \t \t\t "); + EXPECT_EQ(expected, result); + + result = parseHeader(" \t 100 00\tOpQ \t wqrw"); + expected = { "100", "00", "opq", "wqrw" }; + EXPECT_EQ(expected, result); + + result = parseHeader(" \t 100 00\toooh \t wTF", "\t"); + expected = { "100 00", "oooh", "wtf" }; + EXPECT_EQ(expected, result); + + result = parseHeader("123,456,78_9", ","); + expected = { "123", "456", "78_9" }; + EXPECT_EQ(expected, result); } -TEST(IhUtilTest, Split) { - vector<string> result, expected; - split(" \t \t\t ", result); +TEST(IhUtilTest, ParseRecord) { + record_t result, expected; + result = parseRecord(" \t \t\t "); EXPECT_EQ(expected, result); - split(" \t 100 00\toooh \t wqrw", result); + result = parseRecord(" \t 100 00\toooh \t wqrw"); expected = { "100", "00", "oooh", "wqrw" }; EXPECT_EQ(expected, result); - split(" \t 100 00\toooh \t wqrw", result, "\t"); + result = parseRecord(" \t 100 00\toooh \t wqrw", "\t"); expected = { "100 00", "oooh", "wqrw" }; EXPECT_EQ(expected, result); - split("123,456,78_9", result, ","); + result = parseRecord("123,456,78_9", ","); expected = { "123", "456", "78_9" }; EXPECT_EQ(expected, result); } diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp index 9cc47ed4899a..0f6f38edf3c4 100644 --- a/cmds/incidentd/src/Section.cpp +++ b/cmds/incidentd/src/Section.cpp @@ -330,11 +330,13 @@ WorkerThreadSection::Execute(ReportRequestSet* requests) const void CommandSection::init(const char* command, va_list args) { va_list copied_args; - va_copy(copied_args, args); int numOfArgs = 0; - while(va_arg(args, const char*) != NULL) { + + va_copy(copied_args, args); + while(va_arg(copied_args, const char*) != NULL) { numOfArgs++; } + va_end(copied_args); // allocate extra 1 for command and 1 for NULL terminator mCommand = (const char**)malloc(sizeof(const char*) * (numOfArgs + 2)); @@ -342,13 +344,12 @@ void CommandSection::init(const char* command, va_list args) mCommand[0] = command; name = command; for (int i=0; i<numOfArgs; i++) { - const char* arg = va_arg(copied_args, const char*); + const char* arg = va_arg(args, const char*); mCommand[i+1] = arg; name += " "; name += arg; } mCommand[numOfArgs+1] = NULL; - va_end(copied_args); } CommandSection::CommandSection(int id, const int64_t timeoutMs, const char* command, ...) diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 0cec496fa264..c5c6b378bb74 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -16,12 +16,18 @@ package android.view; +import static android.view.DisplayInfoProto.APP_HEIGHT; +import static android.view.DisplayInfoProto.APP_WIDTH; +import static android.view.DisplayInfoProto.LOGICAL_HEIGHT; +import static android.view.DisplayInfoProto.LOGICAL_WIDTH; + import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; import android.util.DisplayMetrics; +import android.util.proto.ProtoOutputStream; import libcore.util.Objects; @@ -654,6 +660,22 @@ public final class DisplayInfo implements Parcelable { return sb.toString(); } + /** + * Write to a protocol buffer output stream. + * Protocol buffer message definition at {@link android.view.DisplayInfoProto} + * + * @param protoOutputStream Stream to write the Rect object to. + * @param fieldId Field Id of the DisplayInfoProto as defined in the parent message + */ + public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) { + final long token = protoOutputStream.start(fieldId); + protoOutputStream.write(LOGICAL_WIDTH, logicalWidth); + protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight); + protoOutputStream.write(APP_WIDTH, appWidth); + protoOutputStream.write(APP_HEIGHT, appHeight); + protoOutputStream.end(token); + } + private static String flagsToString(int flags) { StringBuilder result = new StringBuilder(); if ((flags & Display.FLAG_SECURE) != 0) { diff --git a/core/java/android/view/IApplicationToken.aidl b/core/java/android/view/IApplicationToken.aidl index b01c0ef55812..a063a70a3181 100644 --- a/core/java/android/view/IApplicationToken.aidl +++ b/core/java/android/view/IApplicationToken.aidl @@ -20,5 +20,6 @@ package android.view; /** {@hide} */ interface IApplicationToken { + String getName(); } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 1e50a85833ec..fe50a6484ba8 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -34,6 +34,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; +import android.util.proto.ProtoOutputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -2545,6 +2546,15 @@ public interface WindowManager extends ViewManager { } /** + * @hide + */ + public void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(WindowLayoutParamsProto.TYPE, type); + proto.end(token); + } + + /** * Scale the layout params' coordinates and size. * @hide */ diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 49b7ed8bac0e..d2eb7850b6ab 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -77,6 +77,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import android.view.animation.Animation; import com.android.internal.policy.IKeyguardDismissCallback; @@ -1646,6 +1647,14 @@ public interface WindowManagerPolicy { public void dump(String prefix, PrintWriter writer, String[] args); /** + * Write the WindowManagerPolicy's state into the protocol buffer. + * The message is described in {@link com.android.server.wm.proto.WindowManagerPolicyProto} + * + * @param proto The protocol buffer output stream to write to. + */ + void writeToProto(ProtoOutputStream proto, long fieldId); + + /** * Returns whether a given window type can be magnified. * * @param windowType The window type. diff --git a/core/proto/android/graphics/rect.proto b/core/proto/android/graphics/rect.proto new file mode 100644 index 000000000000..a65d33185e34 --- /dev/null +++ b/core/proto/android/graphics/rect.proto @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2017 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. + */ + +syntax = "proto3"; + +package android.graphics; + +option java_multiple_files = true; + +message RectProto { + int32 left = 1; + int32 top = 2; + int32 right = 3; + int32 bottom = 4; +} + diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto new file mode 100644 index 000000000000..7fb48028494d --- /dev/null +++ b/core/proto/android/server/windowmanagerservice.proto @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2017 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. + */ + +syntax = "proto3"; + +import "frameworks/base/core/proto/android/graphics/rect.proto"; +import "frameworks/base/core/proto/android/view/displayinfo.proto"; +import "frameworks/base/core/proto/android/view/windowlayoutparams.proto"; + +package com.android.server.wm.proto; + +option java_multiple_files = true; + +message WindowManagerServiceProto { + WindowManagerPolicyProto policy = 1; + /* window manager hierarchy structure */ + repeated DisplayProto displays = 2; + /* window references in top down z order */ + repeated IdentifierProto windows = 3; + IdentifierProto focused_window = 4; + string focused_app = 5; + IdentifierProto input_method_window = 6; + bool display_frozen = 7; + int32 rotation = 8; + int32 last_orientation = 9; + AppTransitionProto app_transition = 10; +} + +/* represents PhoneWindowManager */ +message WindowManagerPolicyProto { + .android.graphics.RectProto stable_bounds = 1; +} + +/* represents AppTransition */ +message AppTransitionProto { + enum AppState { + APP_STATE_IDLE = 0; + APP_STATE_READY = 1; + APP_STATE_RUNNING = 2; + APP_STATE_TIMEOUT = 3; + } + AppState app_transition_state = 1; + /* definitions for constants found in {@link com.android.server.wm.AppTransition} */ + enum TransitionType { + TRANSIT_NONE = 0; + TRANSIT_UNSET = -1; + TRANSIT_ACTIVITY_OPEN = 6; + TRANSIT_ACTIVITY_CLOSE = 7; + TRANSIT_TASK_OPEN = 8; + TRANSIT_TASK_CLOSE = 9; + TRANSIT_TASK_TO_FRONT = 10; + TRANSIT_TASK_TO_BACK = 11; + TRANSIT_WALLPAPER_CLOSE = 12; + TRANSIT_WALLPAPER_OPEN = 13; + TRANSIT_WALLPAPER_INTRA_OPEN = 14; + TRANSIT_WALLPAPER_INTRA_CLOSE = 15; + TRANSIT_TASK_OPEN_BEHIND = 16; + TRANSIT_TASK_IN_PLACE = 17; + TRANSIT_ACTIVITY_RELAUNCH = 18; + TRANSIT_DOCK_TASK_FROM_RECENTS = 19; + TRANSIT_KEYGUARD_GOING_AWAY = 20; + TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21; + TRANSIT_KEYGUARD_OCCLUDE = 22; + TRANSIT_KEYGUARD_UNOCCLUDE = 23; + } + TransitionType last_used_app_transition = 2; +} + +/* represents DisplayContent */ +message DisplayProto { + int32 id = 1; + repeated StackProto stacks = 2; + DockedStackDividerControllerProto docked_stack_divider_controller = 3; + PinnedStackControllerProto pinned_stack_controller = 4; + /* non app windows */ + repeated WindowTokenProto above_app_windows = 5; + repeated WindowTokenProto below_app_windows = 6; + repeated WindowTokenProto ime_windows = 7; + int32 dpi = 8; + .android.view.DisplayInfoProto display_info = 9; +} + + +/* represents DockedStackDividerController */ +message DockedStackDividerControllerProto { + bool minimized_dock = 1; +} + +/* represents PinnedStackController */ +message PinnedStackControllerProto { + .android.graphics.RectProto default_bounds = 1; + .android.graphics.RectProto movement_bounds = 2; +} + +/* represents TaskStack */ +message StackProto { + int32 id = 1; + repeated TaskProto tasks = 2; + bool fills_parent = 3; + .android.graphics.RectProto bounds = 4; + bool animation_background_surface_is_dimming = 5; +} + +/* represents Task */ +message TaskProto { + int32 id = 1; + repeated AppWindowTokenProto app_window_tokens = 2; + bool fills_parent = 3; + .android.graphics.RectProto bounds = 4; + .android.graphics.RectProto temp_inset_bounds = 5; +} + +/* represents AppWindowToken */ +message AppWindowTokenProto { + /* obtained from ActivityRecord */ + string name = 1; + WindowTokenProto window_token = 2; +} + +/* represents WindowToken */ +message WindowTokenProto { + int32 hash_code = 1; + repeated WindowStateProto windows = 2; +} + +/* represents WindowState */ +message WindowStateProto { + IdentifierProto identifier = 1; + int32 display_id = 2; + int32 stack_id = 3; + .android.view.WindowLayoutParamsProto attributes = 4; + .android.graphics.RectProto given_content_insets = 5; + .android.graphics.RectProto frame = 6; + .android.graphics.RectProto containing_frame = 7; + .android.graphics.RectProto parent_frame = 8; + .android.graphics.RectProto content_frame = 9; + .android.graphics.RectProto content_insets = 10; + .android.graphics.RectProto surface_insets = 11; + WindowStateAnimatorProto animator = 12; + bool animating_exit = 13; + repeated WindowStateProto child_windows = 14; +} + +message IdentifierProto { + int32 hash_code = 1; + int32 user_id = 2; + string title = 3; +} + +/* represents WindowStateAnimator */ +message WindowStateAnimatorProto { + .android.graphics.RectProto last_clip_rect = 1; + WindowSurfaceControllerProto surface = 2; +} + +/* represents WindowSurfaceController */ +message WindowSurfaceControllerProto { + bool shown = 1; + int32 layer = 2; +}
\ No newline at end of file diff --git a/core/proto/android/view/displayinfo.proto b/core/proto/android/view/displayinfo.proto new file mode 100644 index 000000000000..858386852f59 --- /dev/null +++ b/core/proto/android/view/displayinfo.proto @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2017 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. + */ + +syntax = "proto3"; + +package android.view; + +option java_multiple_files = true; + +/* represents DisplayInfo */ +message DisplayInfoProto { + int32 logical_width = 1; + int32 logical_height = 2; + int32 app_width = 3; + int32 app_height = 4; +} diff --git a/core/proto/android/view/windowlayoutparams.proto b/core/proto/android/view/windowlayoutparams.proto new file mode 100644 index 000000000000..5bb84dceade8 --- /dev/null +++ b/core/proto/android/view/windowlayoutparams.proto @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 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. + */ + +syntax = "proto3"; + +package android.view; + +option java_multiple_files = true; + +/* represents WindowManager.LayoutParams */ +message WindowLayoutParamsProto { + int32 type = 1; +} diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index deafb6638ece..3dc928de60df 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -21,6 +21,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import android.util.proto.ProtoOutputStream; import java.io.PrintWriter; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -194,7 +195,24 @@ public final class Rect implements Parcelable { pw.print(top); pw.print("]["); pw.print(right); pw.print(','); pw.print(bottom); pw.print(']'); } - + + /** + * Write to a protocol buffer output stream. + * Protocol buffer message definition at {@link android.graphics.RectProto} + * + * @param protoOutputStream Stream to write the Rect object to. + * @param fieldId Field Id of the Rect as defined in the parent message + * @hide + */ + public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) { + final long token = protoOutputStream.start(fieldId); + protoOutputStream.write(RectProto.LEFT, left); + protoOutputStream.write(RectProto.TOP, top); + protoOutputStream.write(RectProto.RIGHT, right); + protoOutputStream.write(RectProto.BOTTOM, bottom); + protoOutputStream.end(token); + } + /** * Returns true if the rectangle is empty (left >= right or top >= bottom) */ diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index df70a93a541f..539faf3f72f5 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -749,9 +749,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo static class Token extends IApplicationToken.Stub { private final WeakReference<ActivityRecord> weakActivity; + private final String name; - Token(ActivityRecord activity) { + Token(ActivityRecord activity, Intent intent) { weakActivity = new WeakReference<>(activity); + name = intent.getComponent().flattenToShortString(); } private static ActivityRecord tokenToActivityRecordLocked(Token token) { @@ -775,6 +777,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo sb.append('}'); return sb.toString(); } + + @Override + public String getName() { + return name; + } } static ActivityRecord forTokenLocked(IBinder token) { @@ -798,7 +805,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo ActivityStackSupervisor supervisor, ActivityOptions options, ActivityRecord sourceRecord) { service = _service; - appToken = new Token(this); + appToken = new Token(this, _intent); info = aInfo; launchedFromPid = _launchedFromPid; launchedFromUid = _launchedFromUid; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index ae78d7c551c1..2f01f8b39dd6 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -115,6 +115,8 @@ import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT; import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED; import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN; +import static com.android.server.wm.proto.WindowManagerPolicyProto.STABLE_BOUNDS; + import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManager.StackId; @@ -194,6 +196,7 @@ import android.util.LongSparseArray; import android.util.MutableBoolean; import android.util.Slog; import android.util.SparseArray; +import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.Gravity; import android.view.HapticFeedbackConstants; @@ -8218,6 +8221,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override + public void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + new Rect(mStableLeft, mStableTop, mStableRight, mStableBottom).writeToProto(proto, + STABLE_BOUNDS); + proto.end(token); + } + + @Override public void dump(String prefix, PrintWriter pw, String[] args) { pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode); pw.print(" mSystemReady="); pw.print(mSystemReady); diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index cda3efdf886f..c19ede0c0f4c 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -47,6 +47,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM; +import static com.android.server.wm.proto.AppTransitionProto.APP_TRANSITION_STATE; +import static com.android.server.wm.proto.AppTransitionProto.LAST_USED_APP_TRANSITION; import android.annotation.Nullable; import android.app.ActivityManager; @@ -65,6 +67,7 @@ import android.os.SystemProperties; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; +import android.util.proto.ProtoOutputStream; import android.view.AppTransitionAnimationSpec; import android.view.IAppTransitionAnimationSpecsFuture; import android.view.WindowManager; @@ -1975,6 +1978,13 @@ public class AppTransition implements Dump { } } + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(APP_TRANSITION_STATE, mAppTransitionState); + proto.write(LAST_USED_APP_TRANSITION, mLastUsedAppTransition); + proto.end(token); + } + @Override public void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.println(this); diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 2e4de8c58650..505b4c494f2c 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -49,6 +49,8 @@ import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowManagerService.logWithStack; +import static com.android.server.wm.proto.AppWindowTokenProto.NAME; +import static com.android.server.wm.proto.AppWindowTokenProto.WINDOW_TOKEN; import android.annotation.NonNull; import android.app.Activity; @@ -57,8 +59,10 @@ import android.graphics.Rect; import android.os.Binder; import android.os.Debug; import android.os.IBinder; +import android.os.RemoteException; import android.os.SystemClock; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import android.view.IApplicationToken; import android.view.SurfaceControl; import android.view.WindowManager; @@ -1746,6 +1750,26 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } @Override + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + writeNameToProto(proto, NAME); + super.writeToProto(proto, WINDOW_TOKEN); + proto.end(token); + } + + void writeNameToProto(ProtoOutputStream proto, long fieldId) { + if (appToken == null) { + return; + } + try { + proto.write(fieldId, appToken.getName()); + } catch (RemoteException e) { + // This shouldn't happen, but in this case fall back to outputting nothing + Slog.e(TAG, e.toString()); + } + } + + @Override public String toString() { if (stringName == null) { StringBuilder sb = new StringBuilder(); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 465ca86d5c0a..cfafe2556e65 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -97,6 +97,15 @@ import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP; import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW; import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE; +import static com.android.server.wm.proto.DisplayProto.ABOVE_APP_WINDOWS; +import static com.android.server.wm.proto.DisplayProto.BELOW_APP_WINDOWS; +import static com.android.server.wm.proto.DisplayProto.DISPLAY_INFO; +import static com.android.server.wm.proto.DisplayProto.DOCKED_STACK_DIVIDER_CONTROLLER; +import static com.android.server.wm.proto.DisplayProto.DPI; +import static com.android.server.wm.proto.DisplayProto.ID; +import static com.android.server.wm.proto.DisplayProto.IME_WINDOWS; +import static com.android.server.wm.proto.DisplayProto.PINNED_STACK_CONTROLLER; +import static com.android.server.wm.proto.DisplayProto.STACKS; import android.annotation.NonNull; import android.app.ActivityManager.StackId; @@ -118,6 +127,7 @@ import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.MutableBoolean; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.DisplayInfo; import android.view.InputDevice; @@ -2099,6 +2109,32 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(ID, mDisplayId); + for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) { + final TaskStack stack = mTaskStackContainers.get(stackNdx); + stack.writeToProto(proto, STACKS); + } + mDividerControllerLocked.writeToProto(proto, DOCKED_STACK_DIVIDER_CONTROLLER); + mPinnedStackControllerLocked.writeToProto(proto, PINNED_STACK_CONTROLLER); + for (int i = mAboveAppWindowsContainers.size() - 1; i >= 0; --i) { + final WindowToken windowToken = mAboveAppWindowsContainers.get(i); + windowToken.writeToProto(proto, ABOVE_APP_WINDOWS); + } + for (int i = mBelowAppWindowsContainers.size() - 1; i >= 0; --i) { + final WindowToken windowToken = mBelowAppWindowsContainers.get(i); + windowToken.writeToProto(proto, BELOW_APP_WINDOWS); + } + for (int i = mImeWindowsContainers.size() - 1; i >= 0; --i) { + final WindowToken windowToken = mImeWindowsContainers.get(i); + windowToken.writeToProto(proto, IME_WINDOWS); + } + proto.write(DPI, mBaseDisplayDensity); + mDisplayInfo.writeToProto(proto, DISPLAY_INFO); + proto.end(token); + } + public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); final String subPrefix = " " + prefix; diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 6b514552b227..2b45d67120d9 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -34,6 +34,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED; import static com.android.server.wm.WindowManagerService.LAYER_OFFSET_DIM; +import static com.android.server.wm.proto.DockedStackDividerControllerProto.MINIMIZED_DOCK; import android.content.Context; import android.content.res.Configuration; @@ -42,6 +43,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.ArraySet; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; import android.view.IDockedStackListener; import android.view.animation.AnimationUtils; @@ -919,4 +921,10 @@ public class DockedStackDividerController implements DimLayerUser { mDimLayer.printTo(prefix + " ", pw); } } + + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(MINIMIZED_DOCK, mMinimizedDock); + proto.end(token); + } } diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java index 6d33ce2941bc..1e7140a12d01 100644 --- a/services/core/java/com/android/server/wm/PinnedStackController.java +++ b/services/core/java/com/android/server/wm/PinnedStackController.java @@ -21,6 +21,8 @@ import static android.util.TypedValue.COMPLEX_UNIT_DIP; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static com.android.server.wm.proto.PinnedStackControllerProto.DEFAULT_BOUNDS; +import static com.android.server.wm.proto.PinnedStackControllerProto.MOVEMENT_BOUNDS; import android.app.RemoteAction; import android.content.pm.ParceledListSlice; @@ -35,6 +37,7 @@ import android.util.Log; import android.util.Size; import android.util.Slog; import android.util.TypedValue; +import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; import android.view.Gravity; import android.view.IPinnedStackController; @@ -505,4 +508,12 @@ class PinnedStackController { pw.println(prefix + " ]"); } } + + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + getDefaultBounds().writeToProto(proto, DEFAULT_BOUNDS); + mService.getStackBounds(PINNED_STACK_ID, mTmpRect); + getMovementBounds(mTmpRect).writeToProto(proto, MOVEMENT_BOUNDS); + proto.end(token); + } } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index e83b792e2cf8..05ef1a5fe106 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -35,11 +35,11 @@ import android.provider.Settings; import android.util.EventLog; import android.util.Slog; import android.util.SparseIntArray; +import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.DisplayInfo; import android.view.WindowManager; -import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import com.android.server.EventLogTags; @@ -89,6 +89,8 @@ import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN; import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION; import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING; import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE; +import static com.android.server.wm.proto.WindowManagerServiceProto.DISPLAYS; +import static com.android.server.wm.proto.WindowManagerServiceProto.WINDOWS; /** Root {@link WindowContainer} for the device. */ class RootWindowContainer extends WindowContainer<DisplayContent> { @@ -1055,6 +1057,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { } } + void writeToProto(ProtoOutputStream proto) { + if (mService.mDisplayReady) { + final int count = mChildren.size(); + for (int i = 0; i < count; ++i) { + final DisplayContent displayContent = mChildren.get(i); + displayContent.writeToProto(proto, DISPLAYS); + } + } + forAllWindows((w) -> { + w.writeIdentifierToProto(proto, WINDOWS); + }, true); + } + @Override String getName() { return "ROOT"; diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index e5055e92828e..6349b0587efc 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -29,6 +29,11 @@ import static com.android.server.EventLogTags.WM_TASK_REMOVED; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static com.android.server.wm.proto.TaskProto.APP_WINDOW_TOKENS; +import static com.android.server.wm.proto.TaskProto.BOUNDS; +import static com.android.server.wm.proto.TaskProto.FILLS_PARENT; +import static com.android.server.wm.proto.TaskProto.ID; +import static com.android.server.wm.proto.TaskProto.TEMP_INSET_BOUNDS; import android.app.ActivityManager.StackId; import android.app.ActivityManager.TaskDescription; @@ -37,11 +42,11 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.util.EventLog; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; import android.view.Surface; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.wm.DimLayer.DimLayerUser; import java.io.PrintWriter; import java.util.function.Consumer; @@ -735,6 +740,19 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU return "Task=" + mTaskId; } + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(ID, mTaskId); + for (int i = mChildren.size() - 1; i >= 0; i--) { + final AppWindowToken appWindowToken = mChildren.get(i); + appWindowToken.writeToProto(proto, APP_WINDOW_TOKENS); + } + proto.write(FILLS_PARENT, mFillsParent); + mBounds.writeToProto(proto, BOUNDS); + mTempInsetBounds.writeToProto(proto, TEMP_INSET_BOUNDS); + proto.end(token); + } + public void dump(String prefix, PrintWriter pw) { final String doublePrefix = prefix + " "; diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 39878ccb07dd..474edaa34dbe 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -36,6 +36,11 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.LAYER_OFFSET_DIM; +import static com.android.server.wm.proto.StackProto.ANIMATION_BACKGROUND_SURFACE_IS_DIMMING; +import static com.android.server.wm.proto.StackProto.BOUNDS; +import static com.android.server.wm.proto.StackProto.FILLS_PARENT; +import static com.android.server.wm.proto.StackProto.ID; +import static com.android.server.wm.proto.StackProto.TASKS; import android.app.ActivityManager.StackId; import android.content.res.Configuration; @@ -45,6 +50,7 @@ import android.os.RemoteException; import android.util.EventLog; import android.util.Slog; import android.util.SparseArray; +import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; import android.view.Surface; @@ -52,7 +58,6 @@ import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; import com.android.server.EventLogTags; -import com.android.server.UiThread; import java.io.PrintWriter; @@ -1225,6 +1230,18 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye return mMinimizeAmount != 0f; } + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(ID, mStackId); + for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) { + mChildren.get(taskNdx).writeToProto(proto, TASKS); + } + proto.write(FILLS_PARENT, mFillsParent); + mBounds.writeToProto(proto, BOUNDS); + proto.write(ANIMATION_BACKGROUND_SURFACE_IS_DIMMING, mAnimationBackgroundSurface.isDimming()); + proto.end(token); + } + public void dump(String prefix, PrintWriter pw) { pw.println(prefix + "mStackId=" + mStackId); pw.println(prefix + "mDeferRemoval=" + mDeferRemoval); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5c664c2d16ce..1319ab93e4f1 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -102,6 +102,14 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSA import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static com.android.server.wm.proto.WindowManagerServiceProto.APP_TRANSITION; +import static com.android.server.wm.proto.WindowManagerServiceProto.DISPLAY_FROZEN; +import static com.android.server.wm.proto.WindowManagerServiceProto.FOCUSED_APP; +import static com.android.server.wm.proto.WindowManagerServiceProto.FOCUSED_WINDOW; +import static com.android.server.wm.proto.WindowManagerServiceProto.INPUT_METHOD_WINDOW; +import static com.android.server.wm.proto.WindowManagerServiceProto.LAST_ORIENTATION; +import static com.android.server.wm.proto.WindowManagerServiceProto.POLICY; +import static com.android.server.wm.proto.WindowManagerServiceProto.ROTATION; import android.Manifest; import android.Manifest.permission; @@ -175,6 +183,7 @@ import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.TypedValue; +import android.util.proto.ProtoOutputStream; import android.view.AppTransitionAnimationSpec; import android.view.Display; import android.view.DisplayInfo; @@ -6524,6 +6533,25 @@ public class WindowManagerService extends IWindowManager.Stub } } + private void writeToProtoLocked(ProtoOutputStream proto) { + mPolicy.writeToProto(proto, POLICY); + mRoot.writeToProto(proto); + if (mCurrentFocus != null) { + mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW); + } + if (mFocusedApp != null) { + mFocusedApp.writeNameToProto(proto, FOCUSED_APP); + } + if (mInputMethodWindow != null) { + mInputMethodWindow.writeIdentifierToProto(proto, INPUT_METHOD_WINDOW); + } + proto.write(DISPLAY_FROZEN, mDisplayFrozen); + final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked(); + proto.write(ROTATION, defaultDisplayContent.getRotation()); + proto.write(LAST_ORIENTATION, defaultDisplayContent.getLastOrientation()); + mAppTransition.writeToProto(proto, APP_TRANSITION); + } + private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) { pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)"); @@ -6798,6 +6826,7 @@ public class WindowManagerService extends IWindowManager.Stub if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; boolean dumpAll = false; + boolean useProto = false; int opti = 0; while (opti < args.length) { @@ -6808,6 +6837,8 @@ public class WindowManagerService extends IWindowManager.Stub opti++; if ("-a".equals(opt)) { dumpAll = true; + } else if ("--proto".equals(opt)) { + useProto = true; } else if ("-h".equals(opt)) { pw.println("Window manager dump options:"); pw.println(" [-a] [-h] [cmd] ..."); @@ -6827,12 +6858,21 @@ public class WindowManagerService extends IWindowManager.Stub pw.println(" \"visible\" for the visible windows."); pw.println(" \"visible-apps\" for the visible app windows."); pw.println(" -a: include all available server state."); + pw.println(" --proto: output dump in protocol buffer format."); return; } else { pw.println("Unknown argument: " + opt + "; use -h for help"); } } + if (useProto) { + final ProtoOutputStream proto = new ProtoOutputStream(fd); + synchronized (mWindowMap) { + writeToProtoLocked(proto); + } + proto.flush(); + return; + } // Is the caller requesting to dump a particular piece of data? if (opti < args.length) { String cmd = args[opti]; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 12abe39b082b..31b723fb06f9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -102,6 +102,23 @@ import static com.android.server.wm.WindowStateAnimator.COMMIT_DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW; +import static com.android.server.wm.proto.IdentifierProto.HASH_CODE; +import static com.android.server.wm.proto.IdentifierProto.TITLE; +import static com.android.server.wm.proto.IdentifierProto.USER_ID; +import static com.android.server.wm.proto.WindowStateProto.ANIMATING_EXIT; +import static com.android.server.wm.proto.WindowStateProto.ANIMATOR; +import static com.android.server.wm.proto.WindowStateProto.ATTRIBUTES; +import static com.android.server.wm.proto.WindowStateProto.CHILD_WINDOWS; +import static com.android.server.wm.proto.WindowStateProto.CONTAINING_FRAME; +import static com.android.server.wm.proto.WindowStateProto.CONTENT_FRAME; +import static com.android.server.wm.proto.WindowStateProto.CONTENT_INSETS; +import static com.android.server.wm.proto.WindowStateProto.DISPLAY_ID; +import static com.android.server.wm.proto.WindowStateProto.FRAME; +import static com.android.server.wm.proto.WindowStateProto.GIVEN_CONTENT_INSETS; +import static com.android.server.wm.proto.WindowStateProto.IDENTIFIER; +import static com.android.server.wm.proto.WindowStateProto.PARENT_FRAME; +import static com.android.server.wm.proto.WindowStateProto.STACK_ID; +import static com.android.server.wm.proto.WindowStateProto.SURFACE_INSETS; import android.app.AppOpsManager; import android.content.Context; @@ -125,6 +142,7 @@ import android.util.MergedConfiguration; import android.util.DisplayMetrics; import android.util.Slog; import android.util.TimeUtils; +import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; import android.view.Gravity; import android.view.IApplicationToken; @@ -3390,6 +3408,38 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP || (isChildWindow() && getParentWindow().isDockedResizing()); } + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + writeIdentifierToProto(proto, IDENTIFIER); + proto.write(DISPLAY_ID, getDisplayId()); + proto.write(STACK_ID, getStackId()); + mAttrs.writeToProto(proto, ATTRIBUTES); + mGivenContentInsets.writeToProto(proto, GIVEN_CONTENT_INSETS); + mFrame.writeToProto(proto, FRAME); + mContainingFrame.writeToProto(proto, CONTAINING_FRAME); + mParentFrame.writeToProto(proto, PARENT_FRAME); + mContentFrame.writeToProto(proto, CONTENT_FRAME); + mContentInsets.writeToProto(proto, CONTENT_INSETS); + mAttrs.surfaceInsets.writeToProto(proto, SURFACE_INSETS); + mWinAnimator.writeToProto(proto, ANIMATOR); + proto.write(ANIMATING_EXIT, mAnimatingExit); + for (int i = 0; i < mChildren.size(); i++) { + mChildren.get(i).writeToProto(proto, CHILD_WINDOWS); + } + proto.end(token); + } + + void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(HASH_CODE, System.identityHashCode(this)); + proto.write(USER_ID, UserHandle.getUserId(mOwnerUid)); + final CharSequence title = getWindowTag(); + if (title != null) { + proto.write(TITLE, title.toString()); + } + proto.end(token); + } + void dump(PrintWriter pw, String prefix, boolean dumpAll) { final TaskStack stack = getStack(); pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId()); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 86265c297b1b..67cb3a0bbefe 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -46,6 +46,8 @@ import static com.android.server.wm.WindowManagerService.localLOGV; import static com.android.server.wm.WindowManagerService.logWithStack; import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN; +import static com.android.server.wm.proto.WindowStateAnimatorProto.LAST_CLIP_RECT; +import static com.android.server.wm.proto.WindowStateAnimatorProto.SURFACE; import android.content.Context; import android.graphics.Matrix; @@ -57,6 +59,7 @@ import android.graphics.Region; import android.os.Debug; import android.os.Trace; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; import android.view.MagnificationSpec; import android.view.Surface.OutOfResourcesException; @@ -1885,6 +1888,15 @@ class WindowStateAnimator { mAnimation = newAnimation; } + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + mLastClipRect.writeToProto(proto, LAST_CLIP_RECT); + if (mSurfaceController != null) { + mSurfaceController.writeToProto(proto, SURFACE); + } + proto.end(token); + } + public void dump(PrintWriter pw, String prefix, boolean dumpAll) { if (mAnimating || mLocalAnimating || mAnimationIsEntrance || mAnimation != null) { diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 110d5cb90f45..2e1e3f763a15 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -17,6 +17,8 @@ package com.android.server.wm; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; +import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW; + import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; @@ -24,7 +26,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW; +import static com.android.server.wm.proto.WindowSurfaceControllerProto.LAYER; +import static com.android.server.wm.proto.WindowSurfaceControllerProto.SHOWN; import android.graphics.Point; import android.graphics.PointF; @@ -33,6 +36,7 @@ import android.graphics.Region; import android.os.IBinder; import android.os.Debug; import android.os.Trace; +import android.util.proto.ProtoOutputStream; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceSession; @@ -534,6 +538,12 @@ class WindowSurfaceController { return mSurfaceH; } + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(SHOWN, mSurfaceShown); + proto.write(LAYER, mSurfaceLayer); + proto.end(token); + } public void dump(PrintWriter pw, String prefix, boolean dumpAll) { if (dumpAll) { diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index e3033c9c01a8..b3561c04380b 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -16,9 +16,9 @@ package com.android.server.wm; +import android.util.proto.ProtoOutputStream; import java.util.Comparator; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; @@ -26,6 +26,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; +import static com.android.server.wm.proto.WindowTokenProto.HASH_CODE; +import static com.android.server.wm.proto.WindowTokenProto.WINDOWS; import android.os.Debug; import android.os.IBinder; @@ -261,6 +263,16 @@ class WindowToken extends WindowContainer<WindowState> { super.onDisplayChanged(dc); } + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(HASH_CODE, System.identityHashCode(this)); + for (int i = 0; i < mChildren.size(); i++) { + final WindowState w = mChildren.get(i); + w.writeToProto(proto, WINDOWS); + } + proto.end(token); + } + void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.print("windows="); pw.println(mChildren); pw.print(prefix); pw.print("windowType="); pw.print(windowType); diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java index 95adc9cd5a1a..9f57f4993ed5 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; import android.os.PowerSaveState; +import android.util.proto.ProtoOutputStream; import org.mockito.invocation.InvocationOnMock; import android.annotation.Nullable; @@ -596,6 +597,11 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { } @Override + public void writeToProto(ProtoOutputStream proto, long fieldId) { + + } + + @Override public void dump(String prefix, PrintWriter writer, String[] args) { } diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java index 7ff1110e00f7..40c79bbb183d 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java @@ -92,7 +92,9 @@ public class WindowTestUtils { boolean mOnTop = false; TestAppWindowToken(DisplayContent dc) { - super(dc.mService, new IApplicationToken.Stub() {}, false, dc, true /* fillsParent */, + super(dc.mService, new IApplicationToken.Stub() { + public String getName() {return null;} + }, false, dc, true /* fillsParent */, null /* overrideConfig */, null /* bounds */); } @@ -287,6 +289,10 @@ public class WindowTestUtils { public IBinder asBinder() { return mBinder; } + @Override + public String getName() { + return null; + } } /** Used to track resize reports. */ |