~abreu-alexandre/oxide/add-ua-to-downloadrequested

« back to all changes in this revision

Viewing changes to shared/browser/oxide_web_view.cc

  • Committer: Chris Coulson
  • Date: 2014-09-01 13:49:18 UTC
  • mfrom: (694.1.23 ssl-status-api)
  • Revision ID: chris.coulson@canonical.com-20140901134918-3mqi09aln7uldf2l
Add WebView.securityStatus, WebView.blockedContent, WebView.setCanTemporarilyDisplayInsecureContent, WebView.setCanTemporarilyRunInsecureContent, SecurityStatus, CertificateError and SslCertificate API's. I'm still working on tests for these API's, but this shouldn't block webbrowser-app work

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
#include "content/public/common/menu_item.h"
54
54
#include "content/public/common/url_constants.h"
55
55
#include "content/public/common/web_preferences.h"
 
56
#include "ipc/ipc_message_macros.h"
56
57
#include "net/base/net_errors.h"
 
58
#include "net/ssl/ssl_info.h"
57
59
#include "third_party/WebKit/public/platform/WebGestureDevice.h"
58
60
#include "third_party/WebKit/public/web/WebInputEvent.h"
59
61
#include "ui/base/window_open_disposition.h"
64
66
#include "url/gurl.h"
65
67
#include "url/url_constants.h"
66
68
 
 
69
#include "shared/base/oxide_enum_flags.h"
67
70
#include "shared/base/oxide_event_utils.h"
68
71
#include "shared/browser/compositor/oxide_compositor.h"
69
72
#include "shared/browser/compositor/oxide_compositor_frame_handle.h"
70
73
#include "shared/common/oxide_content_client.h"
 
74
#include "shared/common/oxide_messages.h"
71
75
#include "shared/gl/oxide_shared_gl_context.h"
72
76
 
73
77
#include "oxide_browser_process_main.h"
193
197
  return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
194
198
}
195
199
 
 
200
CertError ToCertError(int error, net::X509Certificate* cert) {
 
201
  if (!net::IsCertificateError(error)) {
 
202
    return CERT_OK;
 
203
  }
 
204
 
 
205
  if (error == net::ERR_CERT_NO_REVOCATION_MECHANISM ||
 
206
      error == net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION) {
 
207
    // These aren't treated as hard errors
 
208
    return CERT_OK;
 
209
  }
 
210
 
 
211
  switch (error) {
 
212
    case net::ERR_CERT_COMMON_NAME_INVALID:
 
213
      return CERT_ERROR_BAD_IDENTITY;
 
214
    case net::ERR_CERT_DATE_INVALID: {
 
215
      if (cert && cert->HasExpired()) {
 
216
        return CERT_ERROR_EXPIRED;
 
217
      }
 
218
      return CERT_ERROR_DATE_INVALID;
 
219
    }
 
220
    case net::ERR_CERT_AUTHORITY_INVALID:
 
221
      return CERT_ERROR_AUTHORITY_INVALID;
 
222
    case net::ERR_CERT_CONTAINS_ERRORS:
 
223
    case net::ERR_CERT_INVALID:
 
224
      return CERT_ERROR_INVALID;
 
225
    case net::ERR_CERT_REVOKED:
 
226
      return CERT_ERROR_REVOKED;
 
227
    case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
 
228
    case net::ERR_CERT_WEAK_KEY:
 
229
      return CERT_ERROR_INSECURE;
 
230
    //case net::ERR_CERT_NON_UNIQUE_NAME:
 
231
    //case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION:
 
232
    default:
 
233
      return CERT_ERROR_GENERIC;
 
234
  }
 
235
}
 
236
 
 
237
OXIDE_MAKE_ENUM_BITWISE_OPERATORS(ContentType)
 
238
 
196
239
typedef std::map<BrowserContext*, std::set<WebView*> > WebViewsPerContextMap;
197
240
base::LazyInstance<WebViewsPerContextMap> g_web_view_per_context;
198
241
 
253
296
  }
