Add a probe to read the display state at the start of a trace

(in case it does not change during the trace)

Bug: 152194759
Change-Id: I4d19cbda91e99dc67d338b206145f5a57a150166
diff --git a/Android.bp b/Android.bp
index b3c79cf..bd4ce93 100644
--- a/Android.bp
+++ b/Android.bp
@@ -325,6 +325,7 @@
     ":perfetto_src_traced_probes_filesystem_filesystem",
     ":perfetto_src_traced_probes_ftrace_format_parser",
     ":perfetto_src_traced_probes_ftrace_ftrace",
+    ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
     ":perfetto_src_traced_probes_metatrace_metatrace",
     ":perfetto_src_traced_probes_packages_list_packages_list",
     ":perfetto_src_traced_probes_power_power",
@@ -825,6 +826,7 @@
     ":perfetto_src_traced_probes_filesystem_filesystem",
     ":perfetto_src_traced_probes_ftrace_format_parser",
     ":perfetto_src_traced_probes_ftrace_ftrace",
+    ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
     ":perfetto_src_traced_probes_metatrace_metatrace",
     ":perfetto_src_traced_probes_packages_list_packages_list",
     ":perfetto_src_traced_probes_power_power",
@@ -1069,6 +1071,7 @@
     ":perfetto_src_traced_probes_filesystem_filesystem",
     ":perfetto_src_traced_probes_ftrace_format_parser",
     ":perfetto_src_traced_probes_ftrace_ftrace",
+    ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
     ":perfetto_src_traced_probes_metatrace_metatrace",
     ":perfetto_src_traced_probes_packages_list_packages_list",
     ":perfetto_src_traced_probes_power_power",
@@ -1456,6 +1459,7 @@
     ":perfetto_src_traced_probes_ftrace_ftrace",
     ":perfetto_src_traced_probes_ftrace_integrationtests",
     ":perfetto_src_traced_probes_ftrace_test_support",
+    ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
     ":perfetto_src_traced_probes_metatrace_metatrace",
     ":perfetto_src_traced_probes_packages_list_packages_list",
     ":perfetto_src_traced_probes_power_power",
@@ -3195,6 +3199,7 @@
   srcs: [
     "protos/perfetto/trace/android/android_log.proto",
     "protos/perfetto/trace/android/graphics_frame_event.proto",
+    "protos/perfetto/trace/android/initial_display_state.proto",
     "protos/perfetto/trace/android/packages_list.proto",
   ],
   tools: [
@@ -3205,6 +3210,7 @@
   out: [
     "external/perfetto/protos/perfetto/trace/android/android_log.gen.cc",
     "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.gen.cc",
+    "external/perfetto/protos/perfetto/trace/android/initial_display_state.gen.cc",
     "external/perfetto/protos/perfetto/trace/android/packages_list.gen.cc",
   ],
 }
@@ -3215,6 +3221,7 @@
   srcs: [
     "protos/perfetto/trace/android/android_log.proto",
     "protos/perfetto/trace/android/graphics_frame_event.proto",
+    "protos/perfetto/trace/android/initial_display_state.proto",
     "protos/perfetto/trace/android/packages_list.proto",
   ],
   tools: [
@@ -3225,6 +3232,7 @@
   out: [
     "external/perfetto/protos/perfetto/trace/android/android_log.gen.h",
     "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.gen.h",
+    "external/perfetto/protos/perfetto/trace/android/initial_display_state.gen.h",
     "external/perfetto/protos/perfetto/trace/android/packages_list.gen.h",
   ],
   export_include_dirs: [
@@ -3239,6 +3247,7 @@
   srcs: [
     "protos/perfetto/trace/android/android_log.proto",
     "protos/perfetto/trace/android/graphics_frame_event.proto",
+    "protos/perfetto/trace/android/initial_display_state.proto",
     "protos/perfetto/trace/android/packages_list.proto",
   ],
   tools: [
@@ -3248,6 +3257,7 @@
   out: [
     "external/perfetto/protos/perfetto/trace/android/android_log.pb.cc",
     "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.cc",
+    "external/perfetto/protos/perfetto/trace/android/initial_display_state.pb.cc",
     "external/perfetto/protos/perfetto/trace/android/packages_list.pb.cc",
   ],
 }
@@ -3258,6 +3268,7 @@
   srcs: [
     "protos/perfetto/trace/android/android_log.proto",
     "protos/perfetto/trace/android/graphics_frame_event.proto",
+    "protos/perfetto/trace/android/initial_display_state.proto",
     "protos/perfetto/trace/android/packages_list.proto",
   ],
   tools: [
@@ -3267,6 +3278,7 @@
   out: [
     "external/perfetto/protos/perfetto/trace/android/android_log.pb.h",
     "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.h",
+    "external/perfetto/protos/perfetto/trace/android/initial_display_state.pb.h",
     "external/perfetto/protos/perfetto/trace/android/packages_list.pb.h",
   ],
   export_include_dirs: [
@@ -3281,6 +3293,7 @@
   srcs: [
     "protos/perfetto/trace/android/android_log.proto",
     "protos/perfetto/trace/android/graphics_frame_event.proto",
+    "protos/perfetto/trace/android/initial_display_state.proto",
     "protos/perfetto/trace/android/packages_list.proto",
   ],
   tools: [
@@ -3291,6 +3304,7 @@
   out: [
     "external/perfetto/protos/perfetto/trace/android/android_log.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc",
+    "external/perfetto/protos/perfetto/trace/android/initial_display_state.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/android/packages_list.pbzero.cc",
   ],
 }
@@ -3301,6 +3315,7 @@
   srcs: [
     "protos/perfetto/trace/android/android_log.proto",
     "protos/perfetto/trace/android/graphics_frame_event.proto",
+    "protos/perfetto/trace/android/initial_display_state.proto",
     "protos/perfetto/trace/android/packages_list.proto",
   ],
   tools: [
@@ -3311,6 +3326,7 @@
   out: [
     "external/perfetto/protos/perfetto/trace/android/android_log.pbzero.h",
     "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.h",
+    "external/perfetto/protos/perfetto/trace/android/initial_display_state.pbzero.h",
     "external/perfetto/protos/perfetto/trace/android/packages_list.pbzero.h",
   ],
   export_include_dirs: [
@@ -6965,6 +6981,22 @@
   ],
 }
 
+// GN: //src/traced/probes/initial_display_state:initial_display_state
+filegroup {
+  name: "perfetto_src_traced_probes_initial_display_state_initial_display_state",
+  srcs: [
+    "src/traced/probes/initial_display_state/initial_display_state_data_source.cc",
+  ],
+}
+
+// GN: //src/traced/probes/initial_display_state:unittests
+filegroup {
+  name: "perfetto_src_traced_probes_initial_display_state_unittests",
+  srcs: [
+    "src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc",
+  ],
+}
+
 // GN: //src/traced/probes/metatrace:metatrace
 filegroup {
   name: "perfetto_src_traced_probes_metatrace_metatrace",
@@ -7609,6 +7641,8 @@
     ":perfetto_src_traced_probes_ftrace_test_messages_zero_gen",
     ":perfetto_src_traced_probes_ftrace_test_support",
     ":perfetto_src_traced_probes_ftrace_unittests",
+    ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
+    ":perfetto_src_traced_probes_initial_display_state_unittests",
     ":perfetto_src_traced_probes_metatrace_metatrace",
     ":perfetto_src_traced_probes_packages_list_packages_list",
     ":perfetto_src_traced_probes_packages_list_unittests",
diff --git a/BUILD b/BUILD
index 6d507fa..da44927 100644
--- a/BUILD
+++ b/BUILD
@@ -177,6 +177,7 @@
         ":src_traced_probes_filesystem_filesystem",
         ":src_traced_probes_ftrace_format_parser",
         ":src_traced_probes_ftrace_ftrace",
+        ":src_traced_probes_initial_display_state_initial_display_state",
         ":src_traced_probes_metatrace_metatrace",
         ":src_traced_probes_packages_list_packages_list",
         ":src_traced_probes_power_power",
@@ -1156,6 +1157,15 @@
     ],
 )
 
+# GN target: //src/traced/probes/initial_display_state:initial_display_state
+filegroup(
+    name = "src_traced_probes_initial_display_state_initial_display_state",
+    srcs = [
+        "src/traced/probes/initial_display_state/initial_display_state_data_source.cc",
+        "src/traced/probes/initial_display_state/initial_display_state_data_source.h",
+    ],
+)
+
 # GN target: //src/traced/probes/metatrace:metatrace
 filegroup(
     name = "src_traced_probes_metatrace_metatrace",
@@ -2051,6 +2061,7 @@
     srcs = [
         "protos/perfetto/trace/android/android_log.proto",
         "protos/perfetto/trace/android/graphics_frame_event.proto",
+        "protos/perfetto/trace/android/initial_display_state.proto",
         "protos/perfetto/trace/android/packages_list.proto",
     ],
     visibility = [
diff --git a/protos/perfetto/trace/android/BUILD.gn b/protos/perfetto/trace/android/BUILD.gn
index 98163d6..a43e446 100644
--- a/protos/perfetto/trace/android/BUILD.gn
+++ b/protos/perfetto/trace/android/BUILD.gn
@@ -20,6 +20,7 @@
   sources = [
     "android_log.proto",
     "graphics_frame_event.proto",
+    "initial_display_state.proto",
     "packages_list.proto",
   ]
 }
diff --git a/protos/perfetto/trace/android/initial_display_state.proto b/protos/perfetto/trace/android/initial_display_state.proto
new file mode 100644
index 0000000..09c1b73
--- /dev/null
+++ b/protos/perfetto/trace/android/initial_display_state.proto
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package perfetto.protos;
+
+message InitialDisplayState {
+  // Same values as android.view.Display.STATE_*
+  optional int32 display_state = 1;
+  optional double brightness = 2;
+}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 2935bfd..abcd848 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -1573,6 +1573,16 @@
 
 // End of protos/perfetto/trace/android/graphics_frame_event.proto
 
+// Begin of protos/perfetto/trace/android/initial_display_state.proto
+
+message InitialDisplayState {
+  // Same values as android.view.Display.STATE_*
+  optional int32 display_state = 1;
+  optional double brightness = 2;
+}
+
+// End of protos/perfetto/trace/android/initial_display_state.proto
+
 // Begin of protos/perfetto/trace/android/packages_list.proto
 
 message PackagesList {
@@ -6716,7 +6726,7 @@
 // TracePacket(s).
 //
 // Next reserved id: 13 (up to 15).
-// Next id: 70.
+// Next id: 71.
 message TracePacket {
   // The timestamp of the TracePacket.
   // By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -6771,6 +6781,7 @@
     CpuInfo cpu_info = 67;
     SmapsPacket smaps_packet = 68;
     TracingServiceEvent service_event = 69;
+    InitialDisplayState initial_display_state = 70;
 
     // Only used in profile packets.
     ProfiledFrameSymbols profiled_frame_symbols = 55;
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 91a10ac..993b05c 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -20,6 +20,7 @@
 import "protos/perfetto/config/trace_config.proto";
 import "protos/perfetto/trace/android/android_log.proto";
 import "protos/perfetto/trace/android/graphics_frame_event.proto";
+import "protos/perfetto/trace/android/initial_display_state.proto";
 import "protos/perfetto/trace/android/packages_list.proto";
 import "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto";
 import "protos/perfetto/trace/chrome/chrome_metadata.proto";
@@ -61,7 +62,7 @@
 // TracePacket(s).
 //
 // Next reserved id: 13 (up to 15).
-// Next id: 70.
+// Next id: 71.
 message TracePacket {
   // The timestamp of the TracePacket.
   // By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -116,6 +117,7 @@
     CpuInfo cpu_info = 67;
     SmapsPacket smaps_packet = 68;
     TracingServiceEvent service_event = 69;
+    InitialDisplayState initial_display_state = 70;
 
     // Only used in profile packets.
     ProfiledFrameSymbols profiled_frame_symbols = 55;
diff --git a/src/traced/probes/BUILD.gn b/src/traced/probes/BUILD.gn
index a5d5cb0..7eec236 100644
--- a/src/traced/probes/BUILD.gn
+++ b/src/traced/probes/BUILD.gn
@@ -56,6 +56,7 @@
     "android_log",
     "common",
     "filesystem",
+    "initial_display_state",
     "metatrace",
     "packages_list",
     "power",
@@ -92,6 +93,7 @@
     "android_log:unittests",
     "common:unittests",
     "filesystem:unittests",
+    "initial_display_state:unittests",
     "packages_list:unittests",
     "ps:unittests",
     "sys_stats:unittests",
diff --git a/src/traced/probes/initial_display_state/BUILD.gn b/src/traced/probes/initial_display_state/BUILD.gn
new file mode 100644
index 0000000..ea71625
--- /dev/null
+++ b/src/traced/probes/initial_display_state/BUILD.gn
@@ -0,0 +1,45 @@
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../../gn/test.gni")
+
+source_set("initial_display_state") {
+  public_deps = [ "../../../tracing/core" ]
+  deps = [
+    "..:data_source",
+    "../../../../gn:default_deps",
+    "../../../../include/perfetto/ext/traced",
+    "../../../../protos/perfetto/trace:zero",
+    "../../../../protos/perfetto/trace/android:zero",
+    "../../../base",
+    "../common",
+  ]
+  sources = [
+    "initial_display_state_data_source.cc",
+    "initial_display_state_data_source.h",
+  ]
+}
+
+perfetto_unittest_source_set("unittests") {
+  testonly = true
+  deps = [
+    ":initial_display_state",
+    "../../../../gn:default_deps",
+    "../../../../gn:gtest_and_gmock",
+    "../../../../protos/perfetto/trace/android:cpp",
+    "../../../../src/tracing/test:test_support",
+    "../common:test_support",
+  ]
+  sources = [ "initial_display_state_data_source_unittest.cc" ]
+}
diff --git a/src/traced/probes/initial_display_state/initial_display_state_data_source.cc b/src/traced/probes/initial_display_state/initial_display_state_data_source.cc
new file mode 100644
index 0000000..5d3150e
--- /dev/null
+++ b/src/traced/probes/initial_display_state/initial_display_state_data_source.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/traced/probes/initial_display_state/initial_display_state_data_source.h"
+
+#include "perfetto/base/time.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_utils.h"
+
+#include "protos/perfetto/trace/android/initial_display_state.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/system_properties.h>
+#endif
+
+namespace perfetto {
+
+// static
+const InitialDisplayStateDataSource::Descriptor
+    InitialDisplayStateDataSource::descriptor = {
+        /* name */ "android.polled_state",
+        /* flags */ Descriptor::kFlagsNone,
+};
+
+InitialDisplayStateDataSource::InitialDisplayStateDataSource(
+    TracingSessionID session_id,
+    std::unique_ptr<TraceWriter> writer)
+    : ProbesDataSource(session_id, &descriptor), writer_(std::move(writer)) {}
+
+void InitialDisplayStateDataSource::Start() {
+  auto packet = writer_->NewTracePacket();
+  packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
+  const base::Optional<std::string> screen_state_str =
+      ReadProperty("debug.tracing.screen_state");
+  const base::Optional<std::string> screen_brightness_str =
+      ReadProperty("debug.tracing.screen_brightness");
+  const base::Optional<int> screen_state =
+      screen_state_str ? base::StringToInt32(*screen_state_str) : base::nullopt;
+  const base::Optional<double> screen_brightness =
+      screen_brightness_str ? base::StringToDouble(*screen_brightness_str)
+                            : base::nullopt;
+  if (screen_state || screen_brightness) {
+    auto* state = packet->set_initial_display_state();
+    if (screen_state) {
+      state->set_display_state(*screen_state);
+    }
+    if (screen_brightness) {
+      state->set_brightness(*screen_brightness);
+    }
+  }
+  packet->Finalize();
+  writer_->Flush();
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+const base::Optional<std::string> InitialDisplayStateDataSource::ReadProperty(
+    const std::string name) {
+  char value[PROP_VALUE_MAX];
+  if (__system_property_get(name.c_str(), value)) {
+    return base::make_optional(value);
+  } else {
+    PERFETTO_ELOG("Unable to read %s", name.c_str());
+    return base::nullopt;
+  }
+}
+#else
+const base::Optional<std::string> InitialDisplayStateDataSource::ReadProperty(
+    const std::string name __attribute__((unused))) {
+  PERFETTO_ELOG("Initial display state only supported on Android.");
+  return base::nullopt;
+}
+#endif
+
+void InitialDisplayStateDataSource::Flush(FlushRequestID,
+                                          std::function<void()> callback) {
+  writer_->Flush(callback);
+}
+
+}  // namespace perfetto
diff --git a/src/traced/probes/initial_display_state/initial_display_state_data_source.h b/src/traced/probes/initial_display_state/initial_display_state_data_source.h
new file mode 100644
index 0000000..c3746d2
--- /dev/null
+++ b/src/traced/probes/initial_display_state/initial_display_state_data_source.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACED_PROBES_INITIAL_DISPLAY_STATE_INITIAL_DISPLAY_STATE_DATA_SOURCE_H_
+#define SRC_TRACED_PROBES_INITIAL_DISPLAY_STATE_INITIAL_DISPLAY_STATE_DATA_SOURCE_H_
+
+#include <memory>
+
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/tracing/core/trace_writer.h"
+#include "src/traced/probes/probes_data_source.h"
+
+namespace perfetto {
+
+class InitialDisplayStateDataSource : public ProbesDataSource {
+ public:
+  static const ProbesDataSource::Descriptor descriptor;
+
+  InitialDisplayStateDataSource(TracingSessionID,
+                                std::unique_ptr<TraceWriter> writer);
+
+  // ProbesDataSource implementation.
+  void Start() override;
+  void Flush(FlushRequestID, std::function<void()> callback) override;
+
+  // Virtual for testing.
+  virtual const base::Optional<std::string> ReadProperty(
+      const std::string name);
+
+ private:
+  std::unique_ptr<TraceWriter> writer_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACED_PROBES_INITIAL_DISPLAY_STATE_INITIAL_DISPLAY_STATE_DATA_SOURCE_H_
diff --git a/src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc b/src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc
new file mode 100644
index 0000000..a4f4f57
--- /dev/null
+++ b/src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/traced/probes/initial_display_state/initial_display_state_data_source.h"
+#include "src/tracing/core/trace_writer_for_testing.h"
+#include "test/gtest_and_gmock.h"
+
+#include "protos/perfetto/trace/android/initial_display_state.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+
+using ::testing::AnyOf;
+using ::testing::ElementsAre;
+using ::testing::Return;
+
+namespace perfetto {
+namespace {
+
+class TestInitialDisplayStateDataSource : public InitialDisplayStateDataSource {
+ public:
+  TestInitialDisplayStateDataSource(std::unique_ptr<TraceWriter> writer)
+      : InitialDisplayStateDataSource(
+            /* session_id */ 0,
+            std::move(writer)) {}
+
+  MOCK_METHOD1(ReadProperty,
+               const base::Optional<std::string>(const std::string));
+};
+
+class InitialDisplayStateDataSourceTest : public ::testing::Test {
+ protected:
+  std::unique_ptr<TestInitialDisplayStateDataSource>
+  GetInitialDisplayStateDataSource() {
+    auto writer =
+        std::unique_ptr<TraceWriterForTesting>(new TraceWriterForTesting());
+    writer_raw_ = writer.get();
+    auto instance = std::unique_ptr<TestInitialDisplayStateDataSource>(
+        new TestInitialDisplayStateDataSource(std::move(writer)));
+    return instance;
+  }
+
+  TraceWriterForTesting* writer_raw_ = nullptr;
+};
+
+TEST_F(InitialDisplayStateDataSourceTest, Success) {
+  ASSERT_TRUE(true);
+  auto data_source = GetInitialDisplayStateDataSource();
+  EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_state"))
+      .WillOnce(Return(base::make_optional("2")));
+  EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_brightness"))
+      .WillOnce(Return(base::make_optional("0.123456")));
+  data_source->Start();
+
+  protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
+  ASSERT_TRUE(packet.has_initial_display_state());
+  auto state = packet.initial_display_state();
+  ASSERT_EQ(state.display_state(), 2);
+  ASSERT_EQ(state.brightness(), 0.123456);
+}
+
+TEST_F(InitialDisplayStateDataSourceTest, Invalid) {
+  ASSERT_TRUE(true);
+  auto data_source = GetInitialDisplayStateDataSource();
+  EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_state"))
+      .WillOnce(Return(base::make_optional("2")));
+  EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_brightness"))
+      .WillOnce(Return(base::make_optional("gotta wear shades")));
+  data_source->Start();
+
+  protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
+  ASSERT_TRUE(packet.has_initial_display_state());
+  auto state = packet.initial_display_state();
+  ASSERT_EQ(state.display_state(), 2);
+  ASSERT_FALSE(state.has_brightness());
+}
+
+TEST_F(InitialDisplayStateDataSourceTest, Failure) {
+  ASSERT_TRUE(true);
+  auto data_source = GetInitialDisplayStateDataSource();
+  EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_state"))
+      .WillOnce(Return(base::nullopt));
+  EXPECT_CALL(*data_source, ReadProperty("debug.tracing.screen_brightness"))
+      .WillOnce(Return(base::nullopt));
+  data_source->Start();
+
+  protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
+  ASSERT_FALSE(packet.has_initial_display_state());
+}
+
+}  // namespace
+}  // namespace perfetto
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 2d86c02..b1bfe5e 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -37,6 +37,7 @@
 #include "src/traced/probes/common/cpu_freq_info.h"
 #include "src/traced/probes/filesystem/inode_file_data_source.h"
 #include "src/traced/probes/ftrace/ftrace_data_source.h"
+#include "src/traced/probes/initial_display_state/initial_display_state_data_source.h"
 #include "src/traced/probes/metatrace/metatrace_data_source.h"
 #include "src/traced/probes/packages_list/packages_list_data_source.h"
 #include "src/traced/probes/power/android_power_data_source.h"
@@ -64,15 +65,16 @@
 constexpr size_t kTracingSharedMemPageSizeHintBytes = 32 * 1024;
 
 ProbesDataSource::Descriptor const* const kAllDataSources[]{
-    &FtraceDataSource::descriptor,        //
-    &ProcessStatsDataSource::descriptor,  //
-    &InodeFileDataSource::descriptor,     //
-    &SysStatsDataSource::descriptor,      //
-    &AndroidPowerDataSource::descriptor,  //
-    &AndroidLogDataSource::descriptor,    //
-    &PackagesListDataSource::descriptor,  //
-    &MetatraceDataSource::descriptor,     //
-    &SystemInfoDataSource::descriptor,    //
+    &FtraceDataSource::descriptor,               //
+    &ProcessStatsDataSource::descriptor,         //
+    &InodeFileDataSource::descriptor,            //
+    &SysStatsDataSource::descriptor,             //
+    &AndroidPowerDataSource::descriptor,         //
+    &AndroidLogDataSource::descriptor,           //
+    &PackagesListDataSource::descriptor,         //
+    &MetatraceDataSource::descriptor,            //
+    &SystemInfoDataSource::descriptor,           //
+    &InitialDisplayStateDataSource::descriptor,  //
 };
 }  // namespace
 
@@ -166,6 +168,8 @@
     data_source = CreateMetatraceDataSource(session_id, config);
   } else if (config.name() == SystemInfoDataSource::descriptor.name) {
     data_source = CreateSystemInfoDataSource(session_id, config);
+  } else if (config.name() == InitialDisplayStateDataSource::descriptor.name) {
+    data_source = CreateInitialDisplayStateDataSource(session_id, config);
   }
 
   if (!data_source) {
@@ -311,6 +315,15 @@
       std::unique_ptr<CpuFreqInfo>(new CpuFreqInfo())));
 }
 
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateInitialDisplayStateDataSource(
+    TracingSessionID session_id,
+    const DataSourceConfig& config) {
+  auto buffer_id = static_cast<BufferID>(config.target_buffer());
+  return std::unique_ptr<ProbesDataSource>(new InitialDisplayStateDataSource(
+      session_id, endpoint_->CreateTraceWriter(buffer_id)));
+}
+
 void ProbesProducer::StopDataSource(DataSourceInstanceID id) {
   PERFETTO_LOG("Producer stop (id=%" PRIu64 ")", id);
   auto it = data_sources_.find(id);
diff --git a/src/traced/probes/probes_producer.h b/src/traced/probes/probes_producer.h
index 7cab1ab..39d6425 100644
--- a/src/traced/probes/probes_producer.h
+++ b/src/traced/probes/probes_producer.h
@@ -90,6 +90,9 @@
   std::unique_ptr<ProbesDataSource> CreateSystemInfoDataSource(
       TracingSessionID session_id,
       const DataSourceConfig& config);
+  std::unique_ptr<ProbesDataSource> CreateInitialDisplayStateDataSource(
+      TracingSessionID session_id,
+      const DataSourceConfig& config);
 
  private:
   enum State {