1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/components/components_handler.h"
6
7 #include "base/bind.h"
8 #include "base/values.h"
9 #include "chrome/grit/generated_resources.h"
10 #include "components/update_client/crx_update_item.h"
11 #include "ui/base/l10n/l10n_util.h"
12
ComponentsHandler(component_updater::ComponentUpdateService * component_updater)13 ComponentsHandler::ComponentsHandler(
14 component_updater::ComponentUpdateService* component_updater)
15 : component_updater_(component_updater) {
16 DCHECK(component_updater_);
17 }
18 ComponentsHandler::~ComponentsHandler() = default;
19
RegisterMessages()20 void ComponentsHandler::RegisterMessages() {
21 web_ui()->RegisterMessageCallback(
22 "requestComponentsData",
23 base::BindRepeating(&ComponentsHandler::HandleRequestComponentsData,
24 base::Unretained(this)));
25
26 web_ui()->RegisterMessageCallback(
27 "checkUpdate", base::BindRepeating(&ComponentsHandler::HandleCheckUpdate,
28 base::Unretained(this)));
29 }
30
OnJavascriptAllowed()31 void ComponentsHandler::OnJavascriptAllowed() {
32 observer_.Add(component_updater_);
33 }
34
OnJavascriptDisallowed()35 void ComponentsHandler::OnJavascriptDisallowed() {
36 observer_.RemoveAll();
37 }
38
HandleRequestComponentsData(const base::ListValue * args)39 void ComponentsHandler::HandleRequestComponentsData(
40 const base::ListValue* args) {
41 AllowJavascript();
42 const base::Value& callback_id = args->GetList()[0];
43
44 base::DictionaryValue result;
45 result.Set("components", LoadComponents());
46 ResolveJavascriptCallback(callback_id, result);
47 }
48
49 // This function is called when user presses button from html UI.
50 // TODO(shrikant): We need to make this button available based on current
51 // state e.g. If component state is currently updating then we need to disable
52 // button. (https://code.google.com/p/chromium/issues/detail?id=272540)
HandleCheckUpdate(const base::ListValue * args)53 void ComponentsHandler::HandleCheckUpdate(const base::ListValue* args) {
54 if (args->GetSize() != 1) {
55 NOTREACHED();
56 return;
57 }
58
59 std::string component_id;
60 if (!args->GetString(0, &component_id)) {
61 NOTREACHED();
62 return;
63 }
64
65 OnDemandUpdate(component_id);
66 }
67
OnEvent(Events event,const std::string & id)68 void ComponentsHandler::OnEvent(Events event, const std::string& id) {
69 base::DictionaryValue parameters;
70 parameters.SetString("event", ComponentEventToString(event));
71 if (!id.empty()) {
72 if (event == Events::COMPONENT_UPDATED) {
73 update_client::CrxUpdateItem item;
74 if (component_updater_->GetComponentDetails(id, &item) && item.component)
75 parameters.SetString("version", item.component->version.GetString());
76 }
77 parameters.SetString("id", id);
78 }
79 FireWebUIListener("component-event", parameters);
80 }
81
ComponentEventToString(Events event)82 base::string16 ComponentsHandler::ComponentEventToString(Events event) {
83 switch (event) {
84 case Events::COMPONENT_CHECKING_FOR_UPDATES:
85 return l10n_util::GetStringUTF16(IDS_COMPONENTS_EVT_STATUS_STARTED);
86 case Events::COMPONENT_WAIT:
87 return l10n_util::GetStringUTF16(IDS_COMPONENTS_EVT_STATUS_SLEEPING);
88 case Events::COMPONENT_UPDATE_FOUND:
89 return l10n_util::GetStringUTF16(IDS_COMPONENTS_EVT_STATUS_FOUND);
90 case Events::COMPONENT_UPDATE_READY:
91 return l10n_util::GetStringUTF16(IDS_COMPONENTS_EVT_STATUS_READY);
92 case Events::COMPONENT_UPDATED:
93 return l10n_util::GetStringUTF16(IDS_COMPONENTS_EVT_STATUS_UPDATED);
94 case Events::COMPONENT_NOT_UPDATED:
95 return l10n_util::GetStringUTF16(IDS_COMPONENTS_EVT_STATUS_NOTUPDATED);
96 case Events::COMPONENT_UPDATE_ERROR:
97 return l10n_util::GetStringUTF16(IDS_COMPONENTS_EVT_STATUS_UPDATE_ERROR);
98 case Events::COMPONENT_UPDATE_DOWNLOADING:
99 return l10n_util::GetStringUTF16(IDS_COMPONENTS_EVT_STATUS_DOWNLOADING);
100 }
101 return l10n_util::GetStringUTF16(IDS_COMPONENTS_UNKNOWN);
102 }
103
ServiceStatusToString(update_client::ComponentState state)104 base::string16 ComponentsHandler::ServiceStatusToString(
105 update_client::ComponentState state) {
106 // TODO(sorin): handle kDownloaded. For now, just handle it as kUpdating.
107 switch (state) {
108 case update_client::ComponentState::kNew:
109 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_NEW);
110 case update_client::ComponentState::kChecking:
111 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_CHECKING);
112 case update_client::ComponentState::kCanUpdate:
113 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_UPDATE);
114 case update_client::ComponentState::kDownloadingDiff:
115 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_DNL_DIFF);
116 case update_client::ComponentState::kDownloading:
117 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_DNL);
118 case update_client::ComponentState::kUpdatingDiff:
119 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_UPDT_DIFF);
120 case update_client::ComponentState::kUpdating:
121 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_UPDATING);
122 case update_client::ComponentState::kDownloaded:
123 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_DOWNLOADED);
124 case update_client::ComponentState::kUpdated:
125 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_UPDATED);
126 case update_client::ComponentState::kUpToDate:
127 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_UPTODATE);
128 case update_client::ComponentState::kUpdateError:
129 return l10n_util::GetStringUTF16(IDS_COMPONENTS_SVC_STATUS_UPDATE_ERROR);
130 case update_client::ComponentState::kUninstalled: // Fall through.
131 case update_client::ComponentState::kRun:
132 case update_client::ComponentState::kLastStatus:
133 return l10n_util::GetStringUTF16(IDS_COMPONENTS_UNKNOWN);
134 }
135 return l10n_util::GetStringUTF16(IDS_COMPONENTS_UNKNOWN);
136 }
137
OnDemandUpdate(const std::string & component_id)138 void ComponentsHandler::OnDemandUpdate(const std::string& component_id) {
139 component_updater_->GetOnDemandUpdater().OnDemandUpdate(
140 component_id, component_updater::OnDemandUpdater::Priority::FOREGROUND,
141 component_updater::Callback());
142 }
143
LoadComponents()144 std::unique_ptr<base::ListValue> ComponentsHandler::LoadComponents() {
145 std::vector<std::string> component_ids;
146 component_ids = component_updater_->GetComponentIDs();
147
148 // Construct DictionaryValues to return to UI.
149 auto component_list = std::make_unique<base::ListValue>();
150 for (size_t j = 0; j < component_ids.size(); ++j) {
151 update_client::CrxUpdateItem item;
152 if (component_updater_->GetComponentDetails(component_ids[j], &item)) {
153 auto component_entry = std::make_unique<base::DictionaryValue>();
154 component_entry->SetString("id", component_ids[j]);
155 component_entry->SetString("status", ServiceStatusToString(item.state));
156 if (item.component) {
157 component_entry->SetString("name", item.component->name);
158 component_entry->SetString("version",
159 item.component->version.GetString());
160 }
161 component_list->Append(std::move(component_entry));
162 }
163 }
164
165 return component_list;
166 }
167