summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/dialpadview
diff options
context:
space:
mode:
authorroldenburg <roldenburg@google.com>2018-02-15 15:22:24 -0800
committerRyan Oldenburg <roldenburg@google.com>2018-02-22 10:57:29 -0800
commit9c9175fc3cf874d7b1e8f6334b8ba709a9e3a310 (patch)
tree22a037ffc19b006367e2eee75f081a63a811e66c /java/com/android/dialer/dialpadview
parentc54ce2658988ca36ca3dfab00daefca4dcfed3b2 (diff)
Show IMEI/MEID in hex, dec, and barcode when appropriate
Bug: 69063060,71706655 Test: SpecialCharSequenceMgrTest PiperOrigin-RevId: 185910798 Change-Id: I60a614d5357809eb982991caa4765d08a53fe936
Diffstat (limited to 'java/com/android/dialer/dialpadview')
-rw-r--r--java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java147
-rw-r--r--java/com/android/dialer/dialpadview/res/layout/dialog_deviceids.xml26
-rw-r--r--java/com/android/dialer/dialpadview/res/layout/row_deviceid.xml49
-rw-r--r--java/com/android/dialer/dialpadview/res/values/dimens.xml2
-rw-r--r--java/com/android/dialer/dialpadview/res/values/strings.xml6
-rw-r--r--java/com/android/dialer/dialpadview/res/values/styles.xml5
6 files changed, 226 insertions, 9 deletions
diff --git a/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java b/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
index 2b7209eb5..c349d2235 100644
--- a/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
+++ b/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
@@ -17,6 +17,7 @@
package com.android.dialer.dialpadview;
import android.Manifest;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DialogFragment;
@@ -28,6 +29,9 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.Color;
import android.net.Uri;
import android.provider.Settings;
import android.support.annotation.Nullable;
@@ -37,8 +41,15 @@ import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.WindowManager;
import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
import android.widget.Toast;
import com.android.common.io.MoreCloseables;
import com.android.contacts.common.database.NoNullCursorAsyncQueryHandler;
@@ -51,8 +62,14 @@ import com.android.dialer.compat.telephony.TelephonyManagerCompat;
import com.android.dialer.oem.MotorolaUtils;
import com.android.dialer.telecom.TelecomUtil;
import com.android.dialer.util.PermissionsUtil;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
/**
* Helper class to listen for some magic character sequences that are handled specially by the
@@ -66,12 +83,9 @@ import java.util.List;
* shared library?)
*/
public class SpecialCharSequenceMgr {
-
- private static final String TAG = "SpecialCharSequenceMgr";
-
private static final String TAG_SELECT_ACCT_FRAGMENT = "tag_select_acct_fragment";
- private static final String MMI_IMEI_DISPLAY = "*#06#";
+ @VisibleForTesting static final String MMI_IMEI_DISPLAY = "*#06#";
private static final String MMI_REGULATORY_INFO_DISPLAY = "*#07#";
/** ***** This code is used to handle SIM Contact queries ***** */
private static final String ADN_PHONE_NUMBER_COLUMN_NAME = "number";
@@ -306,6 +320,7 @@ public class SpecialCharSequenceMgr {
// TODO: Use TelephonyCapabilities.getDeviceIdLabel() to get the device id label instead of a
// hard-coded string.
+ @SuppressLint("HardwareIds")
static boolean handleDeviceIdDisplay(Context context, String input) {
if (!PermissionsUtil.hasPermission(context, Manifest.permission.READ_PHONE_STATE)) {
return false;
@@ -319,29 +334,143 @@ public class SpecialCharSequenceMgr {
? R.string.imei
: R.string.meid;
- List<String> deviceIds = new ArrayList<String>();
+ View customView = LayoutInflater.from(context).inflate(R.layout.dialog_deviceids, null);
+ ViewGroup holder = customView.findViewById(R.id.deviceids_holder);
+
if (TelephonyManagerCompat.getPhoneCount(telephonyManager) > 1) {
for (int slot = 0; slot < telephonyManager.getPhoneCount(); slot++) {
String deviceId = telephonyManager.getDeviceId(slot);
if (!TextUtils.isEmpty(deviceId)) {
- deviceIds.add(deviceId);
+ addDeviceIdRow(holder, deviceId, /* showBarcode */ false);
}
}
} else {
- deviceIds.add(telephonyManager.getDeviceId());
+ addDeviceIdRow(holder, telephonyManager.getDeviceId(), /* showBarcode */ true);
}
new AlertDialog.Builder(context)
.setTitle(labelResId)
- .setItems(deviceIds.toArray(new String[deviceIds.size()]), null)
+ .setView(customView)
.setPositiveButton(android.R.string.ok, null)
.setCancelable(false)
- .show();
+ .show()
+ .getWindow()
+ .setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
return true;
}
return false;
}
+ private static void addDeviceIdRow(ViewGroup holder, String deviceId, boolean showBarcode) {
+ if (TextUtils.isEmpty(deviceId)) {
+ return;
+ }
+
+ ViewGroup row =
+ (ViewGroup)
+ LayoutInflater.from(holder.getContext()).inflate(R.layout.row_deviceid, holder, false);
+ holder.addView(row);
+
+ // Remove the check digit, if exists. This digit is a checksum of the ID.
+ // See https://en.wikipedia.org/wiki/International_Mobile_Equipment_Identity
+ // and https://en.wikipedia.org/wiki/Mobile_equipment_identifier
+ String hex = deviceId.length() == 15 ? deviceId.substring(0, 14) : deviceId;
+
+ // If this is the valid length IMEI or MEID (14 digits), show it in all formats, otherwise fall
+ // back to just showing the raw hex
+ if (hex.length() == 14) {
+ ((TextView) row.findViewById(R.id.deviceid_hex)).setText(hex);
+ ((TextView) row.findViewById(R.id.deviceid_dec)).setText(getDecimalFromHex(hex));
+ row.findViewById(R.id.deviceid_dec_label).setVisibility(View.VISIBLE);
+ } else {
+ ((TextView) row.findViewById(R.id.deviceid_hex)).setText(deviceId);
+ }
+
+ final ImageView barcode = row.findViewById(R.id.deviceid_barcode);
+ if (showBarcode) {
+ // Wait until the layout pass has completed so we the barcode is measured before drawing. We
+ // do this by adding a layout listener and setting the bitmap after getting the callback.
+ barcode
+ .getViewTreeObserver()
+ .addOnGlobalLayoutListener(
+ new OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ barcode.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ Bitmap barcodeBitmap =
+ generateBarcode(hex, barcode.getWidth(), barcode.getHeight());
+ if (barcodeBitmap != null) {
+ barcode.setImageBitmap(barcodeBitmap);
+ }
+ }
+ });
+ } else {
+ barcode.setVisibility(View.GONE);
+ }
+ }
+
+ private static String getDecimalFromHex(String hex) {
+ final String part1 = hex.substring(0, 8);
+ final String part2 = hex.substring(8);
+
+ long dec1;
+ try {
+ dec1 = Long.parseLong(part1, 16);
+ } catch (NumberFormatException e) {
+ LogUtil.e("SpecialCharSequenceMgr.getDecimalFromHex", "unable to parse hex", e);
+ return "";
+ }
+
+ final String manufacturerCode = String.format(Locale.US, "%010d", dec1);
+
+ long dec2;
+ try {
+ dec2 = Long.parseLong(part2, 16);
+ } catch (NumberFormatException e) {
+ LogUtil.e("SpecialCharSequenceMgr.getDecimalFromHex", "unable to parse hex", e);
+ return "";
+ }
+
+ final String serialNum = String.format(Locale.US, "%08d", dec2);
+
+ StringBuilder builder = new StringBuilder(22);
+ builder
+ .append(manufacturerCode, 0, 5)
+ .append(' ')
+ .append(manufacturerCode, 5, manufacturerCode.length())
+ .append(' ')
+ .append(serialNum, 0, 4)
+ .append(' ')
+ .append(serialNum, 4, serialNum.length());
+ return builder.toString();
+ }
+
+ /**
+ * This method generates a 2d barcode using the zxing library. Each pixel of the bitmap is either
+ * black or white painted vertically. We determine which color using the BitMatrix.get(x, y)
+ * method.
+ */
+ private static Bitmap generateBarcode(String hex, int width, int height) {
+ MultiFormatWriter writer = new MultiFormatWriter();
+ String data = Uri.encode(hex);
+
+ try {
+ BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.CODE_128, width, 1);
+ Bitmap bitmap = Bitmap.createBitmap(bitMatrix.getWidth(), height, Config.RGB_565);
+
+ for (int i = 0; i < bitMatrix.getWidth(); i++) {
+ // Paint columns of width 1
+ int[] column = new int[height];
+ Arrays.fill(column, bitMatrix.get(i, 0) ? Color.BLACK : Color.WHITE);
+ bitmap.setPixels(column, 0, 1, i, 0, 1, height);
+ }
+ return bitmap;
+ } catch (WriterException e) {
+ LogUtil.e("SpecialCharSequenceMgr.generateBarcode", "error generating barcode", e);
+ }
+ return null;
+ }
+
private static boolean handleRegulatoryInfoDisplay(Context context, String input) {
if (input.equals(MMI_REGULATORY_INFO_DISPLAY)) {
LogUtil.i(
diff --git a/java/com/android/dialer/dialpadview/res/layout/dialog_deviceids.xml b/java/com/android/dialer/dialpadview/res/layout/dialog_deviceids.xml
new file mode 100644
index 000000000..89e256bde
--- /dev/null
+++ b/java/com/android/dialer/dialpadview/res/layout/dialog_deviceids.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:id="@+id/deviceids_holder"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="?dialogPreferredPadding"
+ android:paddingEnd="?dialogPreferredPadding"
+ android:orientation="vertical"/>
+</ScrollView>
diff --git a/java/com/android/dialer/dialpadview/res/layout/row_deviceid.xml b/java/com/android/dialer/dialpadview/res/layout/row_deviceid.xml
new file mode 100644
index 000000000..53f3e5d0d
--- /dev/null
+++ b/java/com/android/dialer/dialpadview/res/layout/row_deviceid.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="?dialogPreferredPadding"
+ android:orientation="vertical">
+ <TextView
+ style="@style/DeviceIdBody"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/hex"/>
+ <TextView
+ android:id="@+id/deviceid_hex"
+ style="@style/DeviceIdBody"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/deviceid_dec_label"
+ style="@style/DeviceIdBody"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dec"
+ android:visibility="gone"/>
+ <TextView
+ android:id="@+id/deviceid_dec"
+ style="@style/DeviceIdBody"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <ImageView
+ android:id="@+id/deviceid_barcode"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/barcode_height"
+ android:layout_margin="24dp"
+ android:layout_gravity="center_horizontal"/>
+</LinearLayout>
diff --git a/java/com/android/dialer/dialpadview/res/values/dimens.xml b/java/com/android/dialer/dialpadview/res/values/dimens.xml
index 4b386eeb5..6892fcf30 100644
--- a/java/com/android/dialer/dialpadview/res/values/dimens.xml
+++ b/java/com/android/dialer/dialpadview/res/values/dimens.xml
@@ -43,4 +43,6 @@
<!-- Length of dialpad's shadows in dialer. -->
<dimen name="shadow_length">10dp</dimen>
+
+ <dimen name="barcode_height">100dp</dimen>
</resources>
diff --git a/java/com/android/dialer/dialpadview/res/values/strings.xml b/java/com/android/dialer/dialpadview/res/values/strings.xml
index 094ca6b8f..51367b644 100644
--- a/java/com/android/dialer/dialpadview/res/values/strings.xml
+++ b/java/com/android/dialer/dialpadview/res/values/strings.xml
@@ -77,6 +77,12 @@
<!-- The title of a dialog that displays the MEID of the CDMA phone -->
<string name="meid">MEID</string>
+ <!-- The label for the hex encoding of the device ID -->
+ <string name="hex" translatable="false">HEX:</string>
+
+ <!-- The label for the decimal encoding of the device ID -->
+ <string name="dec" translatable="false">DEC:</string>
+
<!-- Dialog text displayed when loading a phone number from the SIM card for speed dial -->
<string name="simContacts_emptyLoading">Loading from SIM card\u2026</string>
diff --git a/java/com/android/dialer/dialpadview/res/values/styles.xml b/java/com/android/dialer/dialpadview/res/values/styles.xml
index d69e6a832..75a54a305 100644
--- a/java/com/android/dialer/dialpadview/res/values/styles.xml
+++ b/java/com/android/dialer/dialpadview/res/values/styles.xml
@@ -116,4 +116,9 @@
<item name="dialpad_voicemail_tint">?attr/dialpad_text_color_secondary</item>
<item name="dialpad_background">#00000000</item>
</style>
+
+ <style name="DeviceIdBody">
+ <item name="android:textColor">?android:textColorPrimary</item>
+ <item name="android:textSize">16sp</item>
+ </style>
</resources>