Home | History | Annotate | Download | only in android
      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 = base::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 =
     82         base::UTF8ToUTF16(utf8_input.substr(0, match.start())).length();
     83     *end_pos = *start_pos + base::UTF8ToUTF16(match.raw_string()).length();
     84 
     85     return true;
     86   }
     87 
     88   return false;
     89 }
     90 
     91 }  // namespace content
     92