Skip to content

Commit

Permalink
Fix crash on iOS due to navigation proxy returning nullptr.
Browse files Browse the repository at this point in the history
Fixes crash on iOS in Cr117 by overriding the NavigationProxy to
use our own proxy instead of the Chromium one, when a webView is
not available (such is the case when syncing history or fetching
favicons).
  • Loading branch information
Brandon-T authored and mkarolin committed Sep 6, 2023
1 parent f89bc75 commit 387e9af
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 158 deletions.
18 changes: 18 additions & 0 deletions chromium_src/ios/web/web_state/ui/crw_web_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* Copyright (c) 2023 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_CHROMIUM_SRC_IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_H_

#define webViewNavigationProxy \
webViewNavigationProxy_ChromiumImpl; \
@property(weak, nonatomic, readonly) id<CRWWebViewNavigationProxy> \
webViewNavigationProxy

#include "src/ios/web/web_state/ui/crw_web_controller.h" // IWYU pragma: export

#undef webViewNavigationProxy

#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_H_
92 changes: 92 additions & 0 deletions chromium_src/ios/web/web_state/ui/crw_web_controller.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Copyright (c) 2023 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "ios/web/web_state/ui/crw_web_controller.h"
#include "net/base/mac/url_conversions.h"
#include "url/gurl.h"

#include <Webkit/Webkit.h>

#define webViewNavigationProxy webViewNavigationProxy_ChromiumImpl
#include "src/ios/web/web_state/ui/crw_web_controller.mm"
#undef webViewNavigationProxy

#pragma mark - BackForwardList

// Back Forward List for use in Navigation Manager
@interface BackForwardList : NSObject
@property(nonatomic, readonly, copy) WKBackForwardListItem* currentItem;
@property(nonatomic, readonly, copy) NSArray<WKBackForwardListItem*>* backList;
@property(nonatomic, readonly, copy)
NSArray<WKBackForwardListItem*>* forwardList;
@end

@implementation BackForwardList
@synthesize currentItem;
@synthesize backList;
@synthesize forwardList;

- (instancetype)init {
self = [super init];
return self;
}

- (WKBackForwardListItem*)itemAtIndex:(NSInteger)index {
if (index == 0) {
return currentItem;
}

if (index > 0 && forwardList.count) {
return forwardList[index - 1];
}

if (backList.count) {
return backList[backList.count + index];
}

return nullptr;
}

- (WKBackForwardListItem*)backItem {
return backList.lastObject;
}

- (WKBackForwardListItem*)forwardItem {
return forwardList.firstObject;
}
@end

#pragma mark - NavigationProxy

@interface NavigationProxy : NSObject <CRWWebViewNavigationProxy>
@end

@implementation NavigationProxy
- (instancetype)init {
if ((self = [super init])) {
}
return self;
}

- (NSURL*)URL {
return net::NSURLWithGURL(GURL(url::kAboutBlankURL));
}

- (WKBackForwardList*)backForwardList {
return (WKBackForwardList*)[[BackForwardList alloc] init];
}
@end

#pragma mark - CRWWebController

@implementation CRWWebController (Brave)
- (id<CRWWebViewNavigationProxy>)webViewNavigationProxy {
if (self.webView) {
return [self webViewNavigationProxy_ChromiumImpl];
}

return [[NavigationProxy alloc] init];
}
@end
158 changes: 0 additions & 158 deletions ios/browser/api/web/web_state/web_state_native.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,165 +26,7 @@
#error "This file requires ARC support."
#endif

#pragma mark - BackForwardList

// Back Forward List for use in Navigation Manager
@interface BackForwardList : NSObject
@property(nonatomic, readonly, copy) WKBackForwardListItem* currentItem;
@property(nonatomic, readonly, copy) NSArray<WKBackForwardListItem*>* backList;
@property(nonatomic, readonly, copy)
NSArray<WKBackForwardListItem*>* forwardList;
@end

