summaryrefslogtreecommitdiffstats
path: root/content/renderer/android/phone_number_detector.cc
blob: 391eeda41f188db2c5d806be51bbf1c5810fe7fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// 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/string_util.h"
#include "base/utf_string_conversions.h"
#include "content/public/renderer/android_content_detection_prefixes.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;

}  // 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(kPhoneNumberPrefix +
      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