Commit 88712b9a authored by Chris Lu's avatar Chris Lu Committed by Commit Bot

[ios] Heuristics for users who may want default browser

Util method LogSignificantUserEvent() will log timestamps of user actions
deemed indicative of users that would want Chrome as their default
browser. The user actions in this CL are Extension Actions, searches
from copied clipboard content, and GrowthKit opens.

Bug: 1107489
Change-Id: If5f24100352a60362c35044feabf9fdc7b29f2ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2330931
Commit-Queue: Chris Lu <thegreenfrog@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795614}
parent 8613e4c5
......@@ -81,6 +81,7 @@ source_set("startup") {
"//ios/chrome/browser/first_run",
"//ios/chrome/browser/net:net",
"//ios/chrome/browser/ntp_snippets",
"//ios/chrome/browser/ui/whats_new:utils",
"//ios/chrome/browser/web:web_internal",
"//ios/chrome/common",
"//ios/chrome/common/app_group",
......
......@@ -9,6 +9,7 @@
#include "base/metrics/user_metrics_action.h"
#include "base/strings/sys_string_conversions.h"
#include "ios/chrome/browser/chrome_url_constants.h"
#import "ios/chrome/browser/ui/whats_new/default_browser_utils.h"
#include "ios/chrome/common/app_group/app_group_constants.h"
#include "ios/chrome/common/x_callback_url.h"
#include "ios/components/webui/web_ui_url_constants.h"
......@@ -186,6 +187,11 @@ NSString* const kLastHTTPURLOpenTime = @"lastHTTPURLOpenTime";
}
UMA_HISTOGRAM_ENUMERATION(kUMAMobileSessionStartActionHistogram, action,
MOBILE_SESSION_START_ACTION_COUNT);
// An HTTP(S) URL open that opened Chrome (e.g. default browser open) should
// be logged as siginficnat activity for a potential user that would want
// Chrome as their default browser in case the user changes away from
// Chrome. This will leave a trace of this activity for re-prompting.
LogLikelyInterestedDefaultBrowserUserActivity();
if (action == START_ACTION_OPEN_HTTP_FROM_OS ||
action == START_ACTION_OPEN_HTTPS_FROM_OS) {
......@@ -392,6 +398,13 @@ NSString* const kLastHTTPURLOpenTime = @"lastHTTPURLOpenTime";
action = ACTION_NEW_INCOGNITO_SEARCH;
}
if (action != ACTION_NO_ACTION) {
// An external action that opened Chrome (i.e. GrowthKit link open, open
// Search, search clipboard content) is activity that should indicate a user
// that would be interested in setting Chrome as the default browser.
LogLikelyInterestedDefaultBrowserUserActivity();
}
if ([secureSourceApp
isEqualToString:app_group::kOpenCommandSourceSearchExtension]) {
UMA_HISTOGRAM_ENUMERATION("IOS.SearchExtension.Action", action,
......
......@@ -71,6 +71,7 @@ source_set("location_bar") {
"//ios/chrome/browser/ui/toolbar/public:feature_flags",
"//ios/chrome/browser/ui/util",
"//ios/chrome/browser/ui/voice",
"//ios/chrome/browser/ui/whats_new:utils",
"//ios/chrome/browser/url_loading",
"//ios/chrome/browser/web",
"//ios/chrome/browser/web_state_list",
......
......@@ -25,6 +25,7 @@
#include "ios/chrome/browser/ui/ui_feature_flags.h"
#import "ios/chrome/browser/ui/util/named_guide.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
#import "ios/chrome/browser/ui/whats_new/default_browser_utils.h"
#import "ios/chrome/common/ui/util/constraints_ui_util.h"
#import "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -593,6 +594,9 @@ const double kFullscreenProgressBadgeViewThreshold = 0.85;
}
- (void)visitCopiedLink:(id)sender {
// A search using clipboard link is activity that should indicate a user
// that would be interested in setting Chrome as the default browser.
LogLikelyInterestedDefaultBrowserUserActivity();
RecordAction(UserMetricsAction("Mobile.OmniboxContextMenu.VisitCopiedLink"));
ClipboardRecentContent::GetInstance()->GetRecentURLFromClipboard(
base::BindOnce(^(base::Optional<GURL> optionalURL) {
......@@ -608,6 +612,9 @@ const double kFullscreenProgressBadgeViewThreshold = 0.85;
}
- (void)searchCopiedText:(id)sender {
// A search using clipboard text is activity that should indicate a user
// that would be interested in setting Chrome as the default browser.
LogLikelyInterestedDefaultBrowserUserActivity();
RecordAction(UserMetricsAction("Mobile.OmniboxContextMenu.SearchCopiedText"));
ClipboardRecentContent::GetInstance()->GetRecentTextFromClipboard(
base::BindOnce(^(base::Optional<base::string16> optionalText) {
......
......@@ -161,6 +161,7 @@ source_set("omnibox_internal") {
"//ios/chrome/browser/ui/toolbar/public:feature_flags",
"//ios/chrome/browser/ui/util",
"//ios/chrome/browser/ui/util:multiwindow_util",
"//ios/chrome/browser/ui/whats_new:utils",
"//ios/chrome/common",
"//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/favicon",
......
......@@ -23,6 +23,7 @@
#include "ios/chrome/browser/ui/ui_feature_flags.h"
#include "ios/chrome/browser/ui/util/ui_util.h"
#include "ios/chrome/browser/ui/util/uikit_ui_util.h"
#import "ios/chrome/browser/ui/whats_new/default_browser_utils.h"
#import "ios/chrome/common/ui/colors/dynamic_color_util.h"
#import "ios/chrome/common/ui/colors/semantic_color_names.h"
#import "ios/chrome/common/ui/util/pointer_interaction_util.h"
......@@ -550,6 +551,9 @@ const CGFloat kClearButtonSize = 28.0f;
}
- (void)visitCopiedLink:(id)sender {
// A search using clipboard link is activity that should indicate a user
// that would be interested in setting Chrome as the default browser.
LogLikelyInterestedDefaultBrowserUserActivity();
RecordAction(UserMetricsAction("Mobile.OmniboxContextMenu.VisitCopiedLink"));
self.omniboxInteractedWhileFocused = YES;
ClipboardRecentContent::GetInstance()->GetRecentURLFromClipboard(
......@@ -566,6 +570,9 @@ const CGFloat kClearButtonSize = 28.0f;
}
- (void)searchCopiedText:(id)sender {
// A search using clipboard text is activity that should indicate a user
// that would be interested in setting Chrome as the default browser.
LogLikelyInterestedDefaultBrowserUserActivity();
RecordAction(UserMetricsAction("Mobile.OmniboxContextMenu.SearchCopiedText"));
self.omniboxInteractedWhileFocused = YES;
ClipboardRecentContent::GetInstance()->GetRecentTextFromClipboard(
......
......@@ -38,6 +38,7 @@ source_set("popup") {
"//ios/chrome/browser/ui/toolbar/public",
"//ios/chrome/browser/ui/toolbar/public:feature_flags",
"//ios/chrome/browser/ui/util",
"//ios/chrome/browser/ui/whats_new:utils",
"//ios/chrome/browser/web_state_list:web_state_list",
"//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/favicon",
......
......@@ -23,6 +23,7 @@
#include "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_suggestions_delegate.h"
#include "ios/chrome/browser/ui/util/ui_util.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
#import "ios/chrome/browser/ui/whats_new/default_browser_utils.h"
#include "ios/chrome/grit/ios_theme_resources.h"
#include "ios/web/public/thread/web_thread.h"
#include "net/url_request/url_request_context_getter.h"
......@@ -131,6 +132,13 @@ void OmniboxPopupViewIOS::OnMatchSelected(
// make sure it stays alive until the call completes.
AutocompleteMatch match = selectedMatch;
if (match.type == AutocompleteMatchType::CLIPBOARD_URL ||
match.type == AutocompleteMatchType::CLIPBOARD_TEXT) {
// A search using clipboard link or text is activity that should indicate a
// user that would be interested in setting Chrome as the default browser.
LogLikelyInterestedDefaultBrowserUserActivity();
}
if (match.type == AutocompleteMatchType::CLIPBOARD_URL) {
base::RecordAction(UserMetricsAction("MobileOmniboxClipboardToURL"));
UMA_HISTOGRAM_LONG_TIMES_100(
......
......@@ -2,6 +2,15 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
source_set("utils") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"default_browser_utils.h",
"default_browser_utils.mm",
]
deps = [ "//base" ]
}
source_set("whats_new") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
......
// Copyright 2020 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.
#ifndef IOS_CHROME_BROWSER_UI_WHATS_NEW_DEFAULT_BROWSER_UTILS_H_
#define IOS_CHROME_BROWSER_UI_WHATS_NEW_DEFAULT_BROWSER_UTILS_H_
// Logs the timestamp of user activity that is deemed to be an indication of
// a user that would likely benefit from having Chrome set as their default
// browser. Before logging the current activity, this method will also clear all
// past expired logs that have happened too far in the past.
void LogLikelyInterestedDefaultBrowserUserActivity();
#endif // IOS_CHROME_BROWSER_UI_WHATS_NEW_DEFAULT_BROWSER_UTILS_H_
// Copyright 2020 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/chrome/browser/ui/whats_new/default_browser_utils.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#import <UIKit/UIKit.h>
namespace {
NSString* const kLastSignificantUserEvent = @"lastSignificantUserEvent";
// Time threshold before activity timestamps should be removed. Currently set to
// seven days.
const NSTimeInterval kUserActivityTimestampExpiration = 7 * 24 * 60 * 60;
}
void LogLikelyInterestedDefaultBrowserUserActivity() {
NSMutableArray<NSDate*>* pastUserEvents =
[[[NSUserDefaults standardUserDefaults]
arrayForKey:kLastSignificantUserEvent] mutableCopy];
if (pastUserEvents) {
NSDate* sevenDaysAgoDate =
[NSDate dateWithTimeIntervalSinceNow:-kUserActivityTimestampExpiration];
// Clear all timestamps that occur later than 7 days ago.
NSUInteger firstUnexpiredIndex =
[pastUserEvents indexOfObjectPassingTest:^BOOL(
NSDate* date, NSUInteger idx, BOOL* stop) {
return ([date laterDate:sevenDaysAgoDate] == date);
}];
if (firstUnexpiredIndex != NSNotFound && firstUnexpiredIndex > 0) {
[pastUserEvents removeObjectsInRange:NSMakeRange(0, firstUnexpiredIndex)];
}
[pastUserEvents addObject:[NSDate date]];
} else {
pastUserEvents = [NSMutableArray arrayWithObject:[NSDate date]];
}
[[NSUserDefaults standardUserDefaults] setObject:pastUserEvents
forKey:kLastSignificantUserEvent];
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment