1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telephony;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.text.Editable;
21 
22 /*
23  * Japanese Phone number formatting rule is a bit complicated.
24  * Here are some valid examples:
25  *
26  * 022-229-1234 0223-23-1234 022-301-9876 015-482-7849 0154-91-3478
27  * 01547-5-4534 090-1234-1234 080-0123-6789
28  * 050-0000-0000 060-0000-0000
29  * 0800-000-9999 0570-000-000 0276-00-0000
30  *
31  * As you can see, there is no straight-forward rule here.
32  * In order to handle this, a big array is prepared.
33  */
34 /* package */ class JapanesePhoneNumberFormatter {
35     private static short FORMAT_MAP[] = {
36     -100, 10, 220, -15, 410, 530, 1200, 670, 780, 1060,
37     -100, -25, 20, 40, 70, 100, 150, 190, 200, 210,
38     -36, -100, -100, -35, -35, -35, 30, -100, -100, -100,
39     -35, -35, -35, -35, -35, -35, -35, -45, -35, -35,
40     -100, -100, -100, -35, -35, -35, -35, 50, -35, 60,
41     -35, -35, -45, -35, -45, -35, -35, -45, -35, -35,
42     -35, -35, -45, -35, -35, -35, -35, -45, -45, -35,
43     -100, -100, -35, -35, -35, 80, 90, -100, -100, -100,
44     -35, -35, -35, -35, -35, -35, -45, -45, -35, -35,
45     -35, -35, -35, -35, -35, -35, -45, -35, -35, -35,
46     -25, -25, -35, -35, 110, 120, 130, -35, 140, -25,
47     -35, -25, -35, -35, -35, -35, -35, -45, -25, -35,
48     -35, -25, -35, -35, -35, -35, -35, -25, -45, -35,
49     -35, -35, -35, -35, -45, -35, -35, -35, -35, -35,
50     -35, -35, -35, -35, -35, -35, -45, -45, -35, -35,
51     -100, -100, -35, 160, 170, 180, -35, -35, -100, -100,
52     -35, -35, -45, -35, -45, -45, -35, -35, -35, -35,
53     -35, -35, -35, -35, -35, -35, -35, -35, -45, -35,
54     -35, -35, -35, -35, -45, -45, -45, -35, -45, -35,
55     -25, -25, -35, -35, -35, -35, -35, -25, -35, -35,
56     -25, -25, -35, -35, -35, -35, -35, -35, -25, -25,
57     -25, -35, -35, -35, -35, -35, -25, -35, -35, -25,
58     -100, -100, 230, 250, 260, 270, 320, 340, 360, 390,
59     -35, -25, -25, 240, -35, -35, -35, -25, -35, -35,
60     -25, -35, -35, -35, -25, -25, -25, -25, -25, -25,
61     -25, -25, -25, -35, -35, -35, -25, -35, -35, -25,
62     -35, -35, -35, -35, -35, -25, -35, -35, -35, -25,
63     -35, -25, -25, -25, -35, 280, 290, 300, 310, -35,
64     -25, -25, -25, -25, -25, -25, -25, -35, -35, -25,
65     -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
66     -25, -25, -35, -35, -35, -25, -25, -25, -25, -25,
67     -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
68     -35, -35, -25, -35, 330, -35, -35, -35, -35, -35,
69     -25, -35, -35, -35, -35, -35, -25, -25, -25, -25,
70     -35, -25, -25, -25, -35, -25, -35, -35, 350, -35,
71     -25, -35, -35, -35, -35, -35, -35, -35, -25, -25,
72     -35, -25, -35, 370, -35, -35, -25, -35, -35, 380,
73     -25, -35, -35, -25, -25, -35, -35, -35, -35, -35,
74     -25, -35, -25, -25, -25, -25, -35, -35, -35, -35,
75     -25, -35, -25, 400, -35, -35, -35, -35, -25, -35,
76     -25, -35, -35, -35, -35, -25, -25, -25, -25, -25,
77     -15, -15, 420, 460, -25, -25, 470, 480, 500, 510,
78     -15, -25, 430, -25, -25, -25, -25, -25, 440, 450,
79     -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
80     -25, -25, -35, -35, -25, -25, -25, -35, -35, -35,
81     -15, -25, -15, -15, -15, -15, -15, -25, -25, -15,
82     -25, -25, -25, -25, -25, -25, -35, -25, -35, -35,
83     -35, -25, -25, -35, -25, -35, -35, -35, -25, -25,
84     490, -15, -25, -25, -25, -35, -35, -25, -35, -35,
85     -15, -35, -35, -35, -35, -35, -35, -35, -35, -15,
86     -35, -25, -25, -25, -25, -25, -25, -25, -25, -25,
87     -25, -25, -25, -35, -35, -35, -25, -25, -25, 520,
88     -100, -100, -45, -100, -45, -100, -45, -100, -45, -100,
89     -26, -100, -25, 540, 580, 590, 600, 610, 630, 640,
90     -25, -35, -35, -35, -25, -25, -35, -35, -35, 550,
91     -35, -35, -25, -25, -25, -25, 560, 570, -25, -35,
92     -35, -35, -35, -35, -25, -25, -25, -25, -25, -25,
93     -25, -25, -25, -25, -35, -25, -25, -35, -25, -25,
94     -25, -25, -25, -25, -35, -35, -25, -35, -35, -25,
95     -35, -35, -25, -35, -35, -35, -35, -35, -35, -25,
96     -100, -35, -35, -35, -35, -35, -35, -35, -35, -35,
97     -36, -100, -35, -35, -35, -35, 620, -35, -35, -100,
98     -35, -35, -35, -35, -35, -35, -35, -35, -35, -45,
99     -25, -35, -25, -25, -35, -35, -35, -35, -25, -25,
100     -25, -25, -25, -25, -35, -35, -35, 650, -35, 660,
101     -35, -35, -35, -35, -45, -35, -35, -35, -35, -45,
102     -35, -35, -35, -35, -35, -35, -35, -35, -35, -25,
103     -26, -100, 680, 690, 700, -25, 720, 730, -25, 740,
104     -25, -35, -25, -25, -25, -35, -25, -25, -25, -25,
105     -25, -25, -25, -25, -25, -35, -35, -35, -35, -35,
106     -35, -100, -35, -35, -35, -35, 710, -35, -35, -35,
107     -35, -35, -35, -35, -35, -35, -35, -35, -45, -35,
108     -25, -35, -25, -35, -25, -35, -35, -35, -35, -25,
109     -35, -35, -35, -35, -35, -25, -35, -25, -35, -35,
110     -35, -35, -25, -25, 750, 760, 770, -35, -35, -35,
111     -25, -35, -25, -25, -25, -25, -35, -35, -35, -25,
112     -25, -35, -35, -35, -35, -25, -25, -35, -35, -25,
113     -25, -35, -35, -35, -35, -35, -25, -25, -35, -35,
114     790, -100, 800, 850, 900, 920, 940, 1030, 1040, 1050,
115     -36, -26, -26, -26, -26, -26, -26, -26, -26, -26,
116     -35, -25, -25, -35, 810, -25, -35, -35, -25, 820,
117     -25, -35, -25, -25, -35, -35, -35, -35, -35, -25,
118     -25, -35, 830, -35, 840, -35, -25, -35, -35, -25,
119     -35, -25, -25, -25, -25, -25, -25, -25, -25, -25,
120     -100, -25, -25, -25, -100, -100, -100, -100, -100, -100,
121     -25, -25, -35, -35, -35, -35, 860, -35, 870, 880,
122     -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
123     -35, -35, -35, -35, -35, -35, -35, -45, -45, -35,
124     -100, -100, -100, -100, -100, -100, 890, -100, -100, -100,
125     -25, -45, -45, -25, -45, -45, -25, -45, -45, -45,
126     -25, -25, -25, -25, -25, -35, -35, 910, -35, -25,
127     -35, -35, -35, -35, -35, -35, -35, -45, -35, -35,
128     -100, 930, -35, -35, -35, -35, -35, -35, -35, -35,
129     -100, -100, -45, -100, -45, -100, -100, -100, -100, -100,
130     -25, -25, -25, 950, -25, 970, 990, -35, 1000, 1010,
131     -35, -35, -35, -35, -35, -35, 960, -35, -35, -35,
132     -45, -45, -45, -45, -45, -45, -35, -45, -45, -45,
133     -35, -35, -25, -35, -35, 980, -35, -35, -35, -35,
134     -100, -100, -25, -25, -100, -100, -100, -100, -100, -100,
135     -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
136     -25, -35, -35, -35, -35, -35, -35, -35, -35, -25,
137     -25, -35, -35, -35, -25, -25, -35, -35, -35, 1020,
138     -45, -45, -35, -35, -45, -45, -45, -45, -45, -45,
139     -25, -25, -25, -25, -25, -35, -25, -35, -25, -35,
140     -35, -25, -25, -35, -35, -35, -25, -35, -25, -35,
141     -25, -25, -35, -35, -35, -35, -35, -35, -35, -25,
142     -26, -100, 1070, 1080, 1090, 1110, 1120, 1130, 1140, 1160,
143     -35, -25, -25, -25, -25, -25, -25, -25, -25, -25,
144     -35, -25, -25, -25, -25, -25, -25, -25, -25, -25,
145     -35, -100, -35, -35, -35, -100, -35, -35, -35, 1100,
146     -35, -35, -35, -35, -35, -35, -45, -35, -35, -35,
147     -35, -25, -35, -25, -35, -35, -35, -35, -25, -35,
148     -25, -25, -25, -25, -35, -35, -35, -35, -35, -35,
149     -25, -25, -35, -35, -35, -25, -25, -35, -35, -35,
150     1150, -25, -35, -35, -35, -35, -35, -35, -25, -25,
151     -35, -35, -45, -35, -35, -35, -35, -35, -35, -35,
152     -35, 1170, -25, -35, 1180, -35, 1190, -35, -25, -25,
153     -100, -100, -45, -45, -100, -100, -100, -100, -100, -100,
154     -25, -35, -35, -35, -35, -35, -35, -25, -25, -35,
155     -35, -35, -35, -35, -35, -35, -35, -35, -35, -45,
156     -26, -15, -15, -15, -15, -15, -15, -15, -15, -15};
157 
158     @UnsupportedAppUsage
format(Editable text)159     public static void format(Editable text) {
160         // Here, "root" means the position of "'":
161         // 0'3, 0'90, and +81'-90
162         // (dash will be deleted soon, so it is actually +81'90).
163         int rootIndex = 1;
164         int length = text.length();
165         if (length > 3
166                 && text.subSequence(0, 3).toString().equals("+81")) {
167             rootIndex = 3;
168         } else if (length < 1 || text.charAt(0) != '0') {
169             return;
170         }
171 
172         CharSequence saved = text.subSequence(0, length);
173 
174         // Strip the dashes first, as we're going to add them back
175         int i = 0;
176         while (i < text.length()) {
177             if (text.charAt(i) == '-') {
178                 text.delete(i, i + 1);
179             } else {
180                 i++;
181             }
182         }
183 
184         length = text.length();
185         int dashposition;
186 
187         i = rootIndex;
188         int base = 0;
189         while (i < length) {
190             char ch = text.charAt(i);
191             if (!Character.isDigit(ch)) {
192                 text.replace(0, length, saved);
193                 return;
194             }
195             short value = FORMAT_MAP[base + ch - '0'];
196             if (value < 0) {
197                 if (value <= -100) {
198                     text.replace(0, length, saved);
199                     return;
200                 }
201                 int dashPos2 = rootIndex + (Math.abs(value) % 10);
202                 if (length > dashPos2) {
203                     text.insert(dashPos2, "-");
204                 }
205                 int dashPos1 = rootIndex + (Math.abs(value) / 10);
206                 if (length > dashPos1) {
207                     text.insert(dashPos1, "-");
208                 }
209                 break;
210             } else {
211                 base = value;
212                 i++;
213             }
214         }
215 
216         if (length > 3 && rootIndex == 3) {
217             text.insert(rootIndex, "-");
218         }
219     }
220 }