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/policy_ui.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/json/json_writer.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/profile_policy_connector.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/profile_policy_connector_factory.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/policy/schema_registry_service.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/policy/schema_registry_service_factory.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/browser/browser_policy_connector.h"
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/browser/cloud/message_util.h"
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/browser/configuration_policy_handler_list.h"
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/browser/policy_error_map.h"
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_client.h"
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h"
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_core.h"
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_store.h"
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_validator.h"
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h"
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_namespace.h"
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/policy_service.h"
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_types.h"
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema.h"
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema_map.h"
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema_registry.h"
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_observer.h"
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_registrar.h"
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_service.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_ui_data_source.h"
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_ui_message_handler.h"
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "grit/components_strings.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "policy/policy_constants.h"
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
55bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "ui/base/l10n/time_format.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/web_contents.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if !defined(OS_ANDROID) && !defined(OS_IOS)
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/extensions/extension_service.h"
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h"
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest_constants.h"
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace em = enterprise_management;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebUIDataSource* CreatePolicyUIHTMLSource() {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebUIDataSource* source =
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::WebUIDataSource::Create(chrome::kChromeUIPolicyHost);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Localized strings.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("title", IDS_POLICY_TITLE);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("filterPlaceholder",
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             IDS_POLICY_FILTER_PLACEHOLDER);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("reloadPolicies", IDS_POLICY_RELOAD_POLICIES);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("status", IDS_POLICY_STATUS);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("statusDevice", IDS_POLICY_STATUS_DEVICE);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("statusUser", IDS_POLICY_STATUS_USER);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("labelDomain", IDS_POLICY_LABEL_DOMAIN);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("labelUsername", IDS_POLICY_LABEL_USERNAME);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("labelClientId", IDS_POLICY_LABEL_CLIENT_ID);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("labelTimeSinceLastRefresh",
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             IDS_POLICY_LABEL_TIME_SINCE_LAST_REFRESH);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("labelRefreshInterval",
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             IDS_POLICY_LABEL_REFRESH_INTERVAL);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("labelStatus", IDS_POLICY_LABEL_STATUS);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("showUnset", IDS_POLICY_SHOW_UNSET);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("noPoliciesSet", IDS_POLICY_NO_POLICIES_SET);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("headerScope", IDS_POLICY_HEADER_SCOPE);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("headerLevel", IDS_POLICY_HEADER_LEVEL);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("headerName", IDS_POLICY_HEADER_NAME);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("headerValue", IDS_POLICY_HEADER_VALUE);
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("headerStatus", IDS_POLICY_HEADER_STATUS);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("showExpandedValue",
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             IDS_POLICY_SHOW_EXPANDED_VALUE);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("hideExpandedValue",
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             IDS_POLICY_HIDE_EXPANDED_VALUE);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("scopeUser", IDS_POLICY_SCOPE_USER);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("scopeDevice", IDS_POLICY_SCOPE_DEVICE);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("levelRecommended", IDS_POLICY_LEVEL_RECOMMENDED);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("levelMandatory", IDS_POLICY_LEVEL_MANDATORY);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("ok", IDS_POLICY_OK);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("unset", IDS_POLICY_UNSET);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddLocalizedString("unknown", IDS_POLICY_UNKNOWN);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->SetUseJsonJSFormatV2();
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->SetJsonPath("strings.js");
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add required resources.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("policy.css", IDR_POLICY_CSS);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("policy.js", IDR_POLICY_JS);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("uber_utils.js", IDR_UBER_UTILS_JS);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->SetDefaultResource(IDR_POLICY_HTML);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return source;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Formats the association state indicated by |data|. If |data| is NULL, the
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// state is considered to be UNMANAGED.
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 FormatAssociationState(const em::PolicyData* data) {
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (data) {
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (data->state()) {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case em::PolicyData::ACTIVE:
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return l10n_util::GetStringUTF16(IDS_POLICY_ASSOCIATION_STATE_ACTIVE);
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case em::PolicyData::UNMANAGED:
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return l10n_util::GetStringUTF16(
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            IDS_POLICY_ASSOCIATION_STATE_UNMANAGED);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case em::PolicyData::DEPROVISIONED:
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return l10n_util::GetStringUTF16(
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            IDS_POLICY_ASSOCIATION_STATE_DEPROVISIONED);
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED() << "Unknown state " << data->state();
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Default to UNMANAGED for the case of missing policy or bad state enum.
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_POLICY_ASSOCIATION_STATE_UNMANAGED);
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetStatusFromCore(const policy::CloudPolicyCore* core,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       base::DictionaryValue* dict) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const policy::CloudPolicyStore* store = core->store();
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const policy::CloudPolicyClient* client = core->client();
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const policy::CloudPolicyRefreshScheduler* refresh_scheduler =
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        core->refresh_scheduler();
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // CloudPolicyStore errors take precedence to show in the status message.
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Other errors (such as transient policy fetching problems) get displayed
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // only if CloudPolicyStore is in STATUS_OK.
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 status =
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      policy::FormatStoreStatus(store->status(), store->validation_status());
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (store->status() == policy::CloudPolicyStore::STATUS_OK) {
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (client && client->status() != policy::DM_STATUS_SUCCESS)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      status = policy::FormatDeviceManagementStatus(client->status());
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else if (!store->is_managed())
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      status = FormatAssociationState(store->policy());
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const em::PolicyData* policy = store->policy();
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string client_id = policy ? policy->device_id() : std::string();
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string username = policy ? policy->username() : std::string();
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta refresh_interval =
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(refresh_scheduler ?
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          refresh_scheduler->refresh_delay() :
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          policy::CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time last_refresh_time = refresh_scheduler ?
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      refresh_scheduler->last_refresh() : base::Time();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool no_error = store->status() == policy::CloudPolicyStore::STATUS_OK &&
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  client && client->status() == policy::DM_STATUS_SUCCESS;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetBoolean("error", !no_error);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString("status", status);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString("clientId", client_id);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString("username", username);
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString("refreshInterval",
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         ui::TimeFormat::LENGTH_SHORT,
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         refresh_interval));
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString("timeSinceLastRefresh", last_refresh_time.is_null() ?
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      l10n_util::GetStringUTF16(IDS_POLICY_NEVER_FETCHED) :
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED,
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             ui::TimeFormat::LENGTH_SHORT,
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             base::Time::NowFromSystemTime() -
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 last_refresh_time));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtractDomainFromUsername(base::DictionaryValue* dict) {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string username;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->GetString("username", &username);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!username.empty())
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString("domain", gaia::ExtractDomainName(username));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Utility function that returns a JSON serialization of the given |dict|.
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_ptr<base::StringValue> DictionaryToJSONString(
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::DictionaryValue* dict) {
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string json_string;
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::JSONWriter::WriteWithOptions(dict,
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     base::JSONWriter::OPTIONS_PRETTY_PRINT,
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                     &json_string);
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return make_scoped_ptr(new base::StringValue(json_string));
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Returns a copy of |value| with some values converted to a representation that
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// i18n_template.js will display in a nicer way.
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)scoped_ptr<base::Value> CopyAndConvert(const base::Value* value) {
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::DictionaryValue* dict = NULL;
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (value->GetAsDictionary(&dict))
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return DictionaryToJSONString(dict).PassAs<base::Value>();
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<base::Value> copy(value->DeepCopy());
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::ListValue* list = NULL;
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (copy->GetAsList(&list)) {
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (list->GetDictionary(i, &dict))
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        list->Set(i, DictionaryToJSONString(dict).release());
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return copy.Pass();
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An interface for querying the status of cloud policy.
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CloudPolicyStatusProvider {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CloudPolicyStatusProvider();
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~CloudPolicyStatusProvider();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets a callback to invoke upon status changes.
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetStatusChangeCallback(const base::Closure& callback);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetStatus(base::DictionaryValue* dict);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void NotifyStatusChange();
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Closure callback_;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CloudPolicyStatusProvider);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Status provider implementation that pulls cloud policy status from a
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// CloudPolicyCore instance provided at construction time. Also listens for
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// changes on that CloudPolicyCore and reports them through the status change
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// callback.
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CloudPolicyCoreStatusProvider
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public CloudPolicyStatusProvider,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public policy::CloudPolicyStore::Observer {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit CloudPolicyCoreStatusProvider(policy::CloudPolicyCore* core);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~CloudPolicyCoreStatusProvider();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // policy::CloudPolicyStore::Observer implementation.
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnStoreLoaded(policy::CloudPolicyStore* store) OVERRIDE;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnStoreError(policy::CloudPolicyStore* store) OVERRIDE;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Policy status is read from the CloudPolicyClient, CloudPolicyStore and
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CloudPolicyRefreshScheduler hosted by this |core_|.
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy::CloudPolicyCore* core_;
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CloudPolicyCoreStatusProvider);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A cloud policy status provider for user policy.
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class UserPolicyStatusProvider : public CloudPolicyCoreStatusProvider {
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UserPolicyStatusProvider(policy::CloudPolicyCore* core);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UserPolicyStatusProvider();
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CloudPolicyCoreStatusProvider implementation.
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetStatus(base::DictionaryValue* dict) OVERRIDE;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UserPolicyStatusProvider);
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A cloud policy status provider for device policy.
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DevicePolicyStatusProvider : public CloudPolicyCoreStatusProvider {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit DevicePolicyStatusProvider(
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      policy::BrowserPolicyConnectorChromeOS* connector);
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DevicePolicyStatusProvider();
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CloudPolicyCoreStatusProvider implementation.
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetStatus(base::DictionaryValue* dict) OVERRIDE;
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string domain_;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DevicePolicyStatusProvider);
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A cloud policy status provider that reads policy status from the policy core
31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// associated with the device-local account specified by |user_id| at
31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// construction time. The indirection via user ID and
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DeviceLocalAccountPolicyService is necessary because the device-local account
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// may go away any time behind the scenes, at which point the status message
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// text will indicate CloudPolicyStore::STATUS_BAD_STATE.
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DeviceLocalAccountPolicyStatusProvider
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public CloudPolicyStatusProvider,
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public policy::DeviceLocalAccountPolicyService::Observer {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeviceLocalAccountPolicyStatusProvider(
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const std::string& user_id,
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      policy::DeviceLocalAccountPolicyService* service);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DeviceLocalAccountPolicyStatusProvider();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CloudPolicyStatusProvider implementation.
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetStatus(base::DictionaryValue* dict) OVERRIDE;
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // policy::DeviceLocalAccountPolicyService::Observer implementation.
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void OnPolicyUpdated(const std::string& user_id) OVERRIDE;
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnDeviceLocalAccountsChanged() OVERRIDE;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::string user_id_;
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy::DeviceLocalAccountPolicyService* service_;
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountPolicyStatusProvider);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The JavaScript message handler for the chrome://policy page.
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass PolicyUIHandler : public content::NotificationObserver,
345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        public content::WebUIMessageHandler,
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        public policy::PolicyService::Observer {
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PolicyUIHandler();
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~PolicyUIHandler();
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // content::NotificationObserver implementation.
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void Observe(int type,
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       const content::NotificationSource& source,
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       const content::NotificationDetails& details) OVERRIDE;
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // content::WebUIMessageHandler implementation.
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void RegisterMessages() OVERRIDE;
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // policy::PolicyService::Observer implementation.
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnPolicyUpdated(const policy::PolicyNamespace& ns,
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const policy::PolicyMap& previous,
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const policy::PolicyMap& current) OVERRIDE;
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send a dictionary containing the names of all known policies to the UI.
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SendPolicyNames() const;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send information about the current policy values to the UI. For each policy
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // whose value has been set, a dictionary containing the value and additional
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // metadata is sent.
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SendPolicyValues() const;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send the status of cloud policy to the UI. For each scope that has cloud
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // policy enabled (device and/or user), a dictionary containing status
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // information is sent.
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SendStatus() const;
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Inserts a description of each policy in |policy_map| into |values|, using
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the optional errors in |errors| to determine the status of each policy.
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void GetPolicyValues(const policy::PolicyMap& policy_map,
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       policy::PolicyErrorMap* errors,
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       base::DictionaryValue* values) const;
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void GetChromePolicyValues(base::DictionaryValue* values) const;
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void HandleInitialized(const base::ListValue* args);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void HandleReloadPolicies(const base::ListValue* args);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnRefreshPoliciesDone() const;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy::PolicyService* GetPolicyService() const;
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool initialized_;
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string device_domain_;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Providers that supply status dictionaries for user and device policy,
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // respectively. These are created on initialization time as appropriate for
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the platform (Chrome OS / desktop) and type of policy that is in effect.
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<CloudPolicyStatusProvider> user_status_provider_;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<CloudPolicyStatusProvider> device_status_provider_;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  content::NotificationRegistrar registrar_;
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::WeakPtrFactory<PolicyUIHandler> weak_factory_;
4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PolicyUIHandler);
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CloudPolicyStatusProvider::CloudPolicyStatusProvider() {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CloudPolicyStatusProvider::~CloudPolicyStatusProvider() {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CloudPolicyStatusProvider::SetStatusChangeCallback(
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Closure& callback) {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_ = callback;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CloudPolicyStatusProvider::GetStatus(base::DictionaryValue* dict) {
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CloudPolicyStatusProvider::NotifyStatusChange() {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!callback_.is_null())
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback_.Run();
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CloudPolicyCoreStatusProvider::CloudPolicyCoreStatusProvider(
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy::CloudPolicyCore* core) : core_(core) {
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  core_->store()->AddObserver(this);
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(bartfab): Add an observer that watches for client errors. Observing
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // core_->client() directly is not safe as the client may be destroyed and
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (re-)created anytime if the user signs in or out on desktop platforms.
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CloudPolicyCoreStatusProvider::~CloudPolicyCoreStatusProvider() {
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  core_->store()->RemoveObserver(this);
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CloudPolicyCoreStatusProvider::OnStoreLoaded(
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy::CloudPolicyStore* store) {
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NotifyStatusChange();
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CloudPolicyCoreStatusProvider::OnStoreError(
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy::CloudPolicyStore* store) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NotifyStatusChange();
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UserPolicyStatusProvider::UserPolicyStatusProvider(
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy::CloudPolicyCore* core) : CloudPolicyCoreStatusProvider(core) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UserPolicyStatusProvider::~UserPolicyStatusProvider() {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UserPolicyStatusProvider::GetStatus(base::DictionaryValue* dict) {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!core_->store()->is_managed())
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetStatusFromCore(core_, dict);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtractDomainFromUsername(dict);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevicePolicyStatusProvider::DevicePolicyStatusProvider(
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy::BrowserPolicyConnectorChromeOS* connector)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : CloudPolicyCoreStatusProvider(
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            connector->GetDeviceCloudPolicyManager()->core()) {
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  domain_ = connector->GetEnterpriseDomain();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevicePolicyStatusProvider::~DevicePolicyStatusProvider() {
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevicePolicyStatusProvider::GetStatus(base::DictionaryValue* dict) {
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetStatusFromCore(core_, dict);
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString("domain", domain_);
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyStatusProvider::DeviceLocalAccountPolicyStatusProvider(
48190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& user_id,
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy::DeviceLocalAccountPolicyService* service)
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      : user_id_(user_id),
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        service_(service) {
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_->AddObserver(this);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceLocalAccountPolicyStatusProvider::
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~DeviceLocalAccountPolicyStatusProvider() {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_->RemoveObserver(this);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyStatusProvider::GetStatus(
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::DictionaryValue* dict) {
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const policy::DeviceLocalAccountPolicyBroker* broker =
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      service_->GetBrokerForUser(user_id_);
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (broker) {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetStatusFromCore(broker->core(), dict);
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetBoolean("error", true);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString("status",
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    policy::FormatStoreStatus(
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        policy::CloudPolicyStore::STATUS_BAD_STATE,
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        policy::CloudPolicyValidatorBase::VALIDATION_OK));
50590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    dict->SetString("username", std::string());
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtractDomainFromUsername(dict);
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetBoolean("publicAccount", true);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyStatusProvider::OnPolicyUpdated(
51290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& user_id) {
51390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (user_id == user_id_)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NotifyStatusChange();
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceLocalAccountPolicyStatusProvider::OnDeviceLocalAccountsChanged() {
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NotifyStatusChange();
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PolicyUIHandler::PolicyUIHandler()
5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    : initialized_(false),
5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      weak_factory_(this) {
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PolicyUIHandler::~PolicyUIHandler() {
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetPolicyService()->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this);
529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetPolicyService()->RemoveObserver(policy::POLICY_DOMAIN_EXTENSIONS, this);
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyUIHandler::RegisterMessages() {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* connector =
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (connector->IsEnterpriseManaged())
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_status_provider_.reset(new DevicePolicyStatusProvider(connector));
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const user_manager::UserManager* user_manager =
5406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get();
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (user_manager->IsLoggedInAsPublicAccount()) {
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy::DeviceLocalAccountPolicyService* local_account_service =
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        connector->GetDeviceLocalAccountPolicyService();
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (local_account_service) {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_status_provider_.reset(
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new DeviceLocalAccountPolicyStatusProvider(
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              user_manager->GetLoggedInUser()->email(), local_account_service));
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    policy::UserCloudPolicyManagerChromeOS* user_cloud_policy_manager =
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        policy::UserCloudPolicyManagerFactoryChromeOS::GetForProfile(
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            Profile::FromWebUI(web_ui()));
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (user_cloud_policy_manager) {
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_status_provider_.reset(
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new UserPolicyStatusProvider(user_cloud_policy_manager->core()));
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  policy::UserCloudPolicyManager* user_cloud_policy_manager =
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      policy::UserCloudPolicyManagerFactory::GetForBrowserContext(
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          web_ui()->GetWebContents()->GetBrowserContext());
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (user_cloud_policy_manager) {
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    user_status_provider_.reset(
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new UserPolicyStatusProvider(user_cloud_policy_manager->core()));
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!user_status_provider_.get())
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    user_status_provider_.reset(new CloudPolicyStatusProvider());
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device_status_provider_.get())
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_status_provider_.reset(new CloudPolicyStatusProvider());
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Closure update_callback(base::Bind(&PolicyUIHandler::SendStatus,
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           base::Unretained(this)));
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_status_provider_->SetStatusChangeCallback(update_callback);
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_status_provider_->SetStatusChangeCallback(update_callback);
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_CHROME, this);
578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_EXTENSIONS, this);
579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  registrar_.Add(this,
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 content::NotificationService::AllSources());
583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  registrar_.Add(this,
5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 content::NotificationService::AllSources());
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_ui()->RegisterMessageCallback(
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "initialized",
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PolicyUIHandler::HandleInitialized, base::Unretained(this)));
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_ui()->RegisterMessageCallback(
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "reloadPolicies",
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PolicyUIHandler::HandleReloadPolicies,
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)));
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PolicyUIHandler::Observe(int type,
597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              const content::NotificationSource& source,
598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              const content::NotificationDetails& details) {
5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(type == extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED ||
6005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         type == extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED);
601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SendPolicyNames();
602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SendPolicyValues();
603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyUIHandler::OnPolicyUpdated(const policy::PolicyNamespace& ns,
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const policy::PolicyMap& previous,
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const policy::PolicyMap& current) {
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendPolicyValues();
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyUIHandler::SendPolicyNames() const {
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue names;
613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui());
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  policy::SchemaRegistry* registry =
616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      policy::SchemaRegistryServiceFactory::GetForContext(
6176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          profile->GetOriginalProfile())->registry();
618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<policy::SchemaMap> schema_map = registry->schema_map();
619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Add Chrome policy names.
621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::DictionaryValue* chrome_policy_names = new base::DictionaryValue;
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  policy::PolicyNamespace chrome_ns(policy::POLICY_DOMAIN_CHROME, "");
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const policy::Schema* chrome_schema = schema_map->GetSchema(chrome_ns);
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (policy::Schema::Iterator it = chrome_schema->GetPropertiesIterator();
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       !it.IsAtEnd(); it.Advance()) {
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    chrome_policy_names->SetBoolean(it.key(), true);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  names.Set("chromePolicyNames", chrome_policy_names);
629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if !defined(OS_ANDROID) && !defined(OS_IOS)
631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Add extension policy names.
632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::DictionaryValue* extension_policy_names = new base::DictionaryValue;
633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  extensions::ExtensionSystem* extension_system =
635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile);
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const extensions::ExtensionSet* extensions =
637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      extension_system->extension_service()->extensions();
638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator it = extensions->begin();
640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       it != extensions->end(); ++it) {
641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const extensions::Extension* extension = it->get();
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Skip this extension if it's not an enterprise extension.
643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!extension->manifest()->HasPath(
6443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        extensions::manifest_keys::kStorageManagedSchema))
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      continue;
646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::DictionaryValue* extension_value = new base::DictionaryValue;
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    extension_value->SetString("name", extension->name());
648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const policy::Schema* schema =
649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        schema_map->GetSchema(policy::PolicyNamespace(
650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            policy::POLICY_DOMAIN_EXTENSIONS, extension->id()));
651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::DictionaryValue* policy_names = new base::DictionaryValue;
652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (schema && schema->valid()) {
653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Get policy names from the extension's policy schema.
654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Store in a map, not an array, for faster lookup on JS side.
655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      for (policy::Schema::Iterator prop = schema->GetPropertiesIterator();
656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)           !prop.IsAtEnd(); prop.Advance()) {
657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        policy_names->SetBoolean(prop.key(), true);
658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    extension_value->Set("policyNames", policy_names);
661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    extension_policy_names->Set(extension->id(), extension_value);
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  names.Set("extensionPolicyNames", extension_policy_names);
664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_ui()->CallJavascriptFunction("policy.Page.setPolicyNames", names);
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyUIHandler::SendPolicyValues() const {
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::DictionaryValue all_policies;
671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Add Chrome policy values.
673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::DictionaryValue* chrome_policies = new base::DictionaryValue;
674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetChromePolicyValues(chrome_policies);
675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  all_policies.Set("chromePolicies", chrome_policies);
676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if !defined(OS_ANDROID) && !defined(OS_IOS)
678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Add extension policy values.
679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  extensions::ExtensionSystem* extension_system =
680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      extensions::ExtensionSystem::Get(Profile::FromWebUI(web_ui()));
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const extensions::ExtensionSet* extensions =
682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      extension_system->extension_service()->extensions();
683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::DictionaryValue* extension_values = new base::DictionaryValue;
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator it = extensions->begin();
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       it != extensions->end(); ++it) {
687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const extensions::Extension* extension = it->get();
688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Skip this extension if it's not an enterprise extension.
689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!extension->manifest()->HasPath(
6903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        extensions::manifest_keys::kStorageManagedSchema))
691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      continue;
692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::DictionaryValue* extension_policies = new base::DictionaryValue;
693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    policy::PolicyNamespace policy_namespace = policy::PolicyNamespace(
694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        policy::POLICY_DOMAIN_EXTENSIONS, extension->id());
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    policy::PolicyErrorMap empty_error_map;
696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    GetPolicyValues(GetPolicyService()->GetPolicies(policy_namespace),
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    &empty_error_map, extension_policies);
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    extension_values->Set(extension->id(), extension_policies);
699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  all_policies.Set("extensionPolicies", extension_values);
701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  web_ui()->CallJavascriptFunction("policy.Page.setPolicyValues", all_policies);
703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PolicyUIHandler::GetPolicyValues(const policy::PolicyMap& map,
706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      policy::PolicyErrorMap* errors,
707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      base::DictionaryValue* values) const {
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (policy::PolicyMap::const_iterator entry = map.begin();
709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       entry != map.end(); ++entry) {
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::DictionaryValue* value = new base::DictionaryValue;
711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    value->Set("value", CopyAndConvert(entry->second.value).release());
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry->second.scope == policy::POLICY_SCOPE_USER)
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value->SetString("scope", "user");
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value->SetString("scope", "machine");
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (entry->second.level == policy::POLICY_LEVEL_RECOMMENDED)
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value->SetString("level", "recommended");
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value->SetString("level", "mandatory");
720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 error = errors->GetErrors(entry->first);
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!error.empty())
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value->SetString("error", error);
723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    values->Set(entry->first, value);
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
726eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PolicyUIHandler::GetChromePolicyValues(
728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::DictionaryValue* values) const {
729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  policy::PolicyService* policy_service = GetPolicyService();
730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  policy::PolicyMap map;
731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
732eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Make a copy that can be modified, since some policy values are modified
733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // before being displayed.
734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  map.CopyFrom(policy_service->GetPolicies(
735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())));
736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Get a list of all the errors in the policy values.
738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const policy::ConfigurationPolicyHandlerList* handler_list =
739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      g_browser_process->browser_policy_connector()->GetHandlerList();
740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  policy::PolicyErrorMap errors;
741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  handler_list->ApplyPolicySettings(map, NULL, &errors);
742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Convert dictionary values to strings for display.
744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  handler_list->PrepareForDisplaying(&map);
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  GetPolicyValues(map, &errors, values);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyUIHandler::SendStatus() const {
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> device_status(new base::DictionaryValue);
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_status_provider_->GetStatus(device_status.get());
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device_domain_.empty())
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    device_status->SetString("domain", device_domain_);
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> user_status(new base::DictionaryValue);
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_status_provider_->GetStatus(user_status.get());
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string username;
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_status->GetString("username", &username);
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!username.empty())
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    user_status->SetString("domain", gaia::ExtractDomainName(username));
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue status;
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device_status->empty())
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status.Set("device", device_status.release());
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!user_status->empty())
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status.Set("user", user_status.release());
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_ui()->CallJavascriptFunction("policy.Page.setStatus", status);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyUIHandler::HandleInitialized(const base::ListValue* args) {
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendPolicyNames();
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendPolicyValues();
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendStatus();
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyUIHandler::HandleReloadPolicies(const base::ListValue* args) {
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetPolicyService()->RefreshPolicies(
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PolicyUIHandler::OnRefreshPoliciesDone,
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PolicyUIHandler::OnRefreshPoliciesDone() const {
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_ui()->CallJavascriptFunction("policy.Page.reloadPoliciesDone");
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)policy::PolicyService* PolicyUIHandler::GetPolicyService() const {
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return policy::ProfilePolicyConnectorFactory::GetForProfile(
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Profile::FromWebUI(web_ui()))->policy_service();
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyUI::PolicyUI(content::WebUI* web_ui) : WebUIController(web_ui) {
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui->AddMessageHandler(new PolicyUIHandler);
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebUIDataSource::Add(Profile::FromWebUI(web_ui),
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                CreatePolicyUIHTMLSource());
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyUI::~PolicyUI() {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
799