nacl_ui.cc revision 3240926e260ce088908e02ac07a6cf7b0c0cbf44
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/nacl_ui.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/plugins/plugin_prefs.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "content/public/browser/browser_thread.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/plugin_service.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_ui_data_source.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_message_handler.h"
32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/common/webplugininfo.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using content::BrowserThread;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::PluginService;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebUIMessageHandler;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebUIDataSource* CreateNaClUIHTMLSource() {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebUIDataSource* source =
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::WebUIDataSource::Create(chrome::kChromeUINaClHost);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->SetUseJsonJSFormatV2();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source->AddLocalizedString("loadingMessage", IDS_NACL_LOADING_MESSAGE);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source->AddLocalizedString("naclLongTitle", IDS_NACL_TITLE_MESSAGE);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->SetJsonPath("strings.js");
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("about_nacl.css", IDR_ABOUT_NACL_CSS);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("about_nacl.js", IDR_ABOUT_NACL_JS);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->SetDefaultResource(IDR_ABOUT_NACL_HTML);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return source;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// NaClDomHandler
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The handler for JavaScript messages for the about:flags page.
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class NaClDomHandler : public WebUIMessageHandler {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NaClDomHandler();
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~NaClDomHandler();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebUIMessageHandler implementation.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RegisterMessages() OVERRIDE;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for the "requestNaClInfo" message.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleRequestNaClInfo(const ListValue* args);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for the NaCl plugin information.
84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void OnGotPlugins(const std::vector<content::WebPluginInfo>& plugins);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // A helper callback that receives the result of checking if PNaCl path
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // exists. |is_valid| is true if the PNaCl path that was returned by
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // PathService is valid, and false otherwise.
893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  void DidValidatePnaclPath(bool* is_valid);
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when enough information is gathered to return data back to the page.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MaybeRespondToPage();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper for MaybeRespondToPage -- called after enough information
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is gathered.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PopulatePageInformation(DictionaryValue* naclInfo);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Factory for the creating refs in callbacks.
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::WeakPtrFactory<NaClDomHandler> weak_ptr_factory_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Returns whether the specified plugin is enabled.
103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool isPluginEnabled(size_t plugin_index);
104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Adds information regarding the operating system and chrome version to list.
106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  void AddOperatingSystemInfo(ListValue* list);
107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
108d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Adds the list of plugins for NaCl to list.
109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  void AddPluginList(ListValue* list);
110d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
111d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Adds the information relevant to PNaCl (e.g., enablement, paths) to list.
112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  void AddPnaclInfo(ListValue* list);
113d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
114d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Adds the information relevant to NaCl to list.
115d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  void AddNaClInfo(ListValue* list);
116d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the page has requested data.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool page_has_requested_data_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the plugin information is ready.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_plugin_info_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Whether PNaCl path was validated. PathService can return a path
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // that does not exists, so it needs to be validated.
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool pnacl_path_validated_;
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool pnacl_path_exists_;
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NaClDomHandler);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NaClDomHandler::NaClDomHandler()
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : weak_ptr_factory_(this),
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      page_has_requested_data_(false),
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      has_plugin_info_(false),
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      pnacl_path_validated_(false),
1363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      pnacl_path_exists_(false) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginService::GetInstance()->GetPlugins(base::Bind(
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      &NaClDomHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr()));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NaClDomHandler::~NaClDomHandler() {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void NaClDomHandler::RegisterMessages() {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "requestNaClInfo",
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&NaClDomHandler::HandleRequestNaClInfo,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions for collecting a list of key-value pairs that will
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be displayed.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddPair(ListValue* list, const string16& key, const string16& value) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* results = new DictionaryValue();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results->SetString("key", key);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results->SetString("value", value);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list->Append(results);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generate an empty data-pair which acts as a line break.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddLineBreak(ListValue* list) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddPair(list, ASCIIToUTF16(""), ASCIIToUTF16(""));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool NaClDomHandler::isPluginEnabled(size_t plugin_index) {
166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::vector<content::WebPluginInfo> info_array;
167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  PluginService::GetInstance()->GetPluginInfoArray(
168d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      GURL(), "application/x-nacl", false, &info_array, NULL);
169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  PluginPrefs* plugin_prefs =
170d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      PluginPrefs::GetForProfile(Profile::FromWebUI(web_ui())).get();
171d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return (!info_array.empty() &&
172d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          plugin_prefs->IsPluginEnabled(info_array[plugin_index]));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NaClDomHandler::AddOperatingSystemInfo(ListValue* list) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Obtain the Chrome version info.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::VersionInfo version_info;
178d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddPair(list,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASCIIToUTF16(version_info.Version() + " (" +
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       chrome::VersionInfo::GetVersionStringModifier() + ")"));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OS version information.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jvoung): refactor this to share the extra windows labeling
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with about:flash, or something.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string os_label = version_info.OSType();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::OSInfo* os = base::win::OSInfo::GetInstance();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (os->version()) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::win::VERSION_XP: os_label += " XP"; break;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::win::VERSION_SERVER_2003:
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      os_label += " Server 2003 or XP Pro 64 bit";
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::win::VERSION_VISTA: os_label += " Vista or Server 2008"; break;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::win::VERSION_WIN7: os_label += " 7 or Server 2008 R2"; break;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case base::win::VERSION_WIN8: os_label += " 8 or Server 2012"; break;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:  os_label += " UNKNOWN"; break;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  os_label += " SP" + base::IntToString(os->service_pack().major);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (os->service_pack().minor > 0)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    os_label += "." + base::IntToString(os->service_pack().minor);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (os->architecture() == base::win::OSInfo::X64_ARCHITECTURE)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    os_label += " 64 bit";
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddPair(list,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_OS),
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASCIIToUTF16(os_label));
208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddLineBreak(list);
209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NaClDomHandler::AddPluginList(ListValue* list) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Obtain the version of the NaCl plugin.
213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::vector<content::WebPluginInfo> info_array;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginService::GetInstance()->GetPluginInfoArray(
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(), "application/x-nacl", false, &info_array, NULL);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 nacl_version;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 nacl_key = ASCIIToUTF16("NaCl plugin");
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info_array.empty()) {
219d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    AddPair(list, nacl_key, ASCIIToUTF16("Disabled"));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only the 0th plugin is used.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nacl_version = info_array[0].version + ASCIIToUTF16(" ") +
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info_array[0].path.LossyDisplayName();
224d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (!isPluginEnabled(0)) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      nacl_version += ASCIIToUTF16(" (Disabled in profile prefs)");
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    AddPair(list, nacl_key, nacl_version);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Mark the rest as not used.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 1; i < info_array.size(); ++i) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      nacl_version = info_array[i].version + ASCIIToUTF16(" ") +
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          info_array[i].path.LossyDisplayName();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      nacl_version += ASCIIToUTF16(" (not used)");
235d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      if (!isPluginEnabled(i)) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nacl_version += ASCIIToUTF16(" (Disabled in profile prefs)");
237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      }
238d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      AddPair(list, nacl_key, nacl_version);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
241d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddLineBreak(list);
242d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NaClDomHandler::AddPnaclInfo(ListValue* list) {
245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Display whether PNaCl is enabled.
246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  string16 pnacl_enabled_string = ASCIIToUTF16("Enabled");
247d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!isPluginEnabled(0)) {
248d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    pnacl_enabled_string = ASCIIToUTF16("Disabled in profile prefs");
249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  } else if (CommandLine::ForCurrentProcess()->HasSwitch(
250d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                 switches::kDisablePnacl)) {
251d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    pnacl_enabled_string = ASCIIToUTF16("Disabled by flag '--disable-pnacl'");
252d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
253d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddPair(list,
254d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          ASCIIToUTF16("Portable Native Client (PNaCl)"),
255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          pnacl_enabled_string);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Obtain the version of the PNaCl translator.
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath pnacl_path;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool got_path = PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_path);
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!got_path || pnacl_path.empty() || !pnacl_path_exists_) {
261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    AddPair(list,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ASCIIToUTF16("PNaCl translator"),
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ASCIIToUTF16("Not installed"));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
265d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    AddPair(list,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ASCIIToUTF16("PNaCl translator path"),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            pnacl_path.LossyDisplayName());
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Version string is part of the directory name:
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // pnacl/<version>/_platform_specific/<arch>/[files]
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Keep in sync with pnacl_component_installer.cc.
271d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    AddPair(list,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ASCIIToUTF16("PNaCl translator version"),
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            pnacl_path.DirName().DirName().BaseName().LossyDisplayName());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
275d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddLineBreak(list);
276d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
277d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
278d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NaClDomHandler::AddNaClInfo(ListValue* list) {
279d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  string16 nacl_enabled_string = ASCIIToUTF16("Disabled");
280d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (isPluginEnabled(0) &&
281d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaCl)) {
282d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    nacl_enabled_string = ASCIIToUTF16("Enabled by flag '--enable-nacl'");
283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
284d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddPair(list,
285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          ASCIIToUTF16("Native Client (non-portable, outside web store)"),
286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          nacl_enabled_string);
287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddLineBreak(list);
288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
289d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NaClDomHandler::HandleRequestNaClInfo(const ListValue* args) {
291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  page_has_requested_data_ = true;
292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Force re-validation of pnacl's path in the next call to
293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // MaybeRespondToPage(), in case PNaCl went from not-installed
294d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // to installed since the request.
295d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  pnacl_path_validated_ = false;
296d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  MaybeRespondToPage();
297d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
298d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
299d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NaClDomHandler::OnGotPlugins(
300d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const std::vector<content::WebPluginInfo>& plugins) {
301d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  has_plugin_info_ = true;
302d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  MaybeRespondToPage();
303d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NaClDomHandler::PopulatePageInformation(DictionaryValue* naclInfo) {
306d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  DCHECK(pnacl_path_validated_);
307d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Store Key-Value pairs of about-information.
308d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  scoped_ptr<ListValue> list(new ListValue());
309d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Display the operating system and chrome version information.
310d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddOperatingSystemInfo(list.get());
311d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Display the list of plugins serving NaCl.
312d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddPluginList(list.get());
313d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Display information relevant to PNaCl.
314d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddPnaclInfo(list.get());
315d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Display information relevant to NaCl (non-portable.
316d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  AddNaClInfo(list.get());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // naclInfo will take ownership of list, and clean it up on destruction.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  naclInfo->Set("naclInfo", list.release());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid NaClDomHandler::DidValidatePnaclPath(bool* is_valid) {
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  pnacl_path_validated_ = true;
3233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  pnacl_path_exists_ = *is_valid;
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MaybeRespondToPage();
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid ValidatePnaclPath(bool* is_valid) {
3283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::FilePath pnacl_path;
3293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  bool got_path = PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_path);
3303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  *is_valid = got_path && !pnacl_path.empty() && base::PathExists(pnacl_path);
3313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
3323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void NaClDomHandler::MaybeRespondToPage() {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't reply until everything is ready.  The page will show a 'loading'
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message until then.
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!page_has_requested_data_ || !has_plugin_info_)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!pnacl_path_validated_) {
3403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    bool* is_valid = new bool;
3413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    BrowserThread::PostBlockingPoolTaskAndReply(
3423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        FROM_HERE,
3433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        base::Bind(&ValidatePnaclPath, is_valid),
3443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        base::Bind(&NaClDomHandler::DidValidatePnaclPath,
3453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                   weak_ptr_factory_.GetWeakPtr(),
3463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                   base::Owned(is_valid)));
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue naclInfo;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PopulatePageInformation(&naclInfo);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->CallJavascriptFunction("nacl.returnNaClInfo", naclInfo);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NaClUI
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NaClUI::NaClUI(content::WebUI* web_ui) : WebUIController(web_ui) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("ViewAboutNaCl"));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  web_ui->AddMessageHandler(new NaClDomHandler());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up the about:nacl source.
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebUIDataSource::Add(profile, CreateNaClUIHTMLSource());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
372