From 08918893a6b3e8b2833faaabcd09803021165a79 Mon Sep 17 00:00:00 2001 From: Xu Zhang Date: Fri, 4 Apr 2014 17:25:59 +0800 Subject: [PATCH 1/2] [Permission] Add permission dialog for user consent * A permission dialog should be shown to user to select whether to grant application to requested permission, when system policy for requested permission is prompt. --- application/common/permission_dialog.cc | 156 ++++++++++++++++++++++++ application/common/permission_dialog.h | 88 +++++++++++++ application/common/permission_types.h | 7 ++ application/xwalk_application.gypi | 2 + 4 files changed, 253 insertions(+) create mode 100644 application/common/permission_dialog.cc create mode 100644 application/common/permission_dialog.h diff --git a/application/common/permission_dialog.cc b/application/common/permission_dialog.cc new file mode 100644 index 0000000000..f2599ede31 --- /dev/null +++ b/application/common/permission_dialog.cc @@ -0,0 +1,156 @@ +// Copyright (c) 2013 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "xwalk/application/common/permission_dialog.h" + +namespace xwalk { +namespace application { + +const int kDialogHeight = 200; +const int kDialogWidth = 300; +// Width of the left column of the dialog when the extension requests +// permissions. +const int kPermissionsLeftColumnWidth = 250; + +CustomScrollableView::CustomScrollableView() {} +CustomScrollableView::~CustomScrollableView() {} + +void CustomScrollableView::Layout() { + SetBounds(x(), y(), width(), GetHeightForWidth(width())); + views::View::Layout(); +} + +PermissionDialog::PermissionDialog( + const std::string& app_id, const std::string& permission) { + LOG(INFO) << "Xu in PermissionDialog::PermissionDialog()"; + app_id_ = app_id; + request_permission_ = base::ASCIIToUTF16(permission); + prompt_type_ = GetPolicyEffect(permission); + Init(); +} + +PermissionDialog::~PermissionDialog() { +} + +bool PermissionDialog::Cancel() { + LOG(INFO) << "Xu clicked Cancel"; + show_dialog_callback_.Run(DENY_ALWAYS); + return true; +} + +bool PermissionDialog::Accept() { + LOG(INFO) << "Xu clicked OK"; + show_dialog_callback_.Run(ALLOW_ALWAYS); + return true; +} + +gfx::Size PermissionDialog::GetPreferredSize() { + return dialog_size_; +} + +base::string16 PermissionDialog::GetWindowTitle() const { + return title_; +} + +void PermissionDialog::Layout() { + scroll_view_->SetBounds(0, 0, width(), height()); + DialogDelegateView::Layout(); +} + +void PermissionDialog::OnPaint(gfx::Canvas* canvas) { + canvas->FillRect(GetLocalBounds(), SK_ColorWHITE); +} + +void PermissionDialog::ButtonPressed( + views::Button* sender, const ui::Event& event) { + LOG(INFO) << "Xu enter ButtonPressed"; + // TODO(Xu): Update permission value of application if needed + NOTREACHED(); + return; +} + +void PermissionDialog::SetShowDialogCallback( + const PermissionCallback& callback) { + LOG(INFO) << "Xu in PermissionDialog::set_callback"; + show_dialog_callback_ = callback; +} + +base::string16 PermissionDialog::GetDialogButtonLabel( + ui::DialogButton button) const { + if (button == ui::DIALOG_BUTTON_OK) + return base::ASCIIToUTF16("Permit"); + if (button == ui::DIALOG_BUTTON_CANCEL) { + return base::ASCIIToUTF16("Deny"); + } + NOTREACHED(); + return base::string16(); +} + +void PermissionDialog::Init() { + LOG(INFO) << "in permisisonDialog Init"; + scroll_view_ = new views::ScrollView(); + scroll_view_->set_hide_horizontal_scrollbar(true); + AddChildView(scroll_view_); + scrollable_ = new CustomScrollableView(); + scroll_view_->SetContents(scrollable_); + views::GridLayout* layout = views::GridLayout::CreatePanel(scrollable_); + scrollable_->SetLayoutManager(layout); + + int column_set_id = 0; + views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); + + column_set->AddColumn(views::GridLayout::LEADING, + views::GridLayout::FILL, + 0, // no resizing + views::GridLayout::USE_PREF, + 0, // no fixed width + kPermissionsLeftColumnWidth); + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + layout->StartRow(0, 0); + permission_header_label_ = + new views::Label(base::ASCIIToUTF16("Widget requires access to:")); + permission_header_label_->SetMultiLine(true); + permission_header_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + permission_header_label_->SizeToFit(0); + layout->AddView(permission_header_label_); + + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + layout->StartRow(0, 0); + permission_item_label_ = new views::Label(request_permission_); + permission_item_label_->SetMultiLine(true); + permission_item_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + permission_item_label_->SizeToFit(0); + layout->AddView(permission_item_label_); + + if (prompt_type_ == PROMPT_SESSION || prompt_type_ == PROMPT_BLANKET) { + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + layout->StartRow(0, 0); + switch (prompt_type_) { + case PROMPT_SESSION: + prompt_checkbox_ = new views::Checkbox( + base::ASCIIToUTF16("Remember for one run")); + break; + case PROMPT_BLANKET: + prompt_checkbox_ = new views::Checkbox( + base::ASCIIToUTF16("Keep setting as permanent")); + break; + default: + break; + } + layout->AddView(prompt_checkbox_); + } + + gfx::Size scrollable_size = scrollable_->GetPreferredSize(); + scrollable_->SetBoundsRect(gfx::Rect(scrollable_size)); + dialog_size_ = gfx::Size(kDialogWidth, kDialogHeight); +} + +PromptType PermissionDialog::GetPolicyEffect(const std::string& permission) { + // TODO(Xu): Get policy effect from system policy, currently just for + // testing, return PROMPT_SESSION + return PROMPT_SESSION; +} + +} // namespace application +} // namespace xwalk diff --git a/application/common/permission_dialog.h b/application/common/permission_dialog.h new file mode 100644 index 0000000000..52f5d9cf0e --- /dev/null +++ b/application/common/permission_dialog.h @@ -0,0 +1,88 @@ +// Copyright (c) 2013 Intel Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef XWALK_APPLICATION_COMMON_PERMISSION_DIALOG_H_ +#define XWALK_APPLICATION_COMMON_PERMISSION_DIALOG_H_ + +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/gfx/canvas.h" +#include "ui/views/controls/label.h" +#include "ui/base/ui_base_types.h" +#include "ui/events/event.h" +#include "ui/views/controls/button/checkbox.h" +#include "ui/views/controls/button/label_button.h" +#include "ui/views/controls/scroll_view.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/layout/layout_constants.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" +#include "ui/views/window/dialog_delegate.h" +#include "xwalk/application/common/permission_types.h" +#include "xwalk/application/browser/application_storage_impl.h" + +namespace xwalk { +namespace application { +// A custom scrollable view implementation for the dialog. +class CustomScrollableView : public views::View { + public: + CustomScrollableView(); + virtual ~CustomScrollableView(); + + private: + virtual void Layout() OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(CustomScrollableView); +}; + +class PermissionDialog : public views::DialogDelegateView, + public views::ButtonListener { + public: + PermissionDialog(const std::string& app_id, const std::string& permission); + virtual ~PermissionDialog(); + virtual bool Cancel() OVERRIDE; + virtual bool Accept() OVERRIDE; + + // DialogDelegateView overrides: + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual base::string16 GetWindowTitle() const OVERRIDE; + virtual base::string16 GetDialogButtonLabel( + ui::DialogButton button) const OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual void Layout() OVERRIDE; + + // ButtonListener override: + virtual void ButtonPressed(views::Button* sender, + const ui::Event& event) OVERRIDE; + + void SetShowDialogCallback(const PermissionCallback& callback); + + private: + void Init(); + PromptType GetPolicyEffect(const std::string& permission); + + std::string app_id_; + base::string16 title_; + base::string16 request_permission_; + PermissionCallback show_dialog_callback_; + views::Label* permission_item_label_; + views::Label* permission_header_label_; + views::Checkbox* prompt_checkbox_; + views::ScrollView* scroll_view_; + // The container view for the scroll view. + CustomScrollableView* scrollable_; + // The preferred size of the dialog. + gfx::Size dialog_size_; + PromptType prompt_type_; + + DISALLOW_COPY_AND_ASSIGN(PermissionDialog); +}; + +} // namespace application +} // namespace xwalk + +#endif // XWALK_APPLICATION_COMMON_PERMISSION_DIALOG_H_ diff --git a/application/common/permission_types.h b/application/common/permission_types.h index 9c2c5296cf..0e65baf099 100644 --- a/application/common/permission_types.h +++ b/application/common/permission_types.h @@ -22,6 +22,13 @@ enum PermissionType { PERSISTENT_PERMISSION, }; +enum PromptType { + UNSET_PROMPT_TYPE = -1, + PROMPT_ONESHOT = 0, + PROMPT_SESSION, + PROMPT_BLANKET +}; + enum RuntimePermission { ALLOW_ONCE = 0, ALLOW_SESSION, diff --git a/application/xwalk_application.gypi b/application/xwalk_application.gypi index ae83293299..c6e5195e9b 100644 --- a/application/xwalk_application.gypi +++ b/application/xwalk_application.gypi @@ -73,6 +73,8 @@ 'common/manifest_handlers/warp_handler.h', 'common/manifest_handlers/widget_handler.cc', 'common/manifest_handlers/widget_handler.h', + 'common/permission_dialog.cc', + 'common/permission_dialog.h', 'common/permission_policy_manager.cc', 'common/permission_policy_manager.h', 'common/permission_types.h', From 314e955269a2ca995cb0f86233896abb226fd5a7 Mon Sep 17 00:00:00 2001 From: Xu Zhang Date: Fri, 4 Apr 2014 18:23:51 +0800 Subject: [PATCH 2/2] [Permission] support to pop up a permission dialog * If the request permission need user consent, it will pop up a dialog for user select --- application/browser/application_service.cc | 18 +++++++++++++++++- application/browser/application_service.h | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/application/browser/application_service.cc b/application/browser/application_service.cc index 1469114ff4..0abda6bd86 100644 --- a/application/browser/application_service.cc +++ b/application/browser/application_service.cc @@ -13,9 +13,11 @@ #include "base/message_loop/message_loop.h" #include "base/path_service.h" #include "base/version.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" +#include "ui/views/widget/widget.h" #include "xwalk/application/browser/application_event_manager.h" #include "xwalk/application/browser/application.h" #include "xwalk/application/browser/application_storage.h" @@ -24,6 +26,7 @@ #include "xwalk/application/common/application_file_util.h" #include "xwalk/application/common/event_names.h" #include "xwalk/application/common/permission_policy_manager.h" +#include "xwalk/application/common/permission_dialog.h" #include "xwalk/runtime/browser/runtime_context.h" #include "xwalk/runtime/browser/runtime.h" #include "xwalk/runtime/browser/xwalk_runner.h" @@ -33,6 +36,7 @@ #include "xwalk/application/browser/installer/tizen/service_package_installer.h" #endif +using content::BrowserThread; namespace xwalk { namespace application { @@ -674,7 +678,9 @@ void ApplicationService::CheckAPIAccessControl(const std::string& app_id, // TODO(Bai): We needed to pop-up a dialog asking user to chose one from // either allow/deny for session/one shot/forever. Then, we need to update // the session and persistent policy accordingly. - callback.Run(UNDEFINED_RUNTIME_PERM); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&ApplicationService::ShowPermissionDialog, + base::Unretained(this), app_id, permission_name, callback)); return; } if (perm == ALLOW) { @@ -705,5 +711,15 @@ bool ApplicationService::RegisterPermissions(const std::string& app_id, return app->RegisterPermissions(extension_name, perm_table); } +void ApplicationService::ShowPermissionDialog(const std::string& app_id, + const std::string& permission, + const PermissionCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + PermissionDialog* dialog_ = new PermissionDialog(app_id, permission); + dialog_->SetShowDialogCallback(callback); + views::Widget::CreateWindow(dialog_)->Show(); +} + } // namespace application } // namespace xwalk diff --git a/application/browser/application_service.h b/application/browser/application_service.h index bed771150a..78c59304ac 100644 --- a/application/browser/application_service.h +++ b/application/browser/application_service.h @@ -89,6 +89,10 @@ class ApplicationService : public Application::Observer { // Implementation of Application::Observer. virtual void OnApplicationTerminated(Application* app) OVERRIDE; + // Show Permission dialog to end user + void ShowPermissionDialog(const std::string& app_id, + const std::string& permission, + const PermissionCallback& callback); xwalk::RuntimeContext* runtime_context_; ApplicationStorage* application_storage_;