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

Unified Diff: components/open_from_clipboard/clipboard_recent_content_ios.mm

Issue 2782823003: Rewrite implementation of ClipboardRecentContent in Objective C. (Closed)
Patch Set: build.gn fix Created 3 years, 8 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: components/open_from_clipboard/clipboard_recent_content_ios.mm
diff --git a/components/open_from_clipboard/clipboard_recent_content_ios.mm b/components/open_from_clipboard/clipboard_recent_content_ios.mm
index 6d7d874c4bcf652d0ec09b56cf9a294db9da2d23..930a2747fdb6bb00f0c8aa5a79517b0615e3cee4 100644
--- a/components/open_from_clipboard/clipboard_recent_content_ios.mm
+++ b/components/open_from_clipboard/clipboard_recent_content_ios.mm
@@ -15,221 +15,78 @@
#include "base/metrics/user_metrics.h"
#include "base/strings/sys_string_conversions.h"
#include "base/sys_info.h"
+#import "components/open_from_clipboard/clipboard_recent_content_impl_ios.h"
+#import "net/base/mac/url_conversions.h"
#include "url/gurl.h"
+#include "url/url_constants.h"
-// Bridge that forwards UIApplicationDidBecomeActiveNotification notifications
-// to its delegate.
-@interface ApplicationDidBecomeActiveNotificationListenerBridge : NSObject
-
-// Initialize the ApplicationDidBecomeActiveNotificationListenerBridge with
-// |delegate| which must not be null.
-- (instancetype)initWithDelegate:(ClipboardRecentContentIOS*)delegate
- NS_DESIGNATED_INITIALIZER;
-
-- (instancetype)init NS_UNAVAILABLE;
-
-@end
-
-@implementation ApplicationDidBecomeActiveNotificationListenerBridge {
- ClipboardRecentContentIOS* _delegate;
-}
-
-- (instancetype)init {
- NOTREACHED();
- return nil;
-}
+namespace {
-- (instancetype)initWithDelegate:(ClipboardRecentContentIOS*)delegate {
- DCHECK(delegate);
- self = [super init];
- if (self) {
- _delegate = delegate;
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(didBecomeActive:)
- name:UIApplicationDidBecomeActiveNotification
- object:nil];
+// Schemes accepted by the ClipboardRecentContentIOS.
+const char* kAuthorizedSchemes[] = {
+ url::kHttpScheme, url::kHttpsScheme, url::kDataScheme, url::kAboutScheme,
+};
+
+// Get the list of authorized schemes.
+NSSet<NSString*>* getAuthorizedSchemeList(
+ const std::string& application_scheme) {
+ NSMutableSet<NSString*>* schemes = [NSMutableSet set];
+ for (size_t i = 0; i < arraysize(kAuthorizedSchemes); ++i) {
+ [schemes addObject:base::SysUTF8ToNSString(kAuthorizedSchemes[i])];
}
- return self;
-}
-
-- (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [super dealloc];
-}
-
-- (void)didBecomeActive:(NSNotification*)notification {
- if (_delegate) {
- _delegate->LoadFromUserDefaults();
- _delegate->UpdateIfNeeded();
+ if (!application_scheme.empty()) {
+ [schemes addObject:base::SysUTF8ToNSString(application_scheme)];
}
-}
-- (void)disconnect {
- _delegate = nullptr;
-}
-
-@end
-
-namespace {
-// Key used to store the pasteboard's current change count. If when resuming
-// chrome the pasteboard's change count is different from the stored one, then
-// it means that the pasteboard's content has changed.
-NSString* kPasteboardChangeCountKey = @"PasteboardChangeCount";
-// Key used to store the last date at which it was detected that the pasteboard
-// changed. It is used to evaluate the age of the pasteboard's content.
-NSString* kPasteboardChangeDateKey = @"PasteboardChangeDate";
-// Key used to store the hash of the content of the pasteboard. Whenever the
-// hash changed, the pasteboard content is considered to have changed.
-NSString* kPasteboardEntryMD5Key = @"PasteboardEntryMD5";
-
-// Compute a hash consisting of the first 4 bytes of the MD5 hash of |string|.
-// This value is used to detect pasteboard content change. Keeping only 4 bytes
-// is a privacy requirement to introduce collision and allow deniability of
-// having copied a given string.
-NSData* WeakMD5FromNSString(NSString* string) {
- unsigned char hash[CC_MD5_DIGEST_LENGTH];
- const std::string clipboard = base::SysNSStringToUTF8(string);
- const char* c_string = clipboard.c_str();
- CC_MD5(c_string, strlen(c_string), hash);
- NSData* data = [NSData dataWithBytes:hash length:4];
- return data;
+ return [schemes copy];
}
} // namespace
-bool ClipboardRecentContentIOS::GetRecentURLFromClipboard(GURL* url) {
- DCHECK(url);
- UpdateIfNeeded();
- if (GetClipboardContentAge() > kMaximumAgeOfClipboard) {
- return false;
- }
-
- GURL url_from_pasteboard = URLFromPasteboard();
- if (url_from_pasteboard.is_valid()) {
- *url = url_from_pasteboard;
- return true;
- }
- return false;
-}
+@interface ClipboardRecentContentDelegateImpl
+ : NSObject<ClipboardRecentContentDelegate>
+@end
-base::TimeDelta ClipboardRecentContentIOS::GetClipboardContentAge() const {
- return base::TimeDelta::FromSeconds(static_cast<int64_t>(
- -[last_pasteboard_change_date_ timeIntervalSinceNow]));
-}
+@implementation ClipboardRecentContentDelegateImpl
-void ClipboardRecentContentIOS::SuppressClipboardContent() {
- // User cleared the user data. The pasteboard entry must be removed from the
- // omnibox list. Force entry expiration by setting copy date to 1970.
- last_pasteboard_change_date_.reset(
- [[NSDate alloc] initWithTimeIntervalSince1970:0]);
- SaveToUserDefaults();
+- (void)onClipboardChanged {
+ base::RecordAction(base::UserMetricsAction("MobileOmniboxClipboardChanged"));
}
-void ClipboardRecentContentIOS::UpdateIfNeeded() {
- if (!HasPasteboardChanged())
- return;
-
- base::RecordAction(base::UserMetricsAction("MobileClipboardChanged"));
-
- GURL url_from_pasteboard = URLFromPasteboard();
- last_pasteboard_change_date_.reset([[NSDate date] retain]);
- last_pasteboard_change_count_ = [UIPasteboard generalPasteboard].changeCount;
- NSString* pasteboard_string = [[UIPasteboard generalPasteboard] string];
- if (!pasteboard_string) {
- pasteboard_string = @"";
- }
- NSData* MD5 = WeakMD5FromNSString(pasteboard_string);
- last_pasteboard_entry_md5_.reset([MD5 retain]);
- SaveToUserDefaults();
-}
+@end
ClipboardRecentContentIOS::ClipboardRecentContentIOS(
const std::string& application_scheme,
NSUserDefaults* group_user_defaults)
- : application_scheme_(application_scheme),
- shared_user_defaults_([group_user_defaults retain]) {
- last_pasteboard_change_count_ = NSIntegerMax;
- LoadFromUserDefaults();
-
- UpdateIfNeeded();
-
- // Makes sure |last_pasteboard_change_count_| was properly initialized.
- DCHECK_NE(last_pasteboard_change_count_, NSIntegerMax);
- notification_bridge_.reset(
- [[ApplicationDidBecomeActiveNotificationListenerBridge alloc]
- initWithDelegate:this]);
-}
-
-bool ClipboardRecentContentIOS::HasPasteboardChanged() const {
- // If |MD5Changed|, we know for sure there has been at least one pasteboard
- // copy since last time it was checked.
- // If the pasteboard content is still the same but the device was not
- // rebooted, the change count can be checked to see if it changed.
- // Note: due to a mismatch between the actual behavior and documentation, and
- // lack of consistency on different reboot scenarios, the change count cannot
- // be checked after a reboot.
- // See radar://21833556 for more information.
- NSInteger change_count = [UIPasteboard generalPasteboard].changeCount;
- bool change_count_changed = change_count != last_pasteboard_change_count_;
-
- bool not_rebooted = Uptime() > GetClipboardContentAge();
- if (not_rebooted)
- return change_count_changed;
-
- NSString* pasteboard_string = [[UIPasteboard generalPasteboard] string];
- if (!pasteboard_string) {
- pasteboard_string = @"";
- }
- NSData* md5 = WeakMD5FromNSString(pasteboard_string);
- BOOL md5_changed = ![md5 isEqualToData:last_pasteboard_entry_md5_];
+ : ClipboardRecentContentIOS([[ClipboardRecentContentImplIOS alloc]
+ initWithAuthorizedSchemes:getAuthorizedSchemeList(application_scheme)
+ userDefaults:group_user_defaults
+ delegate:[[ClipboardRecentContentDelegateImpl alloc]
+ init]]) {}
- return md5_changed;
-}
-
-ClipboardRecentContentIOS::~ClipboardRecentContentIOS() {
- [notification_bridge_ disconnect];
+ClipboardRecentContentIOS::ClipboardRecentContentIOS(
+ ClipboardRecentContentImplIOS* implementation) {
+ implementation_.reset(implementation);
}
-GURL ClipboardRecentContentIOS::URLFromPasteboard() {
- NSString* clipboard_string = [[UIPasteboard generalPasteboard] string];
- if (!clipboard_string) {
- return GURL::EmptyGURL();
- }
- const std::string clipboard = base::SysNSStringToUTF8(clipboard_string);
- GURL gurl = GURL(clipboard);
- if (gurl.is_valid()) {
- if (IsAppropriateSuggestion(gurl))
- return gurl;
- if (!application_scheme_.empty() &&
- gurl.SchemeIs(application_scheme_.c_str())) {
- return gurl;
- }
+bool ClipboardRecentContentIOS::GetRecentURLFromClipboard(GURL* url) {
+ DCHECK(url);
+ NSURL* url_from_pasteboard = [implementation_ recentURLFromClipboard];
+ GURL converted_url = net::GURLWithNSURL(url_from_pasteboard);
+ if (converted_url.is_valid()) {
+ *url = std::move(converted_url);
+ return true;
}
- return GURL::EmptyGURL();
+ return false;
}
-void ClipboardRecentContentIOS::LoadFromUserDefaults() {
- last_pasteboard_change_count_ =
- [shared_user_defaults_ integerForKey:kPasteboardChangeCountKey];
- last_pasteboard_change_date_.reset(
- [[shared_user_defaults_ objectForKey:kPasteboardChangeDateKey] retain]);
- last_pasteboard_entry_md5_.reset(
- [[shared_user_defaults_ objectForKey:kPasteboardEntryMD5Key] retain]);
-
- DCHECK(!last_pasteboard_change_date_ ||
- [last_pasteboard_change_date_ isKindOfClass:[NSDate class]]);
-}
+ClipboardRecentContentIOS::~ClipboardRecentContentIOS() {}
-void ClipboardRecentContentIOS::SaveToUserDefaults() {
- [shared_user_defaults_ setInteger:last_pasteboard_change_count_
- forKey:kPasteboardChangeCountKey];
- [shared_user_defaults_ setObject:last_pasteboard_change_date_
- forKey:kPasteboardChangeDateKey];
- [shared_user_defaults_ setObject:last_pasteboard_entry_md5_
- forKey:kPasteboardEntryMD5Key];
+base::TimeDelta ClipboardRecentContentIOS::GetClipboardContentAge() const {
+ return base::TimeDelta::FromSeconds(
+ static_cast<int64_t>([implementation_ clipboardContentAge]));
}
-base::TimeDelta ClipboardRecentContentIOS::Uptime() const {
- return base::SysInfo::Uptime();
+void ClipboardRecentContentIOS::SuppressClipboardContent() {
+ [implementation_ suppressClipboardContent];
}

Powered by Google App Engine
This is Rietveld 408576698