1e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler/*
2e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * Copyright (C) 2015 The Android Open Source Project
3e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler *
4e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
5e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * you may not use this file except in compliance with the License.
6e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * You may obtain a copy of the License at
7e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler *
8e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
9e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler *
10e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * Unless required by applicable law or agreed to in writing, software
11e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
12e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * See the License for the specific language governing permissions and
14e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler * limitations under the License
15e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler */
16e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
17e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerpackage com.android.settingslib;
18e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
19e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.content.Context;
20e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.content.Intent;
21e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.content.pm.ApplicationInfo;
22e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.content.pm.PackageManager;
23e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.content.pm.ResolveInfo;
24e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.os.Build;
2575ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhangimport android.telephony.PhoneNumberUtils;
2675ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhangimport android.telephony.SubscriptionInfo;
2775ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhangimport android.telephony.TelephonyManager;
28e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.text.TextUtils;
29e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.text.format.DateFormat;
30e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport android.util.Log;
31e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
32e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.io.BufferedReader;
33e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.io.FileReader;
34e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.io.IOException;
35e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.text.ParseException;
36e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.text.SimpleDateFormat;
37e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.util.Date;
38e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.util.List;
39e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.util.Locale;
40e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.util.regex.Matcher;
41e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerimport java.util.regex.Pattern;
42e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
4375ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhangimport static android.content.Context.TELEPHONY_SERVICE;
4475ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang
45e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantlerpublic class DeviceInfoUtils {
46e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    private static final String TAG = "DeviceInfoUtils";
47e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
48e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    private static final String FILENAME_PROC_VERSION = "/proc/version";
49e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    private static final String FILENAME_MSV = "/sys/board_properties/soc/msv";
50e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
51e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    /**
52e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler     * Reads a line from the specified file.
53e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler     * @param filename the file to read from
54e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler     * @return the first line, if any.
55e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler     * @throws IOException if the file couldn't be read
56e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler     */
57e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    private static String readLine(String filename) throws IOException {
58e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        BufferedReader reader = new BufferedReader(new FileReader(filename), 256);
59e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        try {
60e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            return reader.readLine();
61e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        } finally {
62e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            reader.close();
63e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        }
64e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    }
65e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
66e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    public static String getFormattedKernelVersion() {
67e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        try {
68e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            return formatKernelVersion(readLine(FILENAME_PROC_VERSION));
69e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        } catch (IOException e) {
70e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            Log.e(TAG, "IO Exception when getting kernel version for Device Info screen",
71e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                    e);
72e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
73e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            return "Unavailable";
74e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        }
75e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    }
76e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
77e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    public static String formatKernelVersion(String rawKernelVersion) {
78e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        // Example (see tests for more):
79e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        // Linux version 3.0.31-g6fb96c9 (android-build@xxx.xxx.xxx.xxx.com) \
80e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        //     (gcc version 4.6.x-xxx 20120106 (prerelease) (GCC) ) #1 SMP PREEMPT \
81e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        //     Thu Jun 28 11:02:39 PDT 2012
82e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
83e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        final String PROC_VERSION_REGEX =
84e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                "Linux version (\\S+) " + /* group 1: "3.0.31-g6fb96c9" */
857091e2fdc016932e497223f09eab1287aa8bbd0bNick Desaulniers                "\\((\\S+)\\)" +          /* group 2: "x@y.com" (kernel builder) */
867091e2fdc016932e497223f09eab1287aa8bbd0bNick Desaulniers                ".*(#\\d+)" +             /* group 3: "#1" */
877091e2fdc016932e497223f09eab1287aa8bbd0bNick Desaulniers                /* group 4: "Thu Jun 28 11:02:39 PDT 2012" */
887091e2fdc016932e497223f09eab1287aa8bbd0bNick Desaulniers                ".*((?:Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)";
89e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
90e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        Matcher m = Pattern.compile(PROC_VERSION_REGEX).matcher(rawKernelVersion);
91e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        if (!m.matches()) {
92e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            Log.e(TAG, "Regex did not match on /proc/version: " + rawKernelVersion);
93e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            return "Unavailable";
94e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        } else if (m.groupCount() < 4) {
95e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            Log.e(TAG, "Regex match on /proc/version only returned " + m.groupCount()
96e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                    + " groups");
97e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            return "Unavailable";
98e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        }
99e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        return m.group(1) + "\n" +                 // 3.0.31-g6fb96c9
100e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                m.group(2) + " " + m.group(3) + "\n" + // x@y.com #1
101e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                m.group(4);                            // Thu Jun 28 11:02:39 PDT 2012
102e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    }
103e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
104e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    /**
105e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler     * Returns " (ENGINEERING)" if the msv file has a zero value, else returns "".
106e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler     * @return a string to append to the model number description.
107e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler     */
108e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    public static String getMsvSuffix() {
109e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        // Production devices should have a non-zero value. If we can't read it, assume it's a
110e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        // production device so that we don't accidentally show that it's an ENGINEERING device.
111e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        try {
112e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            String msv = readLine(FILENAME_MSV);
113e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            // Parse as a hex number. If it evaluates to a zero, then it's an engineering build.
114e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            if (Long.parseLong(msv, 16) == 0) {
115e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                return " (ENGINEERING)";
116e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            }
117e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        } catch (IOException|NumberFormatException e) {
118e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            // Fail quietly, as the file may not exist on some devices, or may be unreadable
119e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        }
120e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        return "";
121e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    }
122e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
123e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    public static String getFeedbackReporterPackage(Context context) {
124e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        final String feedbackReporter =
125e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                context.getResources().getString(R.string.oem_preferred_feedback_reporter);
126e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        if (TextUtils.isEmpty(feedbackReporter)) {
127e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            // Reporter not configured. Return.
128e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            return feedbackReporter;
129e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        }
130e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        // Additional checks to ensure the reporter is on system image, and reporter is
131e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        // configured to listen to the intent. Otherwise, dont show the "send feedback" option.
132e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        final Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
133e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
134e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        PackageManager pm = context.getPackageManager();
135e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        List<ResolveInfo> resolvedPackages =
136e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
137e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        for (ResolveInfo info : resolvedPackages) {
138e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            if (info.activityInfo != null) {
139e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                if (!TextUtils.isEmpty(info.activityInfo.packageName)) {
140e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                    try {
141e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                        ApplicationInfo ai =
142e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                                pm.getApplicationInfo(info.activityInfo.packageName, 0);
143e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                        if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
144e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                            // Package is on the system image
145e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                            if (TextUtils.equals(
146e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                                    info.activityInfo.packageName, feedbackReporter)) {
147e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                                return feedbackReporter;
148e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                            }
149e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                        }
150e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                    } catch (PackageManager.NameNotFoundException e) {
151e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                        // No need to do anything here.
152e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                    }
153e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                }
154e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            }
155e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        }
156e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        return null;
157e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    }
158e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
159e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    public static String getSecurityPatch() {
160e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        String patch = Build.VERSION.SECURITY_PATCH;
161e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        if (!"".equals(patch)) {
162e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            try {
163e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                SimpleDateFormat template = new SimpleDateFormat("yyyy-MM-dd");
164e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                Date patchDate = template.parse(patch);
165e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                String format = DateFormat.getBestDateTimePattern(Locale.getDefault(), "dMMMMyyyy");
166e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                patch = DateFormat.format(format, patchDate).toString();
167e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            } catch (ParseException e) {
168e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler                // broken parse; fall through and use the raw string
169e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            }
170e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            return patch;
171e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        } else {
172e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler            return null;
173e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler        }
174e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler    }
175e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler
17675ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang    public static String getFormattedPhoneNumber(Context context, SubscriptionInfo subscriptionInfo) {
17775ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang        String formattedNumber = null;
17875ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang        if (subscriptionInfo != null) {
17975ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            final TelephonyManager telephonyManager =
18075ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                    (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE);
18175ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            final String rawNumber =
18275ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                    telephonyManager.getLine1Number(subscriptionInfo.getSubscriptionId());
18375ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            if (!TextUtils.isEmpty(rawNumber)) {
18475ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
18575ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            }
18675ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang
18775ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang        }
18875ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang        return formattedNumber;
18975ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang    }
19075ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang
19175ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang    public static String getFormattedPhoneNumbers(Context context,
19275ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            List<SubscriptionInfo> subscriptionInfo) {
19375ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang        StringBuilder sb = new StringBuilder();
19475ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang        if (subscriptionInfo != null) {
19575ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            final TelephonyManager telephonyManager =
19675ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                    (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE);
19775ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            final int count = subscriptionInfo.size();
19875ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            for (int i = 0; i < count; i++) {
19975ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                final String rawNumber = telephonyManager.getLine1Number(
20075ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                        subscriptionInfo.get(i).getSubscriptionId());
20175ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                if (!TextUtils.isEmpty(rawNumber)) {
20275ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                    sb.append(PhoneNumberUtils.formatNumber(rawNumber));
20375ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                    if (i < count - 1) {
20475ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                        sb.append("\n");
20575ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                    }
20675ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang                }
20775ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang            }
20875ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang        }
20975ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang        return sb.toString();
21075ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang    }
21175ee8d18f1fa986bcdd896d1bbc610b5173d7222Fan Zhang
212e92cf6d7396a044c578ce2338890bcbb5e98ed75Tony Mantler}
213