0

[Parcel Tracking] Remove parcel tracking code from annotations

Parcel tracking was un-launched in https://crrev.com/b6ecf1cb, and
we are now removing the related code from the codebase.

Bug: 391002352
Change-Id: Ia11a1e4925a16ed3ae8d34091c35ad6341343756
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6259075
Reviewed-by: Olivier Robin <olivierrobin@chromium.org>
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Auto-Submit: Stephen McGruer <smcgruer@chromium.org>
Reviewed-by: Rohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1421456}
This commit is contained in:
Stephen McGruer
2025-02-18 09:54:00 -08:00
committed by Chromium LUCI CQ
parent d128323908
commit 0f127594c2
8 changed files with 10 additions and 477 deletions

@ -23,7 +23,6 @@ include_rules = [
"+ios/chrome/browser/open_from_clipboard/model",
"+ios/chrome/browser/optimization_guide/model",
"+ios/chrome/browser/overlays/model/public",
"+ios/chrome/browser/parcel_tracking",
"+ios/chrome/browser/permissions/model",
"+ios/chrome/browser/policy/model",
"+ios/chrome/browser/prerender/model",

@ -14,8 +14,6 @@ source_set("annotations") {
"//components/ukm/ios:ukm_url_recorder",
"//ios/chrome/browser/mailto_handler/model",
"//ios/chrome/browser/mailto_handler/model:mailto_handler_factory",
"//ios/chrome/browser/parcel_tracking:features",
"//ios/chrome/browser/parcel_tracking:prefs",
"//ios/chrome/browser/shared/model/application_context",
"//ios/chrome/browser/shared/model/prefs:pref_names",
"//ios/chrome/browser/shared/model/profile",
@ -41,17 +39,12 @@ source_set("annotations") {
"annotations_tab_helper.mm",
"annotations_util.h",
"annotations_util.mm",
"parcel_number_tracker.h",
"parcel_number_tracker.mm",
]
}
source_set("unit_tests") {
testonly = true
sources = [
"annotations_util_unittest.mm",
"parcel_number_tracker_unittest.mm",
]
sources = [ "annotations_util_unittest.mm" ]
deps = [
":annotations",
"//base/test:test_support",

@ -13,7 +13,6 @@
#import "base/memory/weak_ptr.h"
#import "base/sequence_checker.h"
#import "base/values.h"
#import "ios/chrome/browser/web/model/annotations/parcel_number_tracker.h"
#import "ios/public/provider/chrome/browser/context_menu/context_menu_api.h"
#import "ios/web/public/annotations/annotations_text_observer.h"
#import "ios/web/public/annotations/custom_text_checking_result.h"
@ -47,6 +46,9 @@ class AnnotationsTabHelper : public web::AnnotationsTextObserver,
// Sets the ParcelTrackingOptInCommands that can display the parcel tracking
// opt-in prompt.
//
// TODO(crbug.com/391002352): Remove function entirely, as Parcel Tracking has
// been turned down.
void SetParcelTrackingOptInCommands(
id<ParcelTrackingOptInCommands> parcel_tracking_handler);
@ -94,16 +96,9 @@ class AnnotationsTabHelper : public web::AnnotationsTextObserver,
int seq_id,
std::optional<std::vector<web::TextAnnotation>> deferred);
// Records the measurement detection, and triggers the parcel tracking UI
// display if the given list of annotations contains at least one parcel
// number and the user is eligible for the prompt. Removes parcels from
// `annotations_list`.
// Records the measurement detection from the input `annotations_list`.c
void ProcessAnnotations(std::vector<web::TextAnnotation>& annotations_list);
// Triggers the parcel tracking UI display for the given parcel
// list `parcels`.
void MaybeShowParcelTrackingUI(NSArray<CustomTextCheckingResult*>* parcels);
// Puts annotations data in `match_cache_` and replaces it with a uuid key
// to be passed to JS and expect back in `OnClick`. Builds `decorations`
// from annotations.
@ -115,16 +110,12 @@ class AnnotationsTabHelper : public web::AnnotationsTextObserver,
id<MiniMapCommands> mini_map_handler_ = nil;
id<ParcelTrackingOptInCommands> parcel_tracking_handler_ = nil;
id<UnitConversionCommands> unit_conversion_handler_ = nil;
raw_ptr<web::WebState> web_state_ = nullptr;
std::unique_ptr<base::Value::Dict> metadata_;
ParcelNumberTracker parcel_number_tracker_;
std::map<std::string, NSTextCheckingResult*> match_cache_;
SEQUENCE_CHECKER(sequence_checker_);

@ -17,12 +17,9 @@
#import "components/ukm/ios/ukm_url_recorder.h"
#import "ios/chrome/browser/mailto_handler/model/mailto_handler_service.h"
#import "ios/chrome/browser/mailto_handler/model/mailto_handler_service_factory.h"
#import "ios/chrome/browser/parcel_tracking/features.h"
#import "ios/chrome/browser/parcel_tracking/parcel_tracking_prefs.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/profile/profile_ios.h"
#import "ios/chrome/browser/shared/public/commands/parcel_tracking_opt_in_commands.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/text_selection/model/text_classifier_model_service.h"
#import "ios/chrome/browser/text_selection/model/text_classifier_model_service_factory.h"
#import "ios/chrome/browser/text_selection/model/text_classifier_util.h"
@ -69,7 +66,7 @@ void AnnotationsTabHelper::SetMiniMapCommands(
void AnnotationsTabHelper::SetParcelTrackingOptInCommands(
id<ParcelTrackingOptInCommands> parcel_tracking_handler) {
parcel_tracking_handler_ = parcel_tracking_handler;
NOTREACHED();
}
void AnnotationsTabHelper::SetUnitConversionCommands(
@ -217,26 +214,6 @@ void AnnotationsTabHelper::ApplyDeferredProcessing(
if (main_frame && deferred) {
std::vector<web::TextAnnotation> annotations(std::move(deferred.value()));
PrefService* prefs =
IsHomeCustomizationEnabled()
? ProfileIOS::FromBrowserState(web_state_->GetBrowserState())
->GetPrefs()
: GetApplicationContext()->GetLocalState();
if (IsIOSParcelTrackingEnabled() && !IsParcelTrackingDisabled(prefs)) {
parcel_number_tracker_.ProcessAnnotations(annotations);
// Show UI only if this is the currently active WebState.
if (parcel_number_tracker_.HasNewTrackingNumbers() &&
web_state_->IsVisible()) {
// Call asynchronously to allow the rest of the annotations to be
// decorated first.
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE,
base::BindOnce(&AnnotationsTabHelper::MaybeShowParcelTrackingUI,
weak_factory_.GetWeakPtr(),
parcel_number_tracker_.GetNewTrackingNumbers()));
}
}
if (base::FeatureList::IsEnabled(web::features::kEnableMeasurements)) {
ProcessAnnotations(annotations);
}
@ -276,9 +253,4 @@ void AnnotationsTabHelper::ProcessAnnotations(
detected_measurements);
}
void AnnotationsTabHelper::MaybeShowParcelTrackingUI(
NSArray<CustomTextCheckingResult*>* parcels) {
[parcel_tracking_handler_ showTrackingForParcels:parcels];
}
WEB_STATE_USER_DATA_KEY_IMPL(AnnotationsTabHelper)

@ -7,7 +7,6 @@
#import "base/feature_list.h"
#import "base/metrics/field_trial_params.h"
#import "components/prefs/pref_service.h"
#import "ios/chrome/browser/parcel_tracking/features.h"
#import "ios/chrome/browser/shared/model/prefs/pref_names.h"
#import "ios/chrome/browser/web/model/annotations/annotations_util.h"
#import "ios/web/common/features.h"
@ -145,7 +144,8 @@ bool IsLongPressAnnotationEnabledForType(PrefService* prefs,
case WebAnnotationType::kEMailAddresses:
return true;
case WebAnnotationType::kPackage:
return IsIOSParcelTrackingEnabled();
// Package tracking was turned down in https://crbug.com/377724731
return false;
case WebAnnotationType::kPhoneNumbers:
return true;
case WebAnnotationType::kUnits:
@ -170,7 +170,8 @@ bool IsOneTapAnnotationEnabledForType(PrefService* prefs,
case WebAnnotationType::kEMailAddresses:
return true;
case WebAnnotationType::kPackage:
return IsIOSParcelTrackingEnabled();
// Package tracking was turned down in https://crbug.com/377724731
return false;
case WebAnnotationType::kPhoneNumbers:
return true;
case WebAnnotationType::kUnits:

@ -1,50 +0,0 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_WEB_MODEL_ANNOTATIONS_PARCEL_NUMBER_TRACKER_H_
#define IOS_CHROME_BROWSER_WEB_MODEL_ANNOTATIONS_PARCEL_NUMBER_TRACKER_H_
#import <UIKit/UIKit.h>
#import <optional>
#import "ios/web/common/annotations_utils.h"
#import "ios/web/public/annotations/custom_text_checking_result.h"
@class AnnotationsParcelProvider;
/**
* Class tracking discovered parcel tracking numbers in text.
*/
class ParcelNumberTracker {
public:
explicit ParcelNumberTracker();
~ParcelNumberTracker();
// Records and removes parcels from `annotations_list`.
void ProcessAnnotations(std::vector<web::TextAnnotation>& annotations_list);
// Returns true if any parcels are ready to be dispatched to parcel tracking
// system.
bool HasNewTrackingNumbers();
// Returns the array of parcels ready to be dispatched to parcel tracking
// system and removes them from the match wait list.
NSArray<CustomTextCheckingResult*>* GetNewTrackingNumbers();
private:
// All tracking numbers that have been detected so far on this page, keyed
// by the carrier associated to the number's pattern.
NSMutableDictionary<NSNumber*, AnnotationsParcelProvider*>*
parcel_tracking_numbers_;
// All carriers that have been detected (by name) so far on this page.
NSMutableSet<NSNumber*>* parcel_carriers_;
// Id (0) representing textual data found that is as good as having literal
// carrier identity. For example "Order Number", "Tracking Number", etc.
NSNumber* any_carrier_id_;
};
#endif // IOS_CHROME_BROWSER_WEB_MODEL_ANNOTATIONS_PARCEL_NUMBER_TRACKER_H_

@ -1,119 +0,0 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/web/model/annotations/parcel_number_tracker.h"
#import "ios/web/common/features.h"
/**
* Tracks parcels number found so far in the page and those that have been
* passed on to the Parcel Tracking service.
*/
@interface AnnotationsParcelProvider : NSObject
@property(nonatomic, strong)
NSMutableArray<CustomTextCheckingResult*>* trackingNumbers;
@property(nonatomic, strong) NSMutableSet<NSString*>* uniqueParcelNumbers;
@end
@implementation AnnotationsParcelProvider
- (instancetype)init {
self = [super init];
if (self) {
_trackingNumbers = [NSMutableArray array];
_uniqueParcelNumbers = [NSMutableSet set];
}
return self;
}
@end
ParcelNumberTracker::ParcelNumberTracker() {
parcel_tracking_numbers_ = [NSMutableDictionary dictionary];
parcel_carriers_ = [NSMutableSet set];
any_carrier_id_ = [[NSNumber alloc] initWithInt:0];
}
ParcelNumberTracker::~ParcelNumberTracker() {
parcel_tracking_numbers_ = nil;
parcel_carriers_ = nil;
}
void ParcelNumberTracker::ProcessAnnotations(
std::vector<web::TextAnnotation>& annotations_list) {
for (auto annotation = annotations_list.begin();
annotation != annotations_list.end();) {
NSTextCheckingResult* match = annotation->second;
if (!match || (match.resultType != TCTextCheckingTypeParcelTracking &&
match.resultType != TCTextCheckingTypeCarrier)) {
annotation++;
continue;
}
CustomTextCheckingResult* custom_match =
static_cast<CustomTextCheckingResult*>(match);
if (match.resultType == TCTextCheckingTypeCarrier) {
NSNumber* carrier = [[NSNumber alloc] initWithInt:custom_match.carrier];
[parcel_carriers_ addObject:carrier];
// Remove the carrier from annotations_list to prevent decorating it.
annotation = annotations_list.erase(annotation);
} else if (match.resultType == TCTextCheckingTypeParcelTracking) {
NSNumber* carrier = [[NSNumber alloc] initWithInt:custom_match.carrier];
AnnotationsParcelProvider* parcel =
[parcel_tracking_numbers_ objectForKey:carrier];
if (!parcel) {
parcel = [[AnnotationsParcelProvider alloc] init];
[parcel_tracking_numbers_ setObject:parcel forKey:carrier];
}
// Avoid adding duplicates to `trackingNumbers`.
if (![parcel.uniqueParcelNumbers
containsObject:[custom_match carrierNumber]]) {
[parcel.uniqueParcelNumbers addObject:[custom_match carrierNumber]];
[parcel.trackingNumbers addObject:custom_match];
}
// Remove the parcel from annotations_list to prevent decorating it.
annotation = annotations_list.erase(annotation);
} else {
annotation++;
}
}
}
// Returns true if any parcels are ready to be dispatched to parcel tracking
// system.
bool ParcelNumberTracker::HasNewTrackingNumbers() {
for (NSNumber* key in parcel_tracking_numbers_) {
AnnotationsParcelProvider* parcel =
[parcel_tracking_numbers_ objectForKey:key];
if (base::FeatureList::IsEnabled(
web::features::kEnableNewParcelTrackingNumberDetection) &&
![parcel_carriers_ containsObject:key] &&
![parcel_carriers_ containsObject:any_carrier_id_]) {
continue;
}
if (parcel.trackingNumbers.count) {
return true;
}
}
return false;
}
// Returns the array of parcels ready to be dispatched to parcel tracking
// system and removes them from the match wait list.
NSArray<CustomTextCheckingResult*>*
ParcelNumberTracker::GetNewTrackingNumbers() {
NSMutableArray<CustomTextCheckingResult*>* trackingNumbers =
[NSMutableArray array];
for (NSNumber* key in parcel_tracking_numbers_) {
AnnotationsParcelProvider* parcel =
[parcel_tracking_numbers_ objectForKey:key];
if (base::FeatureList::IsEnabled(
web::features::kEnableNewParcelTrackingNumberDetection) &&
![parcel_carriers_ containsObject:key] &&
![parcel_carriers_ containsObject:any_carrier_id_]) {
continue;
}
[trackingNumbers addObjectsFromArray:parcel.trackingNumbers];
[parcel.trackingNumbers removeAllObjects];
}
return trackingNumbers;
}

@ -1,254 +0,0 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/web/model/annotations/parcel_number_tracker.h"
#import "base/test/scoped_feature_list.h"
#import "ios/web/common/features.h"
#import "ios/web/public/annotations/custom_text_checking_result.h"
#import "testing/gtest_mac.h"
#import "testing/platform_test.h"
class ParcelNumberTrackerTest : public PlatformTest {
public:
ParcelNumberTracker tracker_;
protected:
base::test::ScopedFeatureList scoped_feature_list_;
};
TEST_F(ParcelNumberTrackerTest, TestNumberDetect) {
scoped_feature_list_.Reset();
std::vector<web::TextAnnotation> results;
NSRange range = NSMakeRange(0, 3);
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// Add a number for another carrier
NSTextCheckingResult* match =
[CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:4
carrierNumber:@"123456789"];
results.emplace_back(web::ConvertMatchToAnnotation(@"123456789", range, match,
@"TRACKING_NUMBER"));
tracker_.ProcessAnnotations(results);
// Expect that the tracking number has been removed.
EXPECT_EQ(0ul, results.size());
// and that the tracking numbers is available.
EXPECT_TRUE(tracker_.HasNewTrackingNumbers());
NSArray<CustomTextCheckingResult*>* new_tracking_numbers =
tracker_.GetNewTrackingNumbers();
EXPECT_EQ(1ul, new_tracking_numbers.count);
EXPECT_EQ(new_tracking_numbers[0].carrier, 4);
EXPECT_EQ(new_tracking_numbers[0].carrierNumber, @"123456789");
// Expect the tracking number has been removed.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
new_tracking_numbers = tracker_.GetNewTrackingNumbers();
EXPECT_EQ(0ul, new_tracking_numbers.count);
// Add and process a carrier.
match = [CustomTextCheckingResult carrierCheckingResultWithRange:range
carrier:2];
results.emplace_back(
web::ConvertMatchToAnnotation(@"UPS", range, match, @"CARRIER"));
tracker_.ProcessAnnotations(results);
// Expect that the carrier has been removed.
EXPECT_EQ(0ul, results.size());
// And that no tracking number is available.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// See the same number again.
match = [CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:4
carrierNumber:@"123456789"];
results.emplace_back(web::ConvertMatchToAnnotation(@"123456789", range, match,
@"TRACKING_NUMBER"));
tracker_.ProcessAnnotations(results);
// Expect its' not a new number.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// Add two tracking numbers and an address.
match = [CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:2
carrierNumber:@"abcdefg"];
results.emplace_back(web::ConvertMatchToAnnotation(@"abcdefg", range, match,
@"TRACKING_NUMBER"));
match = [CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:2
carrierNumber:@"hijklmn"];
results.emplace_back(web::ConvertMatchToAnnotation(@"hijklmn", range, match,
@"TRACKING_NUMBER"));
match = [NSTextCheckingResult addressCheckingResultWithRange:range
components:@{}];
results.emplace_back(web::ConvertMatchToAnnotation(@"8 Rue de Londre", range,
match, @"ADDRESS"));
tracker_.ProcessAnnotations(results);
// Expect the address was left untouched.
EXPECT_EQ(1ul, results.size());
// And that there are two new tracking numbers.
EXPECT_TRUE(tracker_.HasNewTrackingNumbers());
new_tracking_numbers = tracker_.GetNewTrackingNumbers();
EXPECT_EQ(2ul, new_tracking_numbers.count);
EXPECT_EQ(new_tracking_numbers[0].carrier, 2);
EXPECT_EQ(new_tracking_numbers[0].carrierNumber, @"abcdefg");
EXPECT_EQ(new_tracking_numbers[1].carrier, 2);
EXPECT_EQ(new_tracking_numbers[1].carrierNumber, @"hijklmn");
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
}
TEST_F(ParcelNumberTrackerTest, TestImprovedCarrierAndNumberDetect) {
scoped_feature_list_.Reset();
scoped_feature_list_.InitWithFeatures(
{web::features::kEnableNewParcelTrackingNumberDetection}, {});
std::vector<web::TextAnnotation> results;
NSRange range = NSMakeRange(0, 3);
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// Add and process a carrier.
NSTextCheckingResult* match =
[CustomTextCheckingResult carrierCheckingResultWithRange:range carrier:2];
results.emplace_back(
web::ConvertMatchToAnnotation(@"UPS", range, match, @"CARRIER"));
tracker_.ProcessAnnotations(results);
// Expect that the carrier has been removed.
EXPECT_EQ(0ul, results.size());
// And that no tracking numbers are available.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// Add a number for another carrier
match = [CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:4
carrierNumber:@"123456789"];
results.emplace_back(web::ConvertMatchToAnnotation(@"123456789", range, match,
@"TRACKING_NUMBER"));
tracker_.ProcessAnnotations(results);
// Expect that the tracking number has been removed.
EXPECT_EQ(0ul, results.size());
// and that no matching tracking numbers are available.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// Add a matching carrier.
match = [CustomTextCheckingResult carrierCheckingResultWithRange:range
carrier:4];
results.emplace_back(
web::ConvertMatchToAnnotation(@"USPS", range, match, @"CARRIER"));
tracker_.ProcessAnnotations(results);
// Expect that matching tracking numbers are available.
EXPECT_TRUE(tracker_.HasNewTrackingNumbers());
// and that calling the check twice doesn't change the result.
EXPECT_TRUE(tracker_.HasNewTrackingNumbers());
NSArray<CustomTextCheckingResult*>* new_tracking_numbers =
tracker_.GetNewTrackingNumbers();
EXPECT_EQ(1ul, new_tracking_numbers.count);
EXPECT_EQ(new_tracking_numbers[0].carrier, 4);
EXPECT_EQ(new_tracking_numbers[0].carrierNumber, @"123456789");
// Expect the tracking number has been removed.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
new_tracking_numbers = tracker_.GetNewTrackingNumbers();
EXPECT_EQ(0ul, new_tracking_numbers.count);
// See the same number again.
match = [CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:4
carrierNumber:@"123456789"];
results.emplace_back(web::ConvertMatchToAnnotation(@"123456789", range, match,
@"TRACKING_NUMBER"));
tracker_.ProcessAnnotations(results);
// Expect its' not a new number.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
match = [CustomTextCheckingResult carrierCheckingResultWithRange:range
carrier:4];
results.emplace_back(
web::ConvertMatchToAnnotation(@"USPS", range, match, @"CARRIER"));
tracker_.ProcessAnnotations(results);
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// Add two tracking numbers for first carrier and an address.
match = [CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:2
carrierNumber:@"abcdefg"];
results.emplace_back(web::ConvertMatchToAnnotation(@"abcdefg", range, match,
@"TRACKING_NUMBER"));
match = [CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:2
carrierNumber:@"hijklmn"];
results.emplace_back(web::ConvertMatchToAnnotation(@"hijklmn", range, match,
@"TRACKING_NUMBER"));
match = [NSTextCheckingResult addressCheckingResultWithRange:range
components:@{}];
results.emplace_back(web::ConvertMatchToAnnotation(@"8 Rue de Londre", range,
match, @"ADDRESS"));
tracker_.ProcessAnnotations(results);
// Expect the address was left untouched.
EXPECT_EQ(1ul, results.size());
// And that there are two new tracking numbers.
EXPECT_TRUE(tracker_.HasNewTrackingNumbers());
new_tracking_numbers = tracker_.GetNewTrackingNumbers();
EXPECT_EQ(2ul, new_tracking_numbers.count);
EXPECT_EQ(new_tracking_numbers[0].carrier, 2);
EXPECT_EQ(new_tracking_numbers[0].carrierNumber, @"abcdefg");
EXPECT_EQ(new_tracking_numbers[1].carrier, 2);
EXPECT_EQ(new_tracking_numbers[1].carrierNumber, @"hijklmn");
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
}
TEST_F(ParcelNumberTrackerTest, TestAnyCarrierAndNumberDetect) {
scoped_feature_list_.Reset();
scoped_feature_list_.InitWithFeatures(
{web::features::kEnableNewParcelTrackingNumberDetection}, {});
std::vector<web::TextAnnotation> results;
NSRange range = NSMakeRange(0, 3);
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// Add a number for carrier 4.
NSTextCheckingResult* match =
[CustomTextCheckingResult parcelCheckingResultWithRange:range
carrier:4
carrierNumber:@"123456789"];
results.emplace_back(web::ConvertMatchToAnnotation(@"123456789", range, match,
@"TRACKING_NUMBER"));
tracker_.ProcessAnnotations(results);
// Expect that the tracking number has been removed.
EXPECT_EQ(0ul, results.size());
// and that no matching tracking numbers are available.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
// Add an any-carrier carrier.
match = [CustomTextCheckingResult carrierCheckingResultWithRange:range
carrier:0];
results.emplace_back(web::ConvertMatchToAnnotation(@"Tracking Number", range,
match, @"CARRIER"));
tracker_.ProcessAnnotations(results);
// Expect that the tracking number is available.
EXPECT_TRUE(tracker_.HasNewTrackingNumbers());
NSArray<CustomTextCheckingResult*>* new_tracking_numbers =
tracker_.GetNewTrackingNumbers();
EXPECT_EQ(1ul, new_tracking_numbers.count);
EXPECT_EQ(new_tracking_numbers[0].carrier, 4);
EXPECT_EQ(new_tracking_numbers[0].carrierNumber, @"123456789");
// Expect the tracking number has been removed.
EXPECT_FALSE(tracker_.HasNewTrackingNumbers());
new_tracking_numbers = tracker_.GetNewTrackingNumbers();
EXPECT_EQ(0ul, new_tracking_numbers.count);
}