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

Unified Diff: components/open_from_clipboard/clipboard_recent_content_ios.mm

Issue 2782823003: Rewrite implementation of ClipboardRecentContent in Objective C. (Closed)
Patch Set: address comments Created 3 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: 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 0ef8e97124dfac6e7a593f981902839c67878ac0..394f46833ea1df534e1e6e451f52c3ff2071f884 100644
--- a/components/open_from_clipboard/clipboard_recent_content_ios.mm
+++ b/components/open_from_clipboard/clipboard_recent_content_ios.mm
@@ -15,233 +15,83 @@
#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_ios_impl.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;
-}
-
-- (instancetype)initWithDelegate:(ClipboardRecentContentIOS*)delegate {
- DCHECK(delegate);
- self = [super init];
- if (self) {
- _delegate = delegate;
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(didBecomeActive:)
- name:UIApplicationDidBecomeActiveNotification
- object:nil];
- }
- return self;
+namespace {
+// Schemes accepted by the ClipboardRecentContentIOS.
+const char* kAuthorizedSchemes[] = {
+ url::kHttpScheme, url::kHttpsScheme, url::kDataScheme, url::kAboutScheme,
+};
}
-- (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [super dealloc];
-}
+@interface ClipboardRecentContentMetricsDelegateImpl
+ : NSObject<ClipboardRecentContentMetricsDelegate>
+@end
-- (void)didBecomeActive:(NSNotification*)notification {
- if (_delegate) {
- _delegate->LoadFromUserDefaults();
- _delegate->UpdateIfNeeded();
- }
-}
+@implementation ClipboardRecentContentMetricsDelegateImpl
-- (void)disconnect {
- _delegate = nullptr;
+- (void)onClipboardChanged {
+ base::RecordAction(base::UserMetricsAction("MobileOmniboxClipboardChanged"));
sdefresne 2017/04/03 09:27:16 (outside of the CL) I think action that is recorde
}
@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";
-base::TimeDelta kMaximumAgeOfClipboard = base::TimeDelta::FromHours(3);
-// Schemes accepted by the ClipboardRecentContentIOS.
-const char* kAuthorizedSchemes[] = {
- url::kHttpScheme,
- url::kHttpsScheme,
- url::kDataScheme,
- url::kAboutScheme,
-};
+ClipboardRecentContentIOS::ClipboardRecentContentIOS(
+ const std::string& application_scheme,
+ NSUserDefaults* group_user_defaults) {
+ ClipboardRecentContentMetricsDelegateImpl* metricsDelegate =
sdefresne 2017/04/03 09:27:16 s/metricsDelegate/metrics_delegate/.
lody 2017/04/04 13:42:18 Done.
+ [[ClipboardRecentContentMetricsDelegateImpl alloc] init];
-// 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;
+ implementation_.reset([[ClipboardRecentContentIOSImpl alloc]
+ initWithDelegate:metricsDelegate
+ authorizedSchemes:GetAuthorizedSchemeList(application_scheme)
+ userDefaults:group_user_defaults]);
}
-} // 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;
+ NSURL* nsurl = [implementation_ getRecentURLFromClipboard];
sdefresne 2017/04/03 09:27:16 url_from_pasteboard
lody 2017/04/04 13:42:18 Done.
+ if (nsurl != nil) {
sdefresne 2017/04/03 09:27:16 No need to test nsurl for nil, net::GURLWithNSURL(
lody 2017/04/04 13:42:18 Done.
+ GURL tempUrl = net::GURLWithNSURL(nsurl);
sdefresne 2017/04/03 09:27:16 NSURL* url_from_pasteboard = [implementation_ getR
lody 2017/04/04 13:42:18 Done.
+ if (tempUrl.is_valid()) {
+ *url = std::move(tempUrl);
+ return true;
+ }
}
return false;
}
+ClipboardRecentContentIOS::~ClipboardRecentContentIOS() {}
+
base::TimeDelta ClipboardRecentContentIOS::GetClipboardContentAge() const {
- return base::TimeDelta::FromSeconds(static_cast<int64_t>(
- -[last_pasteboard_change_date_ timeIntervalSinceNow]));
+ return base::TimeDelta::FromSeconds(
+ static_cast<int64_t>([implementation_ getClipboardContentAge]));
}
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 ClipboardRecentContentIOS::UpdateIfNeeded() {
- if (!HasPasteboardChanged())
- return;
-
- base::RecordAction(base::UserMetricsAction("MobileOmniboxClipboardChanged"));
-
- 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();
-}
-
-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]);
+ [implementation_ suppressClipboardContent];
}
-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_];
-
- return md5_changed;
+void ClipboardRecentContentIOS::SaveToUserDefaults() {
+ [implementation_ saveToUserDefaults];
}
-ClipboardRecentContentIOS::~ClipboardRecentContentIOS() {
- [notification_bridge_ disconnect];
+void ClipboardRecentContentIOS::SetLastPasteboardChangeDate(NSDate* date) {
+ [implementation_ setLastPasteboardChangeDate:date];
}
-GURL ClipboardRecentContentIOS::URLFromPasteboard() {
- NSString* clipboard_string = [[UIPasteboard generalPasteboard] string];
- if (!clipboard_string) {
- return GURL::EmptyGURL();
+NSArray* ClipboardRecentContentIOS::GetAuthorizedSchemeList(
sdefresne 2017/04/03 09:27:16 This can be a free function, no need to export thi
lody 2017/04/04 13:42:18 Done.
+ const std::string& application_scheme) {
+ NSMutableArray* schemes = [NSMutableArray array];
+ for (size_t i = 0; i < arraysize(kAuthorizedSchemes); ++i) {
+ [schemes addObject:base::SysUTF8ToNSString(kAuthorizedSchemes[i])];
}
- const std::string clipboard = base::SysNSStringToUTF8(clipboard_string);
- GURL gurl = GURL(clipboard);
- if (gurl.is_valid()) {
- for (size_t i = 0; i < arraysize(kAuthorizedSchemes); ++i) {
- if (gurl.SchemeIs(kAuthorizedSchemes[i])) {
- return gurl;
- }
- }
- if (!application_scheme_.empty() &&
- gurl.SchemeIs(application_scheme_.c_str())) {
- return gurl;
- }
+ if (!application_scheme.empty()) {
+ [schemes addObject:base::SysUTF8ToNSString(application_scheme)];
}
- return GURL::EmptyGURL();
-}
-
-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]]);
-}
-
-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::Uptime() const {
- return base::SysInfo::Uptime();
+ return schemes;
}

Powered by Google App Engine
This is Rietveld 408576698