[ios] Implements support for chrome://prefs-internals.

BUG=1006711

Change-Id: I16e839f2ac419d051a0f2ca1b40f7ad1c8362966
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1819241
Reviewed-by: Justin Cohen <[email protected]>
Commit-Queue: Rohit Rao <[email protected]>
Cr-Commit-Position: refs/heads/master@{#698873}
diff --git a/ios/chrome/browser/ui/webui/BUILD.gn b/ios/chrome/browser/ui/webui/BUILD.gn
index c275493..8b3e6b6 100644
--- a/ios/chrome/browser/ui/webui/BUILD.gn
+++ b/ios/chrome/browser/ui/webui/BUILD.gn
@@ -22,6 +22,8 @@
     "mojo_web_ui_ios_controller.h",
     "ntp_tiles_internals_ui.cc",
     "ntp_tiles_internals_ui.h",
+    "prefs_internals_ui.cc",
+    "prefs_internals_ui.h",
     "suggestions_ui.cc",
     "suggestions_ui.h",
     "terms_ui.h",
diff --git a/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm b/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm
index a1eb15b3..102d978 100644
--- a/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm
+++ b/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm
@@ -20,6 +20,7 @@
 #include "ios/chrome/browser/ui/webui/net_export/net_export_ui.h"
 #include "ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.h"
 #include "ios/chrome/browser/ui/webui/omaha_ui.h"
+#include "ios/chrome/browser/ui/webui/prefs_internals_ui.h"
 #include "ios/chrome/browser/ui/webui/signin_internals_ui_ios.h"
 #include "ios/chrome/browser/ui/webui/suggestions_ui.h"
 #include "ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.h"
@@ -89,6 +90,8 @@
     return &NewWebUIIOS<OmahaUI>;
   if (url_host == kChromeUIPasswordManagerInternalsHost)
     return &NewWebUIIOS<PasswordManagerInternalsUIIOS>;
+  if (url_host == kChromeUIPrefsInternalsHost)
+    return &NewWebUIIOS<PrefsInternalsUI>;
   if (url_host == kChromeUISignInInternalsHost)
     return &NewWebUIIOS<SignInInternalsUIIOS>;
   if (url.host_piece() == kChromeUISuggestionsHost)
diff --git a/ios/chrome/browser/ui/webui/prefs_internals_ui.cc b/ios/chrome/browser/ui/webui/prefs_internals_ui.cc
new file mode 100644
index 0000000..052e861
--- /dev/null
+++ b/ios/chrome/browser/ui/webui/prefs_internals_ui.cc
@@ -0,0 +1,73 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/ui/webui/prefs_internals_ui.h"
+
+#include <string>
+
+#include "base/json/json_writer.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/values.h"
+#include "components/prefs/pref_service.h"
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#include "ios/chrome/browser/chrome_url_constants.h"
+#include "ios/chrome/browser/suggestions/suggestions_service_factory.h"
+#include "ios/web/public/thread/web_thread.h"
+#include "ios/web/public/webui/url_data_source_ios.h"
+
+namespace {
+
+// A simple data source that returns the preferences for the associated browser
+// state.
+class PrefsInternalsSource : public web::URLDataSourceIOS {
+ public:
+  explicit PrefsInternalsSource(ios::ChromeBrowserState* browser_state)
+      : browser_state_(browser_state) {}
+  ~PrefsInternalsSource() override = default;
+
+  // content::URLDataSource:
+  std::string GetSource() const override { return kChromeUIPrefsInternalsHost; }
+
+  std::string GetMimeType(const std::string& path) const override {
+    return "text/plain";
+  }
+
+  void StartDataRequest(
+      const std::string& path,
+      const web::URLDataSourceIOS::GotDataCallback& callback) override {
+    // TODO(crbug.com/1006711): Properly disable this webui provider for
+    // incognito browser states.
+    if (browser_state_->IsOffTheRecord()) {
+      callback.Run(nullptr);
+      return;
+    }
+
+    DCHECK_CURRENTLY_ON(web::WebThread::UI);
+    std::string json;
+    std::unique_ptr<base::DictionaryValue> prefs =
+        browser_state_->GetPrefs()->GetPreferenceValues(
+            PrefService::INCLUDE_DEFAULTS);
+    DCHECK(prefs);
+    CHECK(base::JSONWriter::WriteWithOptions(
+        *prefs, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json));
+    callback.Run(base::RefCountedString::TakeString(&json));
+  }
+
+ private:
+  ios::ChromeBrowserState* browser_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrefsInternalsSource);
+};
+
+}  // namespace
+
+PrefsInternalsUI::PrefsInternalsUI(web::WebUIIOS* web_ui)
+    : web::WebUIIOSController(web_ui) {
+  ios::ChromeBrowserState* browser_state =
+      ios::ChromeBrowserState::FromWebUIIOS(web_ui);
+  web::URLDataSourceIOS::Add(browser_state,
+                             new PrefsInternalsSource(browser_state));
+}
+
+PrefsInternalsUI::~PrefsInternalsUI() = default;
diff --git a/ios/chrome/browser/ui/webui/prefs_internals_ui.h b/ios/chrome/browser/ui/webui/prefs_internals_ui.h
new file mode 100644
index 0000000..ec2a73a
--- /dev/null
+++ b/ios/chrome/browser/ui/webui/prefs_internals_ui.h
@@ -0,0 +1,26 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_WEBUI_PREFS_INTERNALS_UI_H_
+#define IOS_CHROME_BROWSER_UI_WEBUI_PREFS_INTERNALS_UI_H_
+
+#include "base/macros.h"
+#include "ios/web/public/webui/web_ui_ios_controller.h"
+
+namespace web {
+class WebUIIOS;
+}
+
+// The WebUIController for chrome://prefs-internals. Renders the current user
+// prefs.
+class PrefsInternalsUI : public web::WebUIIOSController {
+ public:
+  explicit PrefsInternalsUI(web::WebUIIOS* web_ui);
+  ~PrefsInternalsUI() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PrefsInternalsUI);
+};
+
+#endif  // IOS_CHROME_BROWSER_UI_WEBUI_PREFS_INTERNALS_UI_H_