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

Unified Diff: ios/web/web_state/ui/crw_wk_web_view_crash_detector.mm

Issue 1048613002: Upstream ios/web/web_state/ui support classes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months 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 side-by-side diff with in-line comments
Download patch
Index: ios/web/web_state/ui/crw_wk_web_view_crash_detector.mm
diff --git a/ios/web/web_state/ui/crw_wk_web_view_crash_detector.mm b/ios/web/web_state/ui/crw_wk_web_view_crash_detector.mm
new file mode 100644
index 0000000000000000000000000000000000000000..50f19239bbc864b22f01252b8e3523c3b48a87b3
--- /dev/null
+++ b/ios/web/web_state/ui/crw_wk_web_view_crash_detector.mm
@@ -0,0 +1,99 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/web/web_state/ui/crw_wk_web_view_crash_detector.h"
+
+#import "base/ios/weak_nsobject.h"
+#include "base/mac/scoped_block.h"
+#import "base/mac/scoped_nsobject.h"
+#import "base/strings/sys_string_conversions.h"
+
+namespace {
+
+// WKWebView property key path that is changed when web process is terminated.
+// The value of this property is not important, but its change may indicate
+// web process termination.
+NSString* const kCrashIndicatorKeyPath = @"scrollView.backgroundColor";
+
+// Returns |YES| if given |error| means that WKWebView process was terminated.
+BOOL IsWebViewTerminationError(NSError* error) {
+ DLOG_IF(WARNING, ![error.domain isEqualToString:WKErrorDomain]) <<
+ "Unexpected WKWebView error domain: " <<
+ base::SysNSStringToUTF8(error.domain);
+ // WKErrorUnknown is returned from unusable WKWebView so assume it's crashed.
+ return ((error.code == WKErrorWebContentProcessTerminated ||
+ error.code == WKErrorUnknown) &&
+ [error.domain isEqualToString:WKErrorDomain]);
+}
+
+} // namespace
+
+@interface CRWWKWebViewCrashDetector()
+
+// Checks WKWebView health by evaluating a simple JavaScript. If evaluation
+// fails with Termination Error then crash is reported.
+- (void)checkHealth;
+
+// Calls _crashHandler.
+- (void)reportCrash;
+
+@end
+
+@implementation CRWWKWebViewCrashDetector {
+ base::scoped_nsobject<WKWebView> _webView;
+ base::mac::ScopedBlock<ProceduralBlock> _crashHandler;
+}
+
+- (instancetype)init {
+ NOTREACHED();
+ return nil;
+}
+
+- (instancetype)initWithWebView:(WKWebView*)webView
+ crashHandler:(ProceduralBlock)handler {
+ DCHECK(webView);
+ DCHECK(handler);
+
+ if (self = [super init]) {
+ _webView.reset([webView retain]);
+ _crashHandler.reset([handler copy]);
+
+ // Once Web Process is terminated -[WKWebView _processDidExit] is called.
+ // That private method does different things inside including the change
+ // of scroll view's background color. We use that color change as an
+ // indication that WKWebView process may have crashed.
+ [_webView addObserver:self
+ forKeyPath:kCrashIndicatorKeyPath
+ options:0
+ context:nil];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [_webView removeObserver:self forKeyPath:kCrashIndicatorKeyPath];
+ [super dealloc];
+}
+
+- (void)observeValueForKeyPath:(NSString*)keyPath
+ ofObject:(id)object
+ change:(NSDictionary*)change
+ context:(void*)context {
+ DCHECK([keyPath isEqualToString:kCrashIndicatorKeyPath]);
+ [self checkHealth];
+}
+
+- (void)checkHealth {
+ base::WeakNSObject<CRWWKWebViewCrashDetector> weakSelf(self);
+ [_webView evaluateJavaScript:@"null" completionHandler:^(id, NSError* error) {
+ if (error && IsWebViewTerminationError(error))
+ [weakSelf reportCrash];
+ }];
+}
+
+- (void)reportCrash {
+ _crashHandler.get()();
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698