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

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: Clean up. 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/macros.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_util.h"
10 #include "chrome/browser/profiles/profile.h"
msw 2016/11/29 20:47:36 ditto nit: just use forward decl.
lgcheng 2016/11/30 19:28:47 Need this so that compile knows Profile is subclas
11 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
12 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h"
13 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
14 #include "chrome/browser/ui/native_window_tracker.h"
15 #include "chrome/grit/generated_resources.h"
16 #include "components/constrained_window/constrained_window_views.h"
17 #include "components/strings/grit/components_strings.h"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/ui_base_types.h"
20 #include "ui/views/controls/image_view.h"
21 #include "ui/views/controls/label.h"
22 #include "ui/views/layout/layout_constants.h"
23 #include "ui/views/view.h"
24 #include "ui/views/window/dialog_delegate.h"
25
26 namespace arc {
27
28 namespace {
29
30 const int kRightColumnWidth = 210;
31 const int kIconSize = 64;
32 const int kIconSourceSize = 32;
msw 2016/11/29 20:47:37 Can we just ask the loader for 64px and let it dea
lgcheng 2016/11/30 19:28:46 Make loader handles the resizing. Remove kIconSour
33
34 class ArcAppDialogView : public views::DialogDelegateView,
35 public AppIconLoaderDelegate {
36 public:
37 ArcAppDialogView(Profile* profile,
38 AppListControllerDelegate* controller,
39 const std::string& app_id,
40 const base::string16& window_title,
41 const base::string16& head_text,
msw 2016/11/29 20:47:36 nit: |heading_text| here and elsewhere
lgcheng 2016/11/30 19:28:46 Done.
42 const base::string16& confirm_button_text,
43 const base::string16& cancel_button_text,
44 ArcAppConfirmCallback& confirm_callback);
45 ~ArcAppDialogView() override;
46
47 // Public method to start dialog process.
msw 2016/11/29 20:47:36 nit: "Start loading the icon; the dialog will be s
lgcheng 2016/11/30 19:28:46 Remove this method. Inline in constructor.
48 void Execute();
49
50 // Public method used for test only.
51 void SelectOptionForTest(bool confirm);
msw 2016/11/29 20:47:37 optional nit: |ConfirmOrCancelForTest|
lgcheng 2016/11/30 19:28:46 Done.
52
53 private:
54 // views::WidgetDelegate:
55 base::string16 GetWindowTitle() const override { return window_title_; }
msw 2016/11/29 20:47:37 nit: define these out-of-line, to be consistent wi
lgcheng 2016/11/30 19:28:47 Done.
56 void DeleteDelegate() override;
57 ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_WINDOW; }
58
59 // views::View:
60 gfx::Size GetPreferredSize() const override;
61 void Layout() override;
62
63 // views::DialogDelegate:
64 base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
65 bool Cancel() override;
66 bool Accept() override;
67
68 // AppIconLoaderDelegate:
69 void OnAppImageUpdated(const std::string& app_id,
70 const gfx::ImageSkia& image) override;
71
72 // Popups the constrained window of confirmation dialog.
msw 2016/11/29 20:47:37 nit: "Constructs and shows the modal dialog widget
lgcheng 2016/11/30 19:28:47 Done.
73 void Show();
74
75 bool initial_setup_ = true;
76 gfx::ImageSkia icon_ = gfx::ImageSkia();
msw 2016/11/29 20:47:37 You don't need to explicitly invoke the default ct
lgcheng 2016/11/30 19:28:47 Done.
77
78 views::ImageView* icon_view_;
msw 2016/11/29 20:47:36 nit: = nullptr;
lgcheng 2016/11/30 19:28:47 Done.
79 views::Label* heading_view_;
msw 2016/11/29 20:47:37 nit: = nullptr;
lgcheng 2016/11/30 19:28:47 Done.
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& head_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 gfx::Size size(gfx::Size(kIconSize, kIconSize));
msw 2016/11/29 20:47:36 nit: "gfx::Size size(kIconSize, kIconSize);" or ju
lgcheng 2016/11/30 19:28:47 Done.
125 icon_view_ = new views::ImageView();
126 icon_view_->SetImageSize(size);
127 AddChildView(icon_view_);
128
129 heading_view_ = new views::Label(head_text);
130 heading_view_->SetMultiLine(true);
131 heading_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
132 heading_view_->SetAllowCharacterBreak(true);
133 AddChildView(heading_view_);
134 }
135
136 ArcAppDialogView::~ArcAppDialogView() {
137 g_current_arc_app_dialog_view = nullptr;
msw 2016/11/29 20:47:37 nit: DCHECK_EQ(this, g_current_arc_app_dialog_view
lgcheng 2016/11/30 19:28:46 Done.
138 }
139
140 void ArcAppDialogView::Execute() {
141 icon_loader_.reset(new ArcAppIconLoader(profile_, kIconSourceSize, this));
msw 2016/11/29 20:47:37 optional nit: inline this in the constructor?
lgcheng 2016/11/30 19:28:46 Done.
142 icon_loader_->FetchImage(app_id_);
143 }
144
145 void ArcAppDialogView::SelectOptionForTest(bool confirm) {
146 if (confirm)
147 Accept();
148 else
149 Cancel();
150 }
151
152 void ArcAppDialogView::DeleteDelegate() {
153 if (controller_) {
msw 2016/11/29 20:47:37 optional nit: remove curlies.
lgcheng 2016/11/30 19:28:47 Done.
154 controller_->OnCloseChildDialog();
155 }
156 delete this;
msw 2016/11/29 20:47:37 optional nit: call DialogDelegateView::DeleteDeleg
lgcheng 2016/11/30 19:28:46 Done.
157 }
158
159 gfx::Size ArcAppDialogView::GetPreferredSize() const {
msw 2016/11/29 20:47:36 nit: Can you use a LayoutManager instead of doing
lgcheng 2016/11/30 19:28:47 This part is identical with extension uninstall di
msw 2016/11/30 23:26:57 I see. Please file a bug to update both in a follo
lgcheng 2016/12/01 02:05:56 Done.
160 int width = kRightColumnWidth;
161 width += kIconSize;
162 width += views::kButtonHEdgeMarginNew * 2;
163 width += views::kRelatedControlHorizontalSpacing;
164
165 int height = views::kPanelVertMargin * 2;
166 height += heading_view_->GetHeightForWidth(kRightColumnWidth);
167
168 return gfx::Size(width,
169 std::max(height, kIconSize + views::kPanelVertMargin * 2));
170 }
171
172 void ArcAppDialogView::Layout() {
173 int x = views::kButtonHEdgeMarginNew;
174 int y = views::kPanelVertMargin;
175
176 heading_view_->SizeToFit(kRightColumnWidth);
177
178 if (heading_view_->height() <= kIconSize) {
179 icon_view_->SetBounds(x, y, kIconSize, kIconSize);
180 x += kIconSize;
181 x += views::kRelatedControlHorizontalSpacing;
182
183 heading_view_->SetX(x);
184 heading_view_->SetY(y + (kIconSize - heading_view_->height()) / 2);
185 } else {
186 icon_view_->SetBounds(x, y + (heading_view_->height() - kIconSize) / 2,
187 kIconSize, kIconSize);
188 x += kIconSize;
189 x += views::kRelatedControlHorizontalSpacing;
190
191 heading_view_->SetX(x);
192 heading_view_->SetY(y);
193 }
194 }
195
196 base::string16 ArcAppDialogView::GetDialogButtonLabel(
197 ui::DialogButton button) const {
198 return button == ui::DIALOG_BUTTON_CANCEL ? cancel_button_text_
199 : confirm_button_text_;
200 }
201
202 bool ArcAppDialogView::Cancel() {
msw 2016/11/29 20:47:37 Not needed; DialogDelegateView::Cancel already ret
lgcheng 2016/11/30 19:28:46 Done.
203 return true;
204 }
205
206 bool ArcAppDialogView::Accept() {
207 confirm_callback_.Run(app_id_, profile_);
208 return true;
209 }
210
211 void ArcAppDialogView::OnAppImageUpdated(const std::string& app_id,
212 const gfx::ImageSkia& image) {
213 DCHECK_EQ(app_id, app_id_);
214
215 if (image.isNull()) {
msw 2016/11/29 20:47:36 nit: remove curlies
lgcheng 2016/11/30 19:28:46 Redundant check removed.
216 icon_ = extensions::util::GetDefaultAppIcon();
msw 2016/11/29 20:47:37 Remove the |icon_| class member and just do: icon_
lgcheng 2016/11/30 19:28:47 Redundant image nullity check removed.
217 } else {
218 icon_ = image;
219 }
220
221 icon_view_->SetImage(icon_);
222
223 if (initial_setup_)
224 Show();
msw 2016/11/29 20:47:36 So we only create and show the dialog once icon lo
lgcheng 2016/11/30 19:28:46 There is safeguard in ArcAppIconLoader ensures tha
msw 2016/11/30 23:26:57 It would be even better to have a safeguard here,
225 }
226
227 void ArcAppDialogView::Show() {
228 initial_setup_ = false;
229
230 // Parent window is killed before icon_ is loaded.
231 if (parent_ && parent_window_tracker_->WasNativeWindowClosed()) {
232 Cancel();
msw 2016/11/29 20:47:37 Does |this| ArcAppDialogView leak here? Perhaps it
lgcheng 2016/11/30 19:28:47 Yes, there is a potential here. delete this added.
233 return;
234 }
235
236 if (controller_)
237 controller_->OnShowChildDialog();
238
239 g_current_arc_app_dialog_view = this;
240 constrained_window::CreateBrowserModalDialogViews(this, parent_)->Show();
241 }
242
243 void ShowDialogImpl(Profile* profile,
msw 2016/11/29 20:47:36 optional nit: inline this in ShowArcAppUninstallDi
lgcheng 2016/11/30 19:28:47 Done.
244 AppListControllerDelegate* controller,
245 const std::string& app_id,
246 const base::string16& window_title,
247 const base::string16& head_text,
248 const base::string16& confirm_button_text,
249 const base::string16& cancel_button_text,
250 ArcAppConfirmCallback& confirm_callback) {
251 ArcAppDialogView* arc_app_dialog = new ArcAppDialogView(
252 profile, controller, app_id, window_title, head_text, confirm_button_text,
253 cancel_button_text, confirm_callback);
254 arc_app_dialog->Execute();
255 }
256
257 } // namespace
258
259 void ShowArcAppUninstallDialog(Profile* profile,
260 AppListControllerDelegate* controller,
261 const std::string& app_id,
262 ArcAppConfirmCallback confirm_callback) {
msw 2016/11/29 20:47:37 nit: bind arc::UninstallArcApp in this function, n
lgcheng 2016/11/30 19:28:46 Done.
263 ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile);
264 DCHECK(arc_prefs);
265 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
266 arc_prefs->GetApp(app_id);
267
268 if (!app_info)
269 return;
270
271 bool is_shortcut = app_info->shortcut;
272
273 base::string16 window_title = l10n_util::GetStringUTF16(
274 is_shortcut ? IDS_EXTENSION_UNINSTALL_PROMPT_TITLE
275 : IDS_APP_UNINSTALL_PROMPT_TITLE);
276
277 base::string16 head_text = base::UTF8ToUTF16(l10n_util::GetStringFUTF8(
278 is_shortcut ? IDS_EXTENSION_UNINSTALL_PROMPT_HEADING
279 : IDS_ARC_APP_UNINSTALL_PROMPT_HEADING,
280 base::UTF8ToUTF16(app_info->name)));
281
282 base::string16 confirm_button_text = l10n_util::GetStringUTF16(
283 is_shortcut ? IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON
284 : IDS_EXTENSION_PROMPT_UNINSTALL_APP_BUTTON);
285
286 base::string16 cancel_button_text = l10n_util::GetStringUTF16(IDS_CANCEL);
287
288 return ShowDialogImpl(profile, controller, app_id, window_title, head_text,
289 confirm_button_text, cancel_button_text,
290 confirm_callback);
291 }
292
293 bool IsArcAppDialogViewAliveForTest() {
294 return g_current_arc_app_dialog_view != nullptr;
295 }
296
297 bool CloseAppDialogViewAndConfirmForTest(bool confirm) {
298 if (!g_current_arc_app_dialog_view)
299 return false;
300
301 g_current_arc_app_dialog_view->SelectOptionForTest(confirm);
302 return true;
303 }
304
305 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698