forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Android] Introduce phone number detection.
For more context see: https://chromiumcodereview.appspot.com/10187020/ BUG=125390 TEST=phone_number_detector_unittest.cc Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=139019 Review URL: https://chromiumcodereview.appspot.com/10440021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139026 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
leandrogracia@chromium.org
committed
May 25, 2012
1 parent
b63fee8
commit 975b42b
Showing
7 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
include_rules = [ | ||
"+third_party/libphonenumber", # For phone number detection. | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright (c) 2012 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. | ||
|
||
#include "content/renderer/android/phone_number_detector.h" | ||
|
||
#include <algorithm> | ||
|
||
#include "base/utf_string_conversions.h" | ||
#include "net/base/escape.h" | ||
#include "third_party/libphonenumber/src/phonenumber_api.h" | ||
#include "third_party/libphonenumber/src/phonenumbers/phonenumbermatch.h" | ||
#include "third_party/libphonenumber/src/phonenumbers/phonenumbermatcher.h" | ||
#include "third_party/libphonenumber/src/phonenumbers/region_code.h" | ||
|
||
using i18n::phonenumbers::PhoneNumberMatch; | ||
using i18n::phonenumbers::PhoneNumberMatcher; | ||
using i18n::phonenumbers::PhoneNumberUtil; | ||
using i18n::phonenumbers::RegionCode; | ||
|
||
namespace { | ||
|
||
// Maximum number of characters to look around for phone number detection. | ||
const size_t kMaximumTelephoneLength = 20; | ||
|
||
// Prefix used for telephone number intent URIs. | ||
const char kPhoneNumberSchemaPrefix[] = "tel:"; | ||
|
||
} // anonymous namespace | ||
|
||
namespace content { | ||
|
||
PhoneNumberDetector::PhoneNumberDetector() | ||
: region_code_(RegionCode::GetUnknown()) { | ||
} | ||
|
||
// Region should be empty or an ISO 3166-1 alpha-2 country code. | ||
PhoneNumberDetector::PhoneNumberDetector(const std::string& region) | ||
: region_code_(region.empty() ? RegionCode::GetUnknown() | ||
: StringToUpperASCII(region)) { | ||
} | ||
|
||
PhoneNumberDetector::~PhoneNumberDetector() { | ||
} | ||
|
||
size_t PhoneNumberDetector::GetMaximumContentLength() { | ||
return kMaximumTelephoneLength; | ||
} | ||
|
||
GURL PhoneNumberDetector::GetIntentURL(const std::string& content_text) { | ||
if (content_text.empty()) | ||
return GURL(); | ||
|
||
return GURL(kPhoneNumberSchemaPrefix + | ||
net::EscapeQueryParamValue(content_text, true)); | ||
} | ||
|
||
bool PhoneNumberDetector::FindContent(const string16::const_iterator& begin, | ||
const string16::const_iterator& end, | ||
size_t* start_pos, | ||
size_t* end_pos, | ||
std::string* content_text) { | ||
string16 utf16_input = string16(begin, end); | ||
std::string utf8_input = UTF16ToUTF8(utf16_input); | ||
|
||
PhoneNumberMatcher matcher(utf8_input, region_code_); | ||
if (matcher.HasNext()) { | ||
PhoneNumberMatch match; | ||
matcher.Next(&match); | ||
|
||
PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); | ||
phone_util->FormatNumberForMobileDialing(match.number(), region_code_, | ||
false, /* with_formatting */ | ||
content_text); | ||
// If the number can't be dialed from the current region, the formatted | ||
// string will be empty. | ||
if (content_text->empty()) | ||
return false; | ||
|
||
// Need to return start_pos and end_pos relative to a UTF16 encoding. | ||
*start_pos = UTF8ToUTF16(utf8_input.substr(0, match.start())).length(); | ||
*end_pos = *start_pos + UTF8ToUTF16(match.raw_string()).length(); | ||
|
||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} // namespace content |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright (c) 2012 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 CONTENT_RENDERER_ANDROID_PHONE_NUMBER_DETECTOR_H_ | ||
#define CONTENT_RENDERER_ANDROID_PHONE_NUMBER_DETECTOR_H_ | ||
#pragma once | ||
|
||
#include "content/renderer/android/content_detector.h" | ||
|
||
class PhoneNumberDetectorTest; | ||
|
||
namespace content { | ||
|
||
// Finds a telephone number in the given content text string. | ||
class PhoneNumberDetector : public ContentDetector { | ||
public: | ||
PhoneNumberDetector(); | ||
explicit PhoneNumberDetector(const std::string& region); | ||
virtual ~PhoneNumberDetector(); | ||
|
||
private: | ||
friend class ::PhoneNumberDetectorTest; | ||
|
||
// Implementation of ContentDetector. | ||
virtual bool FindContent(const string16::const_iterator& begin, | ||
const string16::const_iterator& end, | ||
size_t* start_pos, | ||
size_t* end_pos, | ||
std::string* content_text) OVERRIDE; | ||
virtual GURL GetIntentURL(const std::string& content_text) OVERRIDE; | ||
virtual size_t GetMaximumContentLength() OVERRIDE; | ||
|
||
const std::string region_code_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(PhoneNumberDetector); | ||
}; | ||
|
||
} // namespace content | ||
|
||
#endif // CONTENT_RENDERER_ANDROID_PHONE_NUMBER_DETECTOR_H_ |
74 changes: 74 additions & 0 deletions
74
content/renderer/android/phone_number_detector_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright (c) 2012 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. | ||
|
||
#include "content/renderer/android/phone_number_detector.h" | ||
|
||
#include "base/utf_string_conversions.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
using content::PhoneNumberDetector; | ||
|
||
class PhoneNumberDetectorTest : public testing::Test { | ||
public: | ||
static std::string FindNumber(const std::string& content, | ||
const std::string& region) { | ||
string16 content_16 = UTF8ToUTF16(content); | ||
string16 result_16; | ||
size_t start, end; | ||
PhoneNumberDetector detector(region); | ||
std::string content_text; | ||
if (detector.FindContent(content_16.begin(), content_16.end(), | ||
&start, &end, &content_text)) | ||
result_16 = content_16.substr(start, end - start); | ||
return UTF16ToUTF8(result_16); | ||
} | ||
|
||
static std::string FindAndFormatNumber(const std::string& content, | ||
const std::string& region) { | ||
string16 content_16 = UTF8ToUTF16(content); | ||
string16 result_16; | ||
size_t start, end; | ||
PhoneNumberDetector detector(region); | ||
std::string content_text; | ||
detector.FindContent(content_16.begin(), content_16.end(), | ||
&start, &end, &content_text); | ||
return content_text; | ||
} | ||
}; | ||
|
||
TEST_F(PhoneNumberDetectorTest, FindNumber) { | ||
// Tests cases with valid home numbers. | ||
EXPECT_EQ("617-426-3000", FindNumber("hello 617-426-3000 blah", "us")); | ||
EXPECT_EQ("", FindNumber("hello 617-426-3000 blah", "gb")); | ||
EXPECT_EQ("020-7617-4426", FindNumber("<div>020-7617-4426</div>", "gb")); | ||
EXPECT_EQ("", FindNumber("<div>020-7617-4426</div>", "fr")); | ||
EXPECT_EQ("02.38.96.68.88", FindNumber("Tel:02.38.96.68.88", "fr")); | ||
EXPECT_EQ("", FindNumber("Tel:02.38.96.68.88", "gb")); | ||
EXPECT_EQ("1-800-866-2453", | ||
FindNumber("You can call this number:1-800-866-2453 for more " | ||
"information", "us")); | ||
EXPECT_EQ("+1 203-925-4602", FindNumber("+1 203-925-4602", "us")); | ||
} | ||
|
||
TEST_F(PhoneNumberDetectorTest, FindAndFormatNumber) { | ||
EXPECT_EQ("+16174263000", | ||
FindAndFormatNumber("hello 617-426-3000 blah", "us")); | ||
EXPECT_EQ("", FindAndFormatNumber("hello 617-426-3000 blah", "gb")); | ||
EXPECT_EQ("+442076174426", | ||
FindAndFormatNumber("<div>020-7617-4426</div>", "gb")); | ||
EXPECT_EQ("", FindAndFormatNumber("<div>020-7617-4426</div>", "fr")); | ||
EXPECT_EQ("+33238966888", FindAndFormatNumber("Tel:02.38.96.68.88", "fr")); | ||
EXPECT_EQ("+18008662453", | ||
FindAndFormatNumber("You can call this number:1-800-866-2453 for" | ||
"more information", "us")); | ||
EXPECT_EQ("+12039254602", FindAndFormatNumber("+1 203-925-4602", "us")); | ||
|
||
// "+1 (650) 333-6000" using fullwidth UTF-8 characters. | ||
EXPECT_EQ("+16503336000", FindAndFormatNumber( | ||
"\xEF\xBC\x8B\xEF\xBC\x91\xE3\x80\x80\xEF\xBC\x88" | ||
"\xEF\xBC\x96\xEF\xBC\x95\xEF\xBC\x90\xEF\xBC\x89" | ||
"\xE3\x80\x80\xEF\xBC\x93\xEF\xBC\x93\xEF\xBC\x93" | ||
"\xE3\x83\xBC\xEF\xBC\x96\xEF\xBC\x90\xEF\xBC\x90" | ||
"\xEF\xBC\x90", "us")); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters