Version 2.16.0-44.0.dev

Merge commit '75abd86407e44d31a1ce843df71d0665c2793714' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fc40635..b65a8fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -415,7 +415,14 @@
 
 #### Linter
 
-Updated the Linter to `1.14.0`, which includes changes that
+Updated the Linter to `1.15.0`, which includes changes that
+- adds new lint: `use_decorated_box`.
+- adds new lint: `no_leading_underscores_for_library_prefixes`.
+- adds new lint: `no_leading_underscores_for_local_identifiers`.
+- adds new lint: `secure_pubspec_urls`.
+- adds new lint: `sized_box_shrink_expand`.
+- adds new lint: `avoid_final_parameters`.
+- improves docs for `omit_local_variable_types`.
 - fix `omit_local_variable_types` to not flag a local type that is
   required for inference.
 - allow `while (true) { ... }` in `literal_only_boolean_expressions`.
diff --git a/DEPS b/DEPS
index a2c3532..6a06c77 100644
--- a/DEPS
+++ b/DEPS
@@ -123,7 +123,7 @@
   "intl_tag": "0.17.0-nullsafety",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "7e00f893440a72de0637970325e4ea44bd1e8c8e",
-  "linter_tag": "1.14.0",
+  "linter_tag": "1.15.0",
   "lints_tag": "f9670df2a66e0ec12eb51554e70c1cbf56c8f5d0",
   "logging_rev": "575781ef196e4fed4fb737e38fb4b73d62727187",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 771ccee..29ff4bc 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -97,7 +97,13 @@
   void _registerJsonRpcMethods() {
     _clientPeer.registerMethod('streamListen', (parameters) async {
       final streamId = parameters['streamId'].asString;
-      await dds.streamManager.streamListen(this, streamId);
+      final includePrivates =
+          parameters['_includePrivateMembers'].asBoolOr(false);
+      await dds.streamManager.streamListen(
+        this,
+        streamId,
+        includePrivates: includePrivates,
+      );
       return RPCResponses.success;
     });
 
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
index 46e22cf..1875117 100644
--- a/pkg/dds/lib/src/stream_manager.dart
+++ b/pkg/dds/lib/src/stream_manager.dart
@@ -146,16 +146,19 @@
   /// `streamListen` request for `stream` to the VM service.
   Future<void> streamListen(
     DartDevelopmentServiceClient? client,
-    String stream,
-  ) async {
+    String stream, {
+    bool? includePrivates,
+  }) async {
     await _mutex.runGuarded(
       () async {
         assert(stream.isNotEmpty);
+        bool streamNewlySubscribed = false;
         if (!streamListeners.containsKey(stream)) {
           // Initialize the list of clients for the new stream before we do
           // anything else to ensure multiple clients registering for the same
           // stream in quick succession doesn't result in multiple streamListen
           // requests being sent to the VM service.
+          streamNewlySubscribed = true;
           streamListeners[stream] = <DartDevelopmentServiceClient>[];
           if ((stream == kDebugStream && client == null) ||
               stream != kDebugStream) {
@@ -164,12 +167,17 @@
             final result =
                 await dds.vmServiceClient.sendRequest('streamListen', {
               'streamId': stream,
+              if (includePrivates != null)
+                '_includePrivateMembers': includePrivates,
             });
             assert(result['type'] == 'Success');
           }
         }
         if (streamListeners[stream]!.contains(client)) {
           throw kStreamAlreadySubscribedException;
+        } else if (!streamNewlySubscribed && includePrivates != null) {
+          await dds.vmServiceClient.sendRequest('_setStreamIncludePrivateMembers',
+              {'streamId': stream, 'includePrivateMembers': includePrivates});
         }
         if (client != null) {
           streamListeners[stream]!.add(client);
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index f3dba9a..f0eb4ce 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -128,10 +128,13 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(VMService_ListenStream, 0, 1) {
+DEFINE_NATIVE_ENTRY(VMService_ListenStream, 0, 2) {
 #ifndef PRODUCT
   GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0));
-  bool result = Service::ListenStream(stream_id.ToCString());
+  GET_NON_NULL_NATIVE_ARGUMENT(Bool, include_privates,
+                               arguments->NativeArgAt(1));
+  bool result =
+      Service::ListenStream(stream_id.ToCString(), include_privates.value());
   return Bool::Get(result).ptr();
 #else
   return Object::null();
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index 236343c..5c62c48 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -149,7 +149,11 @@
       return new Future.error(exception);
     }
     String serial = (_requestSerial++).toString();
-    var request = new _WebSocketRequest(method, params);
+    var request = new _WebSocketRequest(method, <String, dynamic>{
+      ...params,
+      // Include internal response data.
+      '_includePrivateMembers': true,
+    });
     if ((_webSocket != null) && _webSocket!.isOpen) {
       // Already connected, send request immediately.
       _sendRequest(serial, request);
diff --git a/runtime/observatory_2/lib/service_common.dart b/runtime/observatory_2/lib/service_common.dart
index b61f4a0..d6eba9b 100644
--- a/runtime/observatory_2/lib/service_common.dart
+++ b/runtime/observatory_2/lib/service_common.dart
@@ -149,7 +149,11 @@
       return new Future.error(exception);
     }
     String serial = (_requestSerial++).toString();
-    var request = new _WebSocketRequest(method, params);
+    var request = new _WebSocketRequest(method, <String, dynamic>{
+      ...params,
+      // Include internal response data.
+      '_includePrivateMembers': true,
+    });
     if ((_webSocket != null) && _webSocket.isOpen) {
       // Already connected, send request immediately.
       _sendRequest(serial, request);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 46b44a3..339318e 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -362,7 +362,7 @@
   V(VMService_OnStart, 0)                                                      \
   V(VMService_OnExit, 0)                                                       \
   V(VMService_OnServerAddressChange, 1)                                        \
-  V(VMService_ListenStream, 1)                                                 \
+  V(VMService_ListenStream, 2)                                                 \
   V(VMService_CancelStream, 1)                                                 \
   V(VMService_RequestAssets, 0)                                                \
   V(VMService_DecodeAssets, 1)                                                 \
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 01b6c5f..fa00c67 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -37,7 +37,9 @@
       param_values_(NULL),
       num_params_(0),
       offset_(0),
-      count_(-1) {
+      count_(-1),
+      include_private_members_(true),
+      ignore_object_depth_(0) {
   ObjectIdRing* ring = NULL;
   Isolate* isolate = Isolate::Current();
   if (isolate != NULL) {
@@ -90,6 +92,10 @@
                  "request %s\n",
                  Dart::UptimeMillis(), main_port, isolate_name, method_);
   }
+  const char* kIncludePrivateMembersKey = "_includePrivateMembers";
+  if (HasParam(kIncludePrivateMembersKey)) {
+    include_private_members_ = ParamIs(kIncludePrivateMembersKey, "true");
+  }
   buffer()->Printf("{\"jsonrpc\":\"2.0\", \"result\":");
 }
 
@@ -368,49 +374,61 @@
   PrintProperty("id", id_zone_->GetServiceId(o));
 }
 
+#define PRIVATE_NAME_CHECK()                                                   \
+  if (!IsAllowableKey(name) || ignore_object_depth_ > 0) return
+
 void JSONStream::PrintProperty(const char* name, const ServiceEvent* event) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(event);
 }
 
 void JSONStream::PrintProperty(const char* name, Breakpoint* bpt) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(bpt);
 }
 
 void JSONStream::PrintProperty(const char* name, TokenPosition tp) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(tp);
 }
 
 void JSONStream::PrintProperty(const char* name, Metric* metric) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(metric);
 }
 
 void JSONStream::PrintProperty(const char* name, MessageQueue* queue) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(queue);
 }
 
 void JSONStream::PrintProperty(const char* name, Isolate* isolate) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(isolate);
 }
 
 void JSONStream::PrintProperty(const char* name,
                                const TimelineEvent* timeline_event) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(timeline_event);
 }
 
 void JSONStream::PrintProperty(const char* name,
                                const TimelineEventBlock* timeline_event_block) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(timeline_event_block);
 }
 
 void JSONStream::PrintfProperty(const char* name, const char* format, ...) {
+  PRIVATE_NAME_CHECK();
   va_list args;
   va_start(args, format);
   writer_.VPrintfProperty(name, format, args);
@@ -462,11 +480,13 @@
 }
 
 void JSONStream::PrintProperty(const char* name, const Object& o, bool ref) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValue(o, ref);
 }
 
 void JSONStream::PrintPropertyVM(const char* name, bool ref) {
+  PRIVATE_NAME_CHECK();
   PrintPropertyName(name);
   PrintValueVM(ref);
 }
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index a00f266..5b37379 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -9,6 +9,7 @@
 #include "platform/allocation.h"
 #include "platform/text_buffer.h"
 #include "vm/json_writer.h"
+#include "vm/os.h"
 #include "vm/service.h"
 #include "vm/token_position.h"
 
@@ -102,6 +103,18 @@
 
   void set_reply_port(Dart_Port port);
 
+  bool include_private_members() const { return include_private_members_; }
+  void set_include_private_members(bool include_private_members) {
+    include_private_members_ = include_private_members;
+  }
+
+  bool IsAllowableKey(const char* key) {
+    if (include_private_members_) {
+      return true;
+    }
+    return *key != '_';
+  }
+
   void SetParams(const char** param_keys,
                  const char** param_values,
                  intptr_t num_params);
@@ -167,15 +180,41 @@
   void PostNullReply(Dart_Port port);
 
   void OpenObject(const char* property_name = NULL) {
+    if (ignore_object_depth_ > 0 ||
+        (property_name != nullptr && !IsAllowableKey(property_name))) {
+      ignore_object_depth_++;
+      return;
+    }
     writer_.OpenObject(property_name);
   }
-  void CloseObject() { writer_.CloseObject(); }
-  void UncloseObject() { writer_.UncloseObject(); }
+  void CloseObject() {
+    if (ignore_object_depth_ > 0) {
+      ignore_object_depth_--;
+      return;
+    }
+    writer_.CloseObject();
+  }
+  void UncloseObject() {
+    // This should be updated to handle unclosing a private object if we need
+    // to handle that case, which we don't currently.
+    writer_.UncloseObject();
+  }
 
   void OpenArray(const char* property_name = NULL) {
+    if (ignore_object_depth_ > 0 ||
+        (property_name != nullptr && !IsAllowableKey(property_name))) {
+      ignore_object_depth_++;
+      return;
+    }
     writer_.OpenArray(property_name);
   }
-  void CloseArray() { writer_.CloseArray(); }
+  void CloseArray() {
+    if (ignore_object_depth_ > 0) {
+      ignore_object_depth_--;
+      return;
+    }
+    writer_.CloseArray();
+  }
 
   void PrintValueNull() { writer_.PrintValueNull(); }
   void PrintValueBool(bool b) { writer_.PrintValueBool(b); }
@@ -211,46 +250,67 @@
 
   void PrintServiceId(const Object& o);
 
+#define PRIVATE_NAME_CHECK()                                                   \
+  if (!IsAllowableKey(name) || ignore_object_depth_ > 0) {                     \
+    return;                                                                    \
+  }
+
   void PrintPropertyBool(const char* name, bool b) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintPropertyBool(name, b);
   }
   void PrintProperty(const char* name, intptr_t i) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty(name, i);
   }
   void PrintProperty64(const char* name, int64_t i) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty64(name, i);
   }
   void PrintPropertyTimeMillis(const char* name, int64_t millis) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty64(name, millis);
   }
   void PrintPropertyTimeMicros(const char* name, int64_t micros) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty64(name, micros);
   }
   void PrintProperty(const char* name, double d) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty(name, d);
   }
   void PrintPropertyBase64(const char* name,
                            const uint8_t* bytes,
                            intptr_t length) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintPropertyBase64(name, bytes, length);
   }
   void PrintProperty(const char* name, const char* s) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintProperty(name, s);
   }
   bool PrintPropertyStr(const char* name,
                         const String& s,
                         intptr_t offset,
                         intptr_t count) {
+    if (!IsAllowableKey(name)) {
+      return false;
+    }
     return writer_.PrintPropertyStr(name, s, offset, count);
   }
   void PrintPropertyNoEscape(const char* name, const char* s) {
+    PRIVATE_NAME_CHECK();
     writer_.PrintPropertyNoEscape(name, s);
   }
   void PrintfProperty(const char* name, const char* format, ...)
       PRINTF_ATTRIBUTE(3, 4);
   void VPrintfProperty(const char* name, const char* format, va_list args) {
+    PRIVATE_NAME_CHECK();
     writer_.VPrintfProperty(name, format, args);
   }
+
+#undef PRIVATE_NAME_CHECK
+
   void PrintProperty(const char* name, const Object& o, bool ref = true);
 
   void PrintProperty(const char* name, const ServiceEvent* event);
@@ -285,7 +345,8 @@
   intptr_t offset_;
   intptr_t count_;
   int64_t setup_time_micros_;
-
+  bool include_private_members_;
+  intptr_t ignore_object_depth_;
   friend class JSONObject;
   friend class JSONArray;
   friend class TimelineEvent;
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 209387d..19e4c6c 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -367,7 +367,7 @@
     &Service::timeline_stream, &Service::profiler_stream,
 };
 
-bool Service::ListenStream(const char* stream_id) {
+bool Service::ListenStream(const char* stream_id, bool include_private_members) {
   if (FLAG_trace_service) {
     OS::PrintErr("vm-service: starting stream '%s'\n", stream_id);
   }
@@ -375,6 +375,7 @@
   for (intptr_t i = 0; i < num_streams; i++) {
     if (strcmp(stream_id, streams_[i]->id()) == 0) {
       streams_[i]->set_enabled(true);
+      streams_[i]->set_include_private_members(include_private_members);
       return true;
     }
   }
@@ -1164,7 +1165,7 @@
 }
 
 void Service::HandleEvent(ServiceEvent* event, bool enter_safepoint) {
-  if (event->stream_info() != NULL && !event->stream_info()->enabled()) {
+  if (event->stream_info() != nullptr && !event->stream_info()->enabled()) {
     if (FLAG_warn_on_pause_with_no_debugger && event->IsPause()) {
       // If we are about to pause a running program which has no
       // debugger connected, tell the user about it.
@@ -1172,7 +1173,7 @@
     }
     // Ignore events when no one is listening to the event stream.
     return;
-  } else if (event->stream_info() != NULL &&
+  } else if (event->stream_info() != nullptr &&
              FLAG_warn_on_pause_with_no_debugger && event->IsPause()) {
     ReportPauseOnConsole(event);
   }
@@ -1180,8 +1181,11 @@
     return;
   }
   JSONStream js;
+  if (event->stream_info() != nullptr) {
+    js.set_include_private_members(event->stream_info()->include_private_members());
+  }
   const char* stream_id = event->stream_id();
-  ASSERT(stream_id != NULL);
+  ASSERT(stream_id != nullptr);
   {
     JSONObject jsobj(&js);
     jsobj.AddProperty("jsonrpc", "2.0");
@@ -1495,6 +1499,30 @@
   }
 }
 
+static const MethodParameter* const set_stream_include_private_members_params[] = {
+    NO_ISOLATE_PARAMETER,
+    new BoolParameter("includePrivateMembers", true),
+    nullptr,
+};
+
+static void SetStreamIncludePrivateMembers(Thread* thread, JSONStream* js) {
+  const char* stream_id = js->LookupParam("streamId");
+  if (stream_id == nullptr) {
+    PrintMissingParamError(js, "streamId");
+    return;
+  }
+  bool include_private_members =
+      BoolParameter::Parse(js->LookupParam("includePrivateMembers"), false);
+  intptr_t num_streams = sizeof(streams_) / sizeof(streams_[0]);
+  for (intptr_t i = 0; i < num_streams; i++) {
+    if (strcmp(stream_id, streams_[i]->id()) == 0) {
+      streams_[i]->set_include_private_members(include_private_members);
+      break;
+    }
+  }
+  PrintSuccess(js);
+}
+
 static void ActOnIsolateGroup(JSONStream* js,
                               std::function<void(IsolateGroup*)> visitor) {
   const String& prefix =
@@ -5626,6 +5654,8 @@
     set_library_debuggable_params },
   { "setName", SetName,
     set_name_params },
+  { "_setStreamIncludePrivateMembers", SetStreamIncludePrivateMembers,
+    set_stream_include_private_members_params },
   { "setTraceClassAllocation", SetTraceClassAllocation,
     set_trace_class_allocation_params },
   { "setVMName", SetVMName,
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index c31b191..d6ba66d 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -68,16 +68,21 @@
 
 class StreamInfo {
  public:
-  explicit StreamInfo(const char* id) : id_(id), enabled_(false) {}
+  explicit StreamInfo(const char* id)
+      : id_(id), enabled_(false), include_private_members_(false) {}
 
   const char* id() const { return id_; }
 
   void set_enabled(bool value) { enabled_ = value; }
   bool enabled() const { return enabled_; }
 
+  void set_include_private_members(bool value) { include_private_members_ = value; }
+  bool include_private_members() const { return include_private_members_; }
+
  private:
   const char* id_;
   bool enabled_;
+  bool include_private_members_;
 };
 
 class Service : public AllStatic {
@@ -168,7 +173,7 @@
   static StreamInfo timeline_stream;
   static StreamInfo profiler_stream;
 
-  static bool ListenStream(const char* stream_id);
+  static bool ListenStream(const char* stream_id, bool include_privates);
   static void CancelStream(const char* stream_id);
 
   static ObjectPtr RequestAssets();
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index ed389a7..c5d2620 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -522,7 +522,9 @@
       return encodeRpcError(message, kStreamAlreadySubscribed);
     }
     if (!_isAnyClientSubscribed(streamId)) {
-      if (!serviceStreams.contains(streamId) && !_vmListenStream(streamId)) {
+      final includePrivates = message.params['_includePrivateMembers'] == true;
+      if (!serviceStreams.contains(streamId) &&
+          !_vmListenStream(streamId, includePrivates)) {
         return encodeRpcError(message, kInvalidParams,
             details: "streamListen: invalid 'streamId' parameter: ${streamId}");
       }
@@ -750,7 +752,7 @@
 
 /// Subscribe to a service stream.
 @pragma("vm:external-name", "VMService_ListenStream")
-external bool _vmListenStream(String streamId);
+external bool _vmListenStream(String streamId, bool include_privates);
 
 /// Cancel a subscription to a service stream.
 @pragma("vm:external-name", "VMService_CancelStream")
diff --git a/tools/VERSION b/tools/VERSION
index 9ffa67f..594094a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 43
+PRERELEASE 44
 PRERELEASE_PATCH 0
\ No newline at end of file