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

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 Mike's comments. Run git cl format. 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));
msw 2016/11/30 23:26:57 nit: add a comment like "The dialog will show once
lgcheng 2016/12/01 02:05:56 Done.
135 icon_loader_->FetchImage(app_id_);
136 }
137
138 ArcAppDialogView::~ArcAppDialogView() {
139 DCHECK_EQ(this, g_current_arc_app_dialog_view);
140 g_current_arc_app_dialog_view = nullptr;
141 }
142
143 void ArcAppDialogView::ConfirmOrCancelForTest(bool confirm) {
144 if (confirm)
145 Accept();
146 else
147 Cancel();
148 this->GetWidget()->Close();
msw 2016/11/30 23:26:57 nit: is this needed? if so, can you remove "this->
lgcheng 2016/12/01 02:05:56 This is needed in test. Calling Accept() or Cancel
149 }
150
151 base::string16 ArcAppDialogView::GetWindowTitle() const {
152 return window_title_;
153 }
154
155 void ArcAppDialogView::DeleteDelegate() {
156 if (controller_)
157 controller_->OnCloseChildDialog();
158 DialogDelegateView::DeleteDelegate();
159 }
160
161 ui::ModalType ArcAppDialogView::GetModalType() const {
162 return ui::MODAL_TYPE_WINDOW;
163 }
164
165 gfx::Size ArcAppDialogView::GetPreferredSize() const {
166 int width = kRightColumnWidth;
167 width += kIconSize;
168 width += views::kButtonHEdgeMarginNew * 2;
169 width += views::kRelatedControlHorizontalSpacing;
170
171 int height = views::kPanelVertMargin * 2;
172 height += heading_view_->GetHeightForWidth(kRightColumnWidth);
173
174 return gfx::Size(width,
175 std::max(height, kIconSize + views::kPanelVertMargin * 2));
176 }
177
178 void ArcAppDialogView::Layout() {
179 int x = views::kButtonHEdgeMarginNew;
180 int y = views::kPanelVertMargin;
181
182 heading_view_->SizeToFit(kRightColumnWidth);
183
184 if (heading_view_->height() <= kIconSize) {
185 icon_view_->SetBounds(x, y, kIconSize, kIconSize);
186 x += kIconSize;
187 x += views::kRelatedControlHorizontalSpacing;
188
189 heading_view_->SetX(x);
190 heading_view_->SetY(y + (kIconSize - heading_view_->height()) / 2);
191 } else {
192 icon_view_->SetBounds(x, y + (heading_view_->height() - kIconSize) / 2,
193 kIconSize, kIconSize);
194 x += kIconSize;
195 x += views::kRelatedControlHorizontalSpacing;
196
197 heading_view_->SetX(x);
198 heading_view_->SetY(y);
199 }
200 }
201
202 base::string16 ArcAppDialogView::GetDialogButtonLabel(
203 ui::DialogButton button) const {
204 return button == ui::DIALOG_BUTTON_CANCEL ? cancel_button_text_
205 : confirm_button_text_;
206 }
207
208 bool ArcAppDialogView::Accept() {
209 confirm_callback_.Run(app_id_, profile_);
210 return true;
211 }
212
213 void ArcAppDialogView::OnAppImageUpdated(const std::string& app_id,
214 const gfx::ImageSkia& image) {
215 DCHECK_EQ(app_id, app_id_);
216
217 icon_view_->SetImage(image);
msw 2016/11/30 23:26:57 nit: DCHECK(!image.isNull()); above.
lgcheng 2016/12/01 02:05:56 Done.
218
219 if (initial_setup_)
220 Show();
221 }
222
223 void ArcAppDialogView::Show() {
224 initial_setup_ = false;
225
226 // Parent window is killed before icon is loaded.
msw 2016/11/30 23:26:57 nit: "The parent window was killed before the icon
lgcheng 2016/12/01 02:05:56 Done.
227 if (parent_ && parent_window_tracker_->WasNativeWindowClosed()) {
228 Cancel();
229 DialogDelegateView::DeleteDelegate();
230 return;
231 }
232
233 if (controller_)
234 controller_->OnShowChildDialog();
235
236 g_current_arc_app_dialog_view = this;
237 constrained_window::CreateBrowserModalDialogViews(this, parent_)->Show();
238 }
239
240 } // namespace
241
242 void ShowArcAppUninstallDialog(Profile* profile,
243 AppListControllerDelegate* controller,
244 const std::string& app_id) {
245 ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile);
246 DCHECK(arc_prefs);
247 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
248 arc_prefs->GetApp(app_id);
249
250 if (!app_info)
251 return;
252
253 bool is_shortcut = app_info->shortcut;
254
255 base::string16 window_title = l10n_util::GetStringUTF16(
256 is_shortcut ? IDS_EXTENSION_UNINSTALL_PROMPT_TITLE
257 : IDS_APP_UNINSTALL_PROMPT_TITLE);
258
259 base::string16 heading_text = base::UTF8ToUTF16(l10n_util::GetStringFUTF8(
260 is_shortcut ? IDS_EXTENSION_UNINSTALL_PROMPT_HEADING
261 : IDS_ARC_APP_UNINSTALL_PROMPT_HEADING,
262 base::UTF8ToUTF16(app_info->name)));
263
264 base::string16 confirm_button_text = l10n_util::GetStringUTF16(
265 is_shortcut ? IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON
266 : IDS_EXTENSION_PROMPT_UNINSTALL_APP_BUTTON);
267
268 base::string16 cancel_button_text = l10n_util::GetStringUTF16(IDS_CANCEL);
269
270 new ArcAppDialogView(profile, controller, app_id, window_title, heading_text,
271 confirm_button_text, cancel_button_text,
272 base::Bind(UninstallArcApp));
273 }
274
275 bool IsArcAppDialogViewAliveForTest() {
276 return g_current_arc_app_dialog_view != nullptr;
277 }
278
279 bool CloseAppDialogViewAndConfirmForTest(bool confirm) {
280 if (!g_current_arc_app_dialog_view)
281 return false;
282
283 g_current_arc_app_dialog_view->ConfirmOrCancelForTest(confirm);
284 return true;
285 }
286
287 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698