Merge "Adding toStrings() to the API." into nyc-dev
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index de90202..10808da 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -624,6 +624,21 @@
                     parcelableCall.getExtras(),
                     parcelableCall.getIntentExtras());
         }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("[pa: ");
+            sb.append(mAccountHandle);
+            sb.append(", hdl: ");
+            sb.append(Log.pii(mHandle));
+            sb.append(", caps: ");
+            sb.append(capabilitiesToString(mCallCapabilities));
+            sb.append(", props: ");
+            sb.append(mCallProperties);
+            sb.append("]");
+            return sb.toString();
+        }
     }
 
     public static abstract class Callback {
@@ -1000,6 +1015,48 @@
         }
     }
 
+    @Override
+    public String toString() {
+        return new StringBuilder().
+                append("Call [id: ").
+                append(mTelecomCallId).
+                append(", state: ").
+                append(stateToString(mState)).
+                append(", details: ").
+                append(mDetails).
+                append("]").toString();
+    }
+
+    /**
+     * @param state An integer value of a {@code STATE_*} constant.
+     * @return A string representation of the value.
+     */
+    private static String stateToString(int state) {
+        switch (state) {
+            case STATE_NEW:
+                return "NEW";
+            case STATE_RINGING:
+                return "RINGING";
+            case STATE_DIALING:
+                return "DIALING";
+            case STATE_ACTIVE:
+                return "ACTIVE";
+            case STATE_HOLDING:
+                return "HOLDING";
+            case STATE_DISCONNECTED:
+                return "DISCONNECTED";
+            case STATE_CONNECTING:
+                return "CONNECTING";
+            case STATE_DISCONNECTING:
+                return "DISCONNECTING";
+            case STATE_SELECT_PHONE_ACCOUNT:
+                return "SELECT_PHONE_ACCOUNT";
+            default:
+                Log.w(Call.class, "Unknown state %d", state);
+                return "UNKNOWN";
+        }
+    }
+
     /**
      * Adds a listener to this {@code Call}.
      *
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index 3f32dbe..2ab0525 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -16,7 +16,10 @@
 
 package android.telecom;
 
+import android.net.Uri;
 import android.os.AsyncTask;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
 
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -152,10 +155,37 @@
     public static String pii(Object pii) {
         if (pii == null || VERBOSE) {
             return String.valueOf(pii);
+        } if (pii instanceof Uri) {
+            return piiUri((Uri) pii);
         }
         return "[" + secureHash(String.valueOf(pii).getBytes()) + "]";
     }
 
+    private static String piiUri(Uri handle) {
+        StringBuilder sb = new StringBuilder();
+        String scheme = handle.getScheme();
+        if (!TextUtils.isEmpty(scheme)) {
+            sb.append(scheme).append(":");
+        }
+        String value = handle.getSchemeSpecificPart();
+        if (!TextUtils.isEmpty(value)) {
+            for (int i = 0; i < value.length(); i++) {
+                char c = value.charAt(i);
+                if (PhoneNumberUtils.isStartsPostDial(c)) {
+                    sb.append(c);
+                } else if (PhoneNumberUtils.isDialable(c)) {
+                    sb.append("*");
+                } else if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {
+                    sb.append("*");
+                } else {
+                    sb.append(c);
+                }
+            }
+        }
+        return sb.toString();
+
+    }
+
     private static String secureHash(byte[] input) {
         if (sMessageDigest != null) {
             sMessageDigest.reset();