1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/renderer/android/phone_number_detector.h" 6 7 #include <algorithm> 8 9 #include "base/strings/string_util.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "content/public/renderer/android_content_detection_prefixes.h" 12 #include "net/base/escape.h" 13 #include "third_party/libphonenumber/src/phonenumber_api.h" 14 #include "third_party/libphonenumber/src/phonenumbers/phonenumbermatch.h" 15 #include "third_party/libphonenumber/src/phonenumbers/phonenumbermatcher.h" 16 #include "third_party/libphonenumber/src/phonenumbers/region_code.h" 17 18 using i18n::phonenumbers::PhoneNumberMatch; 19 using i18n::phonenumbers::PhoneNumberMatcher; 20 using i18n::phonenumbers::PhoneNumberUtil; 21 using i18n::phonenumbers::RegionCode; 22 23 namespace { 24 25 // Maximum number of characters to look around for phone number detection. 26 const size_t kMaximumTelephoneLength = 20; 27 28 } // anonymous namespace 29 30 namespace content { 31 32 PhoneNumberDetector::PhoneNumberDetector() 33 : region_code_(RegionCode::GetUnknown()) { 34 } 35 36 // Region should be empty or an ISO 3166-1 alpha-2 country code. 37 PhoneNumberDetector::PhoneNumberDetector(const std::string& region) 38 : region_code_(region.empty() ? RegionCode::GetUnknown() 39 : StringToUpperASCII(region)) { 40 } 41 42 PhoneNumberDetector::~PhoneNumberDetector() { 43 } 44 45 size_t PhoneNumberDetector::GetMaximumContentLength() { 46 return kMaximumTelephoneLength; 47 } 48 49 GURL PhoneNumberDetector::GetIntentURL(const std::string& content_text) { 50 if (content_text.empty()) 51 return GURL(); 52 53 return GURL(kPhoneNumberPrefix + 54 net::EscapeQueryParamValue(content_text, true)); 55 } 56 57 bool PhoneNumberDetector::FindContent( 58 const base::string16::const_iterator& begin, 59 const base::string16::const_iterator& end, 60 size_t* start_pos, 61 size_t* end_pos, 62 std::string* content_text) { 63 base::string16 utf16_input = base::string16(begin, end); 64 std::string utf8_input = UTF16ToUTF8(utf16_input); 65 66 PhoneNumberMatcher matcher(utf8_input, region_code_); 67 if (matcher.HasNext()) { 68 PhoneNumberMatch match; 69 matcher.Next(&match); 70 71 PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); 72 phone_util->FormatNumberForMobileDialing(match.number(), region_code_, 73 false, /* with_formatting */ 74 content_text); 75 // If the number can't be dialed from the current region, the formatted 76 // string will be empty. 77 if (content_text->empty()) 78 return false; 79 80 // Need to return start_pos and end_pos relative to a UTF16 encoding. 81 *start_pos = UTF8ToUTF16(utf8_input.substr(0, match.start())).length(); 82 *end_pos = *start_pos + UTF8ToUTF16(match.raw_string()).length(); 83 84 return true; 85 } 86 87 return false; 88 } 89 90 } // namespace content 91