1
// Copyright 2007, Google Inc.
3
// Redistribution and use in source and binary forms, with or without
4
// modification, are permitted provided that the following conditions are met:
6
// 1. Redistributions of source code must retain the above copyright notice,
7
// this list of conditions and the following disclaimer.
8
// 2. Redistributions in binary form must reproduce the above copyright notice,
9
// this list of conditions and the following disclaimer in the documentation
10
// and/or other materials provided with the distribution.
11
// 3. Neither the name of Google Inc. nor the names of its contributors may be
12
// used to endorse or promote products derived from this software without
13
// specific prior written permission.
15
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
#include "gears/base/common/common.h"
27
#include "gears/base/common/js_types.h"
28
#include "gears/base/common/permissions_db.h"
29
#include "gears/base/common/string_utils.h"
30
#include "gears/base/common/url_utils.h"
31
#include "third_party/jsoncpp/json.h"
32
#include "gears/ui/common/html_dialog.h"
33
#include "gears/ui/common/permissions_dialog.h"
35
const char16 *kLocalDataDialogType = STRING16(L"localData");
36
const char16 *kLocationDataDialogType = STRING16(L"locationData");
38
// Internal helper functions.
39
static bool ToJsonStringValue(const char16 *str, Json::Value *json_value);
40
static bool PopulateArguments(const SecurityOrigin &origin,
41
const char16* dialog_type,
42
const char16 *custom_icon,
43
const char16 *custom_name,
44
const char16 *custom_message,
46
static const char16* DialogTypeForPermission(
47
PermissionsDB::PermissionType type);
49
//------------------------------------------------------------------------------
52
PermissionState PermissionsDialog::Prompt(
53
const SecurityOrigin &origin,
54
PermissionsDB::PermissionType type,
55
const CustomContent *custom_content,
56
BrowsingContext *browsing_context) {
57
// Note: Arguments and results are coupled to the values that
58
// permissions_dialog.html.m4 is expecting.
59
const char16* dialog_type = DialogTypeForPermission(type);
60
HtmlDialog dialog(browsing_context);
61
const char16 *custom_icon = NULL;
62
const char16 *custom_name = NULL;
63
const char16 *custom_message = NULL;
65
custom_icon = custom_content->custom_icon_url.c_str();
66
custom_name = custom_content->custom_name.c_str();
67
custom_message = custom_content->custom_message.c_str();
70
if (!PopulateArguments(origin,
80
const int kDialogWidth = 230;
81
const int kDialogHeight = 240;
83
const int kDialogWidth = 360;
84
const int kDialogHeight = 220;
86
const char16 *kDialogFile = STRING16(L"permissions_dialog.html");
88
HtmlDialogReturnValue retval =
89
dialog.DoModal(kDialogFile, kDialogWidth, kDialogHeight);
91
if (retval == HTML_DIALOG_FAILURE) {
92
LOG(("PermissionsDialog::Prompt() - Unexpected result."));
96
// Extract the dialog results.
100
if (retval == HTML_DIALOG_SUPPRESSED) {
103
} else if (dialog.result == Json::Value::null) {
104
// A null dialog.result is okay; it means the user closed the dialog
105
// instead of pressing any button.
109
if (!dialog.result["allow"].isBool() ||
110
!dialog.result["permanently"].isBool()) {
112
LOG(("PermissionsDialog::Prompt() - Unexpected result."));
116
allow = dialog.result["allow"].asBool();
117
permanently = dialog.result["permanently"].asBool();
120
// Store permanent results in the DB.
122
PermissionsDB::PermissionValue value =
123
allow ? PermissionsDB::PERMISSION_ALLOWED
124
: PermissionsDB::PERMISSION_DENIED;
125
PermissionsDB *permissions = PermissionsDB::GetDB();
127
permissions->SetPermission(origin, type, value);
131
// Convert the results to a PermissionState value.
133
if (permanently) return ALLOWED_PERMANENTLY;
134
else return ALLOWED_TEMPORARILY;
136
if (permanently) return DENIED_PERMANENTLY;
137
else return DENIED_TEMPORARILY;
141
PermissionsDialog::CustomContent* PermissionsDialog::CreateCustomContent(
142
JsCallContext *context) {
143
std::string16 site_name;
144
std::string16 image_url;
145
std::string16 extra_message;
147
JsArgument argv[] = {
148
{ JSPARAM_OPTIONAL, JSPARAM_STRING16, &site_name },
149
{ JSPARAM_OPTIONAL, JSPARAM_STRING16, &image_url },
150
{ JSPARAM_OPTIONAL, JSPARAM_STRING16, &extra_message },
152
context->GetArguments(ARRAYSIZE(argv), argv);
154
if (context->is_exception_set())
157
return new CustomContent(image_url.c_str(),
159
extra_message.c_str());
162
//------------------------------------------------------------------------------
163
// PermissionsDialog::CustomContent
165
PermissionsDialog::CustomContent::CustomContent(
166
const char16 *custom_icon_url_in,
167
const char16 *custom_name_in,
168
const char16 *custom_message_in)
169
: custom_icon_url(custom_icon_url_in),
170
custom_name(custom_name_in),
171
custom_message(custom_message_in) {
174
//------------------------------------------------------------------------------
177
static bool ToJsonStringValue(const char16 *str, Json::Value *json_value) {
182
if (!String16ToUTF8(str, &str8)) {
183
LOG(("PermissionsDialog::ToJsonStringValue: Could not convert string.\n"));
186
*json_value = Json::Value(str8);
191
static bool PopulateArguments(const SecurityOrigin &origin,
192
const char16* dialog_type,
193
const char16 *custom_icon,
194
const char16 *custom_name,
195
const char16 *custom_message,
198
assert(args->isObject());
199
assert(args->size() == 0);
200
assert(dialog_type && dialog_type[0]);
202
// Show something more user-friendly for kUnknownDomain.
203
// TODO(aa): This is needed by settings dialog too. Factor this out into a
205
std::string16 display_origin(origin.url());
206
if (origin.host() == kUnknownDomain) {
207
ReplaceAll(display_origin,
208
std::string16(kUnknownDomain),
209
std::string16(STRING16(L"<no domain>")));
212
if (!ToJsonStringValue(display_origin.c_str(), &((*args)["origin"]))) {
216
if (!ToJsonStringValue(dialog_type, &((*args)["dialogType"]))) {
220
if (custom_icon && custom_icon[0]) {
221
std::string16 full_icon_url;
222
if (!ResolveAndNormalize(origin.full_url().c_str(),
225
!ToJsonStringValue(full_icon_url.c_str(), &((*args)["customIcon"]))) {
230
if (custom_name && custom_name[0] &&
231
!ToJsonStringValue(custom_name, &((*args)["customName"]))) {
235
if (custom_message && custom_message[0] &&
236
!ToJsonStringValue(custom_message, &((*args)["customMessage"]))) {
243
static const char16* DialogTypeForPermission(
244
PermissionsDB::PermissionType type) {
246
case PermissionsDB::PERMISSION_LOCAL_DATA:
247
return kLocalDataDialogType;
248
case PermissionsDB::PERMISSION_LOCATION_DATA:
249
return kLocationDataDialogType;
251
LOG(("Invalid permission type.\n"));