Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Side by Side Diff: chrome/browser/ui/views/arc_app_dialog_view.cc

Issue 2529783002: arc: Implement uninstall confirmation dialog for Arc app. (Closed)
Patch Set: Address minor comments. Rebase. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/app_list/arc/arc_app_dialog.h"
6
7 #include "base/bind.h"
8 #include "base/macros.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/extensions/extension_util.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
13 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h"
14 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
15 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
16 #include "chrome/browser/ui/native_window_tracker.h"
17 #include "chrome/grit/generated_resources.h"
18 #include "components/constrained_window/constrained_window_views.h"
19 #include "components/strings/grit/components_strings.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/ui_base_types.h"
22 #include "ui/views/controls/image_view.h"
23 #include "ui/views/controls/label.h"
24 #include "ui/views/layout/layout_constants.h"
25 #include "ui/views/view.h"
26 #include "ui/views/widget/widget.h"
27 #include "ui/views/window/dialog_delegate.h"
28
29 namespace arc {
30
31 namespace {
32
33 const int kRightColumnWidth = 210;
34 const int kIconSize = 64;
35
36 using ArcAppConfirmCallback =
37 base::Callback<void(const std::string& app_id, Profile* profile)>;
38
39 class ArcAppDialogView : public views::DialogDelegateView,
40 public AppIconLoaderDelegate {
41 public:
42 ArcAppDialogView(Profile* profile,
43 AppListControllerDelegate* controller,
44 const std::string& app_id,
45 const base::string16& window_title,
46 const base::string16& heading_text,
47 const base::string16& confirm_button_text,
48 const base::string16& cancel_button_text,
49 ArcAppConfirmCallback confirm_callback);
50 ~ArcAppDialogView() override;
51
52 // Public method used for test only.
53 void ConfirmOrCancelForTest(bool confirm);
54
55 private:
56 // views::WidgetDelegate:
57 base::string16 GetWindowTitle() const override;
58 void DeleteDelegate() override;
59 ui::ModalType GetModalType() const override;
60
61 // views::View:
62 gfx::Size GetPreferredSize() const override;
63 void Layout() override;
64
65 // views::DialogDelegate:
66 base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
67 bool Accept() override;
68
69 // AppIconLoaderDelegate:
70 void OnAppImageUpdated(const std::string& app_id,
71 const gfx::ImageSkia& image) override;
72
73 // Constructs and shows the modal dialog widget.
74 void Show();
75
76 bool initial_setup_ = true;
77
78 views::ImageView* icon_view_ = nullptr;
79 views::Label* heading_view_ = nullptr;
80
81 std::unique_ptr<ArcAppIconLoader> icon_loader_;
82
83 Profile* const profile_;
84
85 AppListControllerDelegate* controller_;
86
87 gfx::NativeWindow parent_;
88
89 // Tracks whether |parent_| got destroyed.
90 std::unique_ptr<NativeWindowTracker> parent_window_tracker_;
91
92 const std::string app_id_;
93 const base::string16 window_title_;
94 const base::string16 confirm_button_text_;
95 const base::string16 cancel_button_text_;
96 ArcAppConfirmCallback confirm_callback_;
97
98 DISALLOW_COPY_AND_ASSIGN(ArcAppDialogView);
99 };
100
101 // Browertest use only. Global pointer of ArcAppDialogView which is shown.
102 ArcAppDialogView* g_current_arc_app_dialog_view = nullptr;
103
104 ArcAppDialogView::ArcAppDialogView(Profile* profile,
105 AppListControllerDelegate* controller,
106 const std::string& app_id,
107 const base::string16& window_title,
108 const base::string16& heading_text,
109 const base::string16& confirm_button_text,
110 const base::string16& cancel_button_text,
111 ArcAppConfirmCallback confirm_callback)
112 : profile_(profile),
113 controller_(controller),
114 app_id_(app_id),
115 window_title_(window_title),
116 confirm_button_text_(confirm_button_text),
117 cancel_button_text_(cancel_button_text),
118 confirm_callback_(confirm_callback) {
119 DCHECK(controller);
120 parent_ = controller_->GetAppListWindow();
121 if (parent_)
122 parent_window_tracker_ = NativeWindowTracker::Create(parent_);
123
124 icon_view_ = new views::ImageView();
125 icon_view_->SetImageSize(gfx::Size(kIconSize, kIconSize));
126 AddChildView(icon_view_);
127
128 heading_view_ = new views::Label(heading_text);
129 heading_view_->SetMultiLine(true);
130 heading_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
131 heading_view_->SetAllowCharacterBreak(true);
132 AddChildView(heading_view_);
133
134 icon_loader_.reset(new ArcAppIconLoader(profile_, kIconSize, this));
135 // The dialog will show once the icon is loaded.
136 icon_loader_->FetchImage(app_id_);
137 }
138
139 ArcAppDialogView::~ArcAppDialogView() {
140 DCHECK_EQ(this, g_current_arc_app_dialog_view);
141 g_current_arc_app_dialog_view = nullptr;
142 }
143
144 void ArcAppDialogView::ConfirmOrCancelForTest(bool confirm) {
145 if (confirm)
146 Accept();
147 else
148 Cancel();
149 GetWidget()->Close();
150 }
151
152 base::string16 ArcAppDialogView::GetWindowTitle() const {
153 return window_title_;
154 }
155
156 void ArcAppDialogView::DeleteDelegate() {
157 if (controller_)
158 controller_->OnCloseChildDialog();
159 DialogDelegateView::DeleteDelegate();
160 }
161
162 ui::ModalType ArcAppDialogView::GetModalType() const {
163 return ui::MODAL_TYPE_WINDOW;
164 }
165
166 // TODO(lgcheng@) The code below is copied from
167 // ExtensionUninstallDialogDelegateView sizing and layout code. Use
168 // LayoutManager to relace these manual layout. See crbug.com/670110.
169 gfx::Size ArcAppDialogView::GetPreferredSize() const {
170 int width = kRightColumnWidth;
171 width += kIconSize;
172 width += views::kButtonHEdgeMarginNew * 2;
173 width += views::kRelatedControlHorizontalSpacing;
174
175 int height = views::kPanelVertMargin * 2;
176 height += heading_view_->GetHeightForWidth(kRightColumnWidth);
177
178 return gfx::Size(width,
179 std::max(height, kIconSize + views::kPanelVertMargin * 2));
180 }
181
182 void ArcAppDialogView::Layout() {
183 int x = views::kButtonHEdgeMarginNew;
184 int y = views::kPanelVertMargin;
185
186 heading_view_->SizeToFit(kRightColumnWidth);
187
188 if (heading_view_->height() <= kIconSize) {
189 icon_view_->SetBounds(x, y, kIconSize, kIconSize);
190 x += kIconSize;
191 x += views::kRelatedControlHorizontalSpacing;
192
193 heading_view_->SetX(x);
194 heading_view_->SetY(y + (kIconSize - heading_view_->height()) / 2);
195 } else {
196 icon_view_->SetBounds(x, y + (heading_view_->height() - kIconSize) / 2,
197 kIconSize, kIconSize);
198 x += kIconSize;
199 x += views::kRelatedControlHorizontalSpacing;
200
201 heading_view_->SetX(x);
202 heading_view_->SetY(y);
203 }
204 }
205
206 base::string16 ArcAppDialogView::GetDialogButtonLabel(
207 ui::DialogButton button) const {
208 return button == ui::DIALOG_BUTTON_CANCEL ? cancel_button_text_
209 : confirm_button_text_;
210 }
211
212 bool ArcAppDialogView::Accept() {
213 confirm_callback_.Run(app_id_, profile_);
214 return true;
215 }
216
217 void ArcAppDialogView::OnAppImageUpdated(const std::string& app_id,
218 const gfx::ImageSkia& image) {
219 DCHECK_EQ(app_id, app_id_);
220 DCHECK(!image.isNull());
221
222 icon_view_->SetImage(image);
223
224 if (initial_setup_)
225 Show();
226 }
227
228 void ArcAppDialogView::Show() {
229 initial_setup_ = false;
230
231 // The parent window was killed before the icon was loaded.
232 if (parent_ && parent_window_tracker_->WasNativeWindowClosed()) {
233 Cancel();
234 DialogDelegateView::DeleteDelegate();
235 return;
236 }
237
238 if (controller_)
239 controller_->OnShowChildDialog();
240
241 g_current_arc_app_dialog_view = this;
242 constrained_window::CreateBrowserModalDialogViews(this, parent_)->Show();
243 }
244
245 } // namespace
246
247 void ShowArcAppUninstallDialog(Profile* profile,
248 AppListControllerDelegate* controller,
249 const std::string& app_id) {
250 ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile);
251 DCHECK(arc_prefs);
252 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
253 arc_prefs->GetApp(app_id);
254
255 if (!app_info)
256 return;
257
258 bool is_shortcut = app_info->shortcut;
259
260 base::string16 window_title = l10n_util::GetStringUTF16(
261 is_shortcut ? IDS_EXTENSION_UNINSTALL_PROMPT_TITLE
262 : IDS_APP_UNINSTALL_PROMPT_TITLE);
263
264 base::string16 heading_text = base::UTF8ToUTF16(l10n_util::GetStringFUTF8(
265 is_shortcut ? IDS_EXTENSION_UNINSTALL_PROMPT_HEADING
266 : IDS_ARC_APP_UNINSTALL_PROMPT_HEADING,
267 base::UTF8ToUTF16(app_info->name)));
268
269 base::string16 confirm_button_text = l10n_util::GetStringUTF16(
270 is_shortcut ? IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON
271 : IDS_EXTENSION_PROMPT_UNINSTALL_APP_BUTTON);
272
273 base::string16 cancel_button_text = l10n_util::GetStringUTF16(IDS_CANCEL);
274
275 new ArcAppDialogView(profile, controller, app_id, window_title, heading_text,
276 confirm_button_text, cancel_button_text,
277 base::Bind(UninstallArcApp));
278 }
279
280 bool IsArcAppDialogViewAliveForTest() {
281 return g_current_arc_app_dialog_view != nullptr;
282 }
283
284 bool CloseAppDialogViewAndConfirmForTest(bool confirm) {
285 if (!g_current_arc_app_dialog_view)
286 return false;
287
288 g_current_arc_app_dialog_view->ConfirmOrCancelForTest(confirm);
289 return true;
290 }
291
292 } // namespace arc
OLDNEW
« no previous file with comments | « chrome/browser/ui/app_list/arc/arc_app_utils.cc ('k') | chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698