~ubuntu-branches/ubuntu/karmic/gears/karmic

« back to all changes in this revision

Viewing changes to gears/ui/common/permissions_dialog.cc

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Lesicnik
  • Date: 2009-04-30 19:15:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090430191525-0790sb5wzg8ou0xb
Tags: upstream-0.5.21.0~svn3334+dfsg
ImportĀ upstreamĀ versionĀ 0.5.21.0~svn3334+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2007, Google Inc.
 
2
//
 
3
// Redistribution and use in source and binary forms, with or without 
 
4
// modification, are permitted provided that the following conditions are met:
 
5
//
 
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.
 
14
//
 
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.
 
25
 
 
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"
 
34
 
 
35
const char16 *kLocalDataDialogType = STRING16(L"localData");
 
36
const char16 *kLocationDataDialogType = STRING16(L"locationData");
 
37
 
 
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,
 
45
                              Json::Value *args);
 
46
static const char16* DialogTypeForPermission(
 
47
    PermissionsDB::PermissionType type);
 
48
 
 
49
//------------------------------------------------------------------------------
 
50
// PermissionsDialog
 
51
 
 
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;
 
64
  if (custom_content) {
 
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();
 
68
  }
 
69
 
 
70
  if (!PopulateArguments(origin,
 
71
                         dialog_type,
 
72
                         custom_icon,
 
73
                         custom_name,
 
74
                         custom_message,
 
75
                         &dialog.arguments)) {
 
76
    return NOT_SET;
 
77
  }
 
78
 
 
79
#ifdef OS_WINCE
 
80
  const int kDialogWidth = 230;
 
81
  const int kDialogHeight = 240;
 
82
#else
 
83
  const int kDialogWidth = 360;
 
84
  const int kDialogHeight = 220;
 
85
#endif
 
86
  const char16 *kDialogFile = STRING16(L"permissions_dialog.html");
 
87
 
 
88
  HtmlDialogReturnValue retval =
 
89
      dialog.DoModal(kDialogFile, kDialogWidth, kDialogHeight);
 
90
 
 
91
  if (retval == HTML_DIALOG_FAILURE) {
 
92
    LOG(("PermissionsDialog::Prompt() - Unexpected result."));
 
93
    return NOT_SET;
 
94
  }
 
95
 
 
96
  // Extract the dialog results.
 
97
  bool allow;
 
98
  bool permanently;
 
99
 
 
100
  if (retval == HTML_DIALOG_SUPPRESSED) {
 
101
    allow = true;
 
102
    permanently = true;
 
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.
 
106
    allow = false;
 
107
    permanently = false;
 
108
  } else {
 
109
    if (!dialog.result["allow"].isBool() ||
 
110
        !dialog.result["permanently"].isBool()) {
 
111
      assert(false);
 
112
      LOG(("PermissionsDialog::Prompt() - Unexpected result."));
 
113
      return NOT_SET;
 
114
    }
 
115
 
 
116
    allow = dialog.result["allow"].asBool();
 
117
    permanently = dialog.result["permanently"].asBool();
 
118
  }
 
119
 
 
120
  // Store permanent results in the DB.
 
121
  if (permanently) {
 
122
    PermissionsDB::PermissionValue value = 
 
123
                       allow ? PermissionsDB::PERMISSION_ALLOWED
 
124
                             : PermissionsDB::PERMISSION_DENIED;
 
125
    PermissionsDB *permissions = PermissionsDB::GetDB();
 
126
    if (permissions) {
 
127
      permissions->SetPermission(origin, type, value);
 
128
    }
 
129
  }
 
130
 
 
131
  // Convert the results to a PermissionState value.
 
132
  if (allow) {
 
133
    if (permanently) return ALLOWED_PERMANENTLY;
 
134
    else return ALLOWED_TEMPORARILY;
 
135
  } else {
 
136
    if (permanently) return DENIED_PERMANENTLY;
 
137
    else return DENIED_TEMPORARILY;
 
138
  }
 
139
}
 
140
 
 
141
PermissionsDialog::CustomContent* PermissionsDialog::CreateCustomContent(
 
142
      JsCallContext *context) {
 
143
  std::string16 site_name;
 
144
  std::string16 image_url;
 
145
  std::string16 extra_message;
 
146
 
 
147
  JsArgument argv[] = {
 
148
    { JSPARAM_OPTIONAL, JSPARAM_STRING16, &site_name },
 
149
    { JSPARAM_OPTIONAL, JSPARAM_STRING16, &image_url },
 
150
    { JSPARAM_OPTIONAL, JSPARAM_STRING16, &extra_message },
 
151
  };
 
152
  context->GetArguments(ARRAYSIZE(argv), argv);
 
153
  
 
154
  if (context->is_exception_set())
 
155
    return NULL;
 
156
 
 
157
  return new CustomContent(image_url.c_str(),
 
158
                           site_name.c_str(),
 
159
                           extra_message.c_str());
 
160
}
 
161
 
 
162
//------------------------------------------------------------------------------
 
163
// PermissionsDialog::CustomContent
 
164
 
 
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) {
 
172
}
 
173
 
 
174
//------------------------------------------------------------------------------
 
175
// Internal
 
176
 
 
177
static bool ToJsonStringValue(const char16 *str, Json::Value *json_value) {
 
178
  assert(str);
 
179
  assert(json_value);
 
180
 
 
181
  std::string str8;
 
182
  if (!String16ToUTF8(str, &str8)) {
 
183
    LOG(("PermissionsDialog::ToJsonStringValue: Could not convert string.\n"));
 
184
    return false;
 
185
  }
 
186
  *json_value = Json::Value(str8);
 
187
  return true;
 
188
}
 
189
 
 
190
 
 
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,
 
196
                              Json::Value *args) {
 
197
  assert(args);
 
198
  assert(args->isObject());
 
199
  assert(args->size() == 0);
 
200
  assert(dialog_type && dialog_type[0]);
 
201
 
 
202
  // Show something more user-friendly for kUnknownDomain.
 
203
  // TODO(aa): This is needed by settings dialog too. Factor this out into a
 
204
  // common utility.
 
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>")));
 
210
  }
 
211
 
 
212
  if (!ToJsonStringValue(display_origin.c_str(), &((*args)["origin"]))) {
 
213
    return false;
 
214
  }
 
215
 
 
216
  if (!ToJsonStringValue(dialog_type, &((*args)["dialogType"]))) {
 
217
    return false;
 
218
  }
 
219
 
 
220
  if (custom_icon && custom_icon[0]) {
 
221
    std::string16 full_icon_url;
 
222
    if (!ResolveAndNormalize(origin.full_url().c_str(),
 
223
                             custom_icon,
 
224
                             &full_icon_url) ||
 
225
        !ToJsonStringValue(full_icon_url.c_str(), &((*args)["customIcon"]))) {
 
226
      return false;
 
227
    }
 
228
  }
 
229
 
 
230
  if (custom_name && custom_name[0] &&
 
231
      !ToJsonStringValue(custom_name, &((*args)["customName"]))) {
 
232
    return false;
 
233
  }
 
234
 
 
235
  if (custom_message && custom_message[0] &&
 
236
      !ToJsonStringValue(custom_message, &((*args)["customMessage"]))) {
 
237
    return false;
 
238
  }
 
239
 
 
240
  return true;
 
241
}
 
242
 
 
243
static const char16* DialogTypeForPermission(
 
244
    PermissionsDB::PermissionType type) {
 
245
  switch (type) {
 
246
    case PermissionsDB::PERMISSION_LOCAL_DATA:
 
247
      return kLocalDataDialogType;
 
248
    case PermissionsDB::PERMISSION_LOCATION_DATA:
 
249
      return kLocationDataDialogType;
 
250
    default:
 
251
      LOG(("Invalid permission type.\n"));
 
252
      assert(false);
 
253
      return NULL;
 
254
  };
 
255
}