254
297
}
255
298
 
 
299
void WebView::OnDidBlockDisplayingInsecureContent() {
 
300
  if (blocked_content_ & CONTENT_TYPE_MIXED_DISPLAY) {
 
301
    return;
 
302
  }
 
303
 
 
304
  blocked_content_ |= CONTENT_TYPE_MIXED_DISPLAY;
 
305
 
 
306
  OnContentBlocked();
 
307
}
 
308
 
 
309
void WebView::OnDidBlockRunningInsecureContent() {
 
310
  if (blocked_content_ & CONTENT_TYPE_MIXED_SCRIPT) {
 
311
    return;
 
312
  }
 
313
 
 
314
  blocked_content_ |= CONTENT_TYPE_MIXED_SCRIPT;
 
315
 
 
316
  OnContentBlocked();
 
317
}
 
318
 
256
319
size_t WebView::GetScriptMessageHandlerCount() const {
257
320
  return 0;
258
321
}
455
518
  }
456
519
}
457
520
 
 
521
void WebView::SSLStateChanged() {
 
522
  DCHECK(web_contents_);
 
523
 
 
524
  content::NavigationEntry* entry =
 
525
      web_contents_->GetController().GetVisibleEntry();
 
526
  if (!entry) {
 
527
    return;
 
528
  }
 
529
 
 
530
  SecurityStatus old_status = security_status_;
 
531
  security_status_.Update(entry->GetSSL());
 
532
 
 
533
  OnSecurityStatusChanged(old_status);
 
534
}
 
535
 
458
536
bool WebView::ShouldCreateWebContents(const GURL& target_url,
459
537
                                      WindowOpenDisposition disposition,
460
538
                                      bool user_gesture) {
551
629
}
552
630
 
553
631
void WebView::RenderProcessGone(base::TerminationStatus status) {
554
 
  geolocation_permission_requests_.CancelAllPending();
 
632
  permission_request_manager_.CancelAllPendingRequests();
555
633
}
556
634
 
557
635
void WebView::RenderViewHostChanged(content::RenderViewHost* old_host,
611
689
  DispatchLoadFailed(validated_url, error_code, error_description);
612
690
}
613
691
 
 
692
void WebView::DidNavigateMainFrame(
 
693
    const content::LoadCommittedDetails& details,
 
694
    const content::FrameNavigateParams& params) {
 
695
  if (details.is_navigation_to_different_page()) {
 
696
    permission_request_manager_.CancelAllPendingRequests();
 
697
 
 
698
    blocked_content_ = CONTENT_TYPE_NONE;
 
699
    OnContentBlocked();
 
700
  }
 
701
}
 
702
 
614
703
void WebView::DidFinishLoad(content::RenderFrameHost* render_frame_host,
615
704
                            const GURL& validated_url) {
616
705
  if (render_frame_host->GetParent()) {
633
722
 
634
723
void WebView::NavigationEntryCommitted(
635
724
    const content::LoadCommittedDetails& load_details) {
636
 
  if (load_details.is_navigation_to_different_page()) {
637
 
    geolocation_permission_requests_.CancelAllPending();
638
 
  }
639
725
  OnNavigationEntryCommitted();
640
726
}
641
727
 
674
760
  }
675
761
}
676
762
 
 
763
bool WebView::OnMessageReceived(const IPC::Message& msg,
 
764
                                content::RenderFrameHost* render_frame_host) {
 
765
  bool handled = true;
 
766
  IPC_BEGIN_MESSAGE_MAP(WebView, msg)
 
767
    IPC_MESSAGE_HANDLER(OxideHostMsg_DidBlockDisplayingInsecureContent,
 
768
                        OnDidBlockDisplayingInsecureContent)
 
769
    IPC_MESSAGE_HANDLER(OxideHostMsg_DidBlockRunningInsecureContent,
 
770
                        OnDidBlockRunningInsecureContent)
 
771
    IPC_MESSAGE_UNHANDLED(handled = false)
 
772
  IPC_END_MESSAGE_MAP()
 
773
 
 
774
  return handled;
 
775
}
 
776
 
677
777
void WebView::OnURLChanged() {}
678
778
void WebView::OnTitleChanged() {}
679
779
void WebView::OnIconChanged(const GURL& icon) {}
705
805
void WebView::OnWebPreferencesDestroyed() {}
706
806
 
707
807
void WebView::OnRequestGeolocationPermission(
708
 
    scoped_ptr<GeolocationPermissionRequest> request) {}
 
808
    const GURL& origin,
 
809
    const GURL& embedder,
 
810
    scoped_ptr<SimplePermissionRequest> request) {}
709
811
 
710
812
void WebView::OnUnhandledKeyboardEvent(
711
813
    const content::NativeWebKeyboardEvent& event) {}
746
848
void WebView::OnFocusedNodeChanged() {}
747
849
void WebView::OnSelectionBoundsChanged() {}
748
850
 
 
851
void WebView::OnSecurityStatusChanged(const SecurityStatus& old) {}
 
852
bool WebView::OnCertificateError(
 
853
    bool is_main_frame,
 
854
    CertError cert_error,
 
855
    const scoped_refptr<net::X509Certificate>& cert,
 
856
    const GURL& request_url,
 
857
    content::ResourceType resource_type,
 
858
    bool strict_enforcement,
 
859
    scoped_ptr<SimplePermissionRequest> request) {
 
860
  permission_request_manager_.AbortPendingRequest(request.get());
 
861
  return false;
 
862
}
 
863
void WebView::OnContentBlocked() {}
 
864
 
749
865
WebView::WebView()
750
866
    : text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
751
867
      show_ime_if_needed_(false),
758
874
      in_swap_(false),
759
875
      initial_preferences_(NULL),
760
876
      root_frame_(NULL),
761
 
      is_fullscreen_(false) {
 
877
      is_fullscreen_(false),
 
878
      blocked_content_(CONTENT_TYPE_NONE) {
762
879
  gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
763
880
}
764
881
 
781
898
}
782
899
 
783
900
WebView::~WebView() {
 
901
  permission_request_manager_.CancelAllPendingRequests();
 
902
 
784
903
  BrowserContext* context = GetBrowserContext();
785
904
  WebViewsPerContextMap::iterator it =
786
905
      g_web_view_per_context.Get().find(context);
922
1041
  return FromWebContents(content::WebContents::FromRenderViewHost(rvh));
923
1042
}
924
1043
 
 
1044
// static
 
1045
WebView* WebView::FromRenderFrameHost(content::RenderFrameHost* rfh) {
 
1046
  return FromWebContents(content::WebContents::FromRenderFrameHost(rfh));
 
1047
}
 
1048
 