@implementation BackForwardList
@synthesize currentItem;
@synthesize backList;
@synthesize forwardList;

- (instancetype)init {
self = [super init];
return self;
}

- (WKBackForwardListItem*)itemAtIndex:(NSInteger)index {
if (index == 0) {
return currentItem;
}

if (index > 0 && forwardList.count) {
return forwardList[index - 1];
}

if (backList.count) {
return backList[backList.count + index];
}

return nullptr;
}

- (WKBackForwardListItem*)backItem {
return backList.lastObject;
}

- (WKBackForwardListItem*)forwardItem {
return forwardList.firstObject;
}
@end

#pragma mark - NavigationProxy

@interface NavigationProxy : NSObject <CRWWebViewNavigationProxy>
@end

@implementation NavigationProxy
- (instancetype)init {
if ((self = [super init])) {
}
return self;
}

- (NSURL*)URL {
return net::NSURLWithGURL(GURL(url::kAboutBlankURL));
}

- (WKBackForwardList*)backForwardList {
return (WKBackForwardList*)[[BackForwardList alloc] init];
}
@end

#pragma mark - NavigationDelegate

namespace brave {
class NavigationDelegate : public web::NavigationManagerDelegate {
public:
NavigationDelegate(web::WebState* web_state);
~NavigationDelegate() override;
void ClearDialogs() override;
void RecordPageStateInNavigationItem() override;
void LoadCurrentItem(web::NavigationInitiationType type) override;
void LoadIfNecessary() override;
void Reload() override;
void OnNavigationItemCommitted(web::NavigationItem* item) override;
web::WebState* GetWebState() override;
void SetWebStateUserAgent(web::UserAgentType user_agent_type) override;
id<CRWWebViewNavigationProxy> GetWebViewNavigationProxy() const override;
void GoToBackForwardListItem(WKBackForwardListItem* wk_item,
web::NavigationItem* item,
web::NavigationInitiationType type,
bool has_user_gesture) override;

void RemoveWebView() override;
web::NavigationItemImpl* GetPendingItem() override;
GURL GetCurrentURL() const override;

private:
web::WebState* web_state_;
};

NavigationDelegate::~NavigationDelegate() = default;

id<CRWWebViewNavigationProxy> NavigationDelegate::GetWebViewNavigationProxy()
const {
return [[NavigationProxy alloc] init];
}

web::WebState* NavigationDelegate::GetWebState() {
return web_state_;
}

web::NavigationItemImpl* NavigationDelegate::GetPendingItem() {
return nullptr;
}

NavigationDelegate::NavigationDelegate(web::WebState* web_state)
: web_state_(web_state) {
// Not needed on iOS
}

void NavigationDelegate::ClearDialogs() {
// Not needed on iOS
}

void NavigationDelegate::RecordPageStateInNavigationItem() {
// Not needed on iOS
}

void NavigationDelegate::LoadCurrentItem(web::NavigationInitiationType type) {
// Not needed on iOS
}

void NavigationDelegate::LoadIfNecessary() {
// Not needed on iOS
}

void NavigationDelegate::Reload() {
// Not needed on iOS
}

void NavigationDelegate::OnNavigationItemCommitted(web::NavigationItem* item) {
// Not needed on iOS
}

void NavigationDelegate::SetWebStateUserAgent(
web::UserAgentType user_agent_type) {
// Not needed on iOS
}

void NavigationDelegate::GoToBackForwardListItem(
WKBackForwardListItem* wk_item,
web::NavigationItem* item,
web::NavigationInitiationType type,
bool has_user_gesture) {
// Not needed on iOS
}

void NavigationDelegate::RemoveWebView() {
// Not needed on iOS
}

GURL NavigationDelegate::GetCurrentURL() const {
return GURL();
}

#pragma mark NativeWebState

Expand Down

0 comments on commit 387e9af

Please sign in to comment.