summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/incident_helper/IncidentHelper.cpp104
-rw-r--r--cmds/incident_helper/ih_util.cpp37
-rw-r--r--cmds/incident_helper/ih_util.h9
-rw-r--r--cmds/incident_helper/tests/ih_util_test.cpp31
-rw-r--r--cmds/incidentd/src/Section.cpp9
-rw-r--r--core/java/android/view/DisplayInfo.java22
-rw-r--r--core/java/android/view/IApplicationToken.aidl1
-rw-r--r--core/java/android/view/WindowManager.java10
-rw-r--r--core/java/android/view/WindowManagerPolicy.java9
-rw-r--r--core/proto/android/graphics/rect.proto29
-rw-r--r--core/proto/android/server/windowmanagerservice.proto173
-rw-r--r--core/proto/android/view/displayinfo.proto29
-rw-r--r--core/proto/android/view/windowlayoutparams.proto26
-rw-r--r--graphics/java/android/graphics/Rect.java20
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java11
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java11
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java10
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java24
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java36
-rw-r--r--services/core/java/com/android/server/wm/DockedStackDividerController.java8
-rw-r--r--services/core/java/com/android/server/wm/PinnedStackController.java11
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java17
-rw-r--r--services/core/java/com/android/server/wm/Task.java20
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java19
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java40
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java50
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java8
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. */