925
1049
const GURL& WebView::GetURL() const {
926
1050
  if (!web_contents_) {
927
1051
    return initial_url_;
1183
1307
  return GetContainerBoundsDip().size();
1184
1308
}
1185
1309
 
 
1310
void WebView::SetCanTemporarilyDisplayInsecureContent(bool allow) {
 
1311
  if (!web_contents_) {
 
1312
    return;
 
1313
  }
 
1314
 
 
1315
  if (!(blocked_content_ & CONTENT_TYPE_MIXED_DISPLAY) && allow) {
 
1316
    return;
 
1317
  }
 
1318
 
 
1319
  if (allow) {
 
1320
    blocked_content_ &= ~CONTENT_TYPE_MIXED_DISPLAY;
 
1321
    OnContentBlocked();
 
1322
  }
 
1323
 
 
1324
  web_contents_->SendToAllFrames(
 
1325
      new OxideMsg_SetAllowDisplayingInsecureContent(MSG_ROUTING_NONE, allow));
 
1326
  web_contents_->GetMainFrame()->Send(
 
1327
      new OxideMsg_ReloadFrame(web_contents_->GetMainFrame()->GetRoutingID()));
 
1328
}
 
1329
 
 
1330
void WebView::SetCanTemporarilyRunInsecureContent(bool allow) {
 
1331
  if (!web_contents_) {
 
1332
    return;
 
1333
  }
 
1334
 
 
1335
  if (!(blocked_content_ & CONTENT_TYPE_MIXED_SCRIPT) && allow) {
 
1336
    return;
 
1337
  }
 
1338
 
 
1339
  if (allow) {
 
1340
    blocked_content_ &= ~CONTENT_TYPE_MIXED_DISPLAY;
 
1341
    blocked_content_ &= ~CONTENT_TYPE_MIXED_SCRIPT;
 
1342
    OnContentBlocked();
 
1343
  }
 
1344
 
 
1345
  web_contents_->SendToAllFrames(
 
1346
      new OxideMsg_SetAllowRunningInsecureContent(MSG_ROUTING_NONE, allow));
 
1347
  web_contents_->GetMainFrame()->Send(
 
1348
      new OxideMsg_ReloadFrame(web_contents_->GetMainFrame()->GetRoutingID()));
 
1349
}
 
1350
 
1186
1351
void WebView::ShowPopupMenu(const gfx::Rect& bounds,
1187
1352
                            int selected_item,
1188
1353
                            const std::vector<content::MenuItem>& items,
1208
1373
}
1209
1374
 
1210
1375
void WebView::RequestGeolocationPermission(
1211
 
    int id,
1212
1376
    const GURL& origin,
1213
 
    const base::Callback<void(bool)>& callback) {
1214
 
  scoped_ptr<GeolocationPermissionRequest> request(
1215
 
      new GeolocationPermissionRequest(
1216
 
        &geolocation_permission_requests_, id, origin,
1217
 
        web_contents_->GetLastCommittedURL().GetOrigin(), callback));
1218
 
  OnRequestGeolocationPermission(request.Pass());
 
1377
    const base::Callback<void(bool)>& callback,
 
1378
    base::Closure* cancel_callback) {
 
1379
  scoped_ptr<SimplePermissionRequest> request(
 
1380
      permission_request_manager_.CreateSimplePermissionRequest(
 
1381
        PERMISSION_REQUEST_TYPE_GEOLOCATION,
 
1382
        callback,
 
1383
        cancel_callback));
 
1384
  OnRequestGeolocationPermission(
 
1385
      origin,
 
1386
      web_contents_->GetLastCommittedURL().GetOrigin(),
 
1387
      request.Pass());
1219
1388
}
1220
1389
 
1221
 
void WebView::CancelGeolocationPermissionRequest(int id) {
1222
 
  geolocation_permission_requests_.CancelPendingRequestWithID(id);
 
1390
void WebView::AllowCertificateError(
 
1391
    content::RenderFrameHost* rfh,
 
1392
    int cert_error,
 
1393
    const net::SSLInfo& ssl_info,
 
1394
    const GURL& request_url,
 
1395
    content::ResourceType resource_type,
 
1396
    bool overridable,
 
1397
    bool strict_enforcement,
 
1398
    const base::Callback<void(bool)>& callback,
 
1399
    content::CertificateRequestResultType* result) {
 
1400
  WebFrame* frame = WebFrame::FromRenderFrameHost(rfh);
 
1401
  if (!frame) {
 
1402
    *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
 
1403
    return;
 
1404
  }
 
1405
 
 
1406
  DCHECK_EQ(frame->view(), this);
 
1407
  CHECK(!overridable || !strict_enforcement) <<
 
1408
      "overridable and strict_enforcement are expected to be mutually exclusive";
 
1409
 
 
1410
  scoped_ptr<SimplePermissionRequest> request;
 
1411
  if (overridable) {
 
1412
    request =
 
1413
        permission_request_manager_.CreateSimplePermissionRequest(
 
1414
          PERMISSION_REQUEST_TYPE_CERT_ERROR_OVERRIDE,
 
1415
          callback, NULL);
 
1416
  } else {
 
1417
    *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
 
1418
  }
 
1419
 
 
1420
  if (!OnCertificateError(!frame->parent(),
 
1421
                          ToCertError(cert_error, ssl_info.cert.get()),
 
1422
                          ssl_info.cert,
 
1423
                          request_url,
 
1424
                          resource_type,
 
1425
                          strict_enforcement,
 
1426
                          request.Pass())) {
 
1427
    *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
 
1428
  }
1223
1429
}
1224
1430
 
1225
1431
void WebView::UpdateWebPreferences() {