Merge "Fix the build: Revert "Switching to the final PDF rendering library""
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index a233b1d..f36c36a 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -73,7 +73,7 @@
}
private static SharedElementListener getListener(Activity activity, boolean isReturning) {
- return isReturning ? activity.mExitTransitionListener : activity.mEnterTransitionListener;
+ return isReturning ? activity.mEnterTransitionListener : activity.mExitTransitionListener;
}
@Override
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
index 643e8c2..fa9f479 100644
--- a/core/java/android/net/LocalSocketImpl.java
+++ b/core/java/android/net/LocalSocketImpl.java
@@ -56,7 +56,10 @@
/** {@inheritDoc} */
@Override
public int available() throws IOException {
- return available_native(fd);
+ FileDescriptor myFd = fd;
+ if (myFd == null) throw new IOException("socket closed");
+
+ return available_native(myFd);
}
/** {@inheritDoc} */
diff --git a/core/res/res/drawable-hdpi/popup_background_qntm_mult.9.png b/core/res/res/drawable-hdpi/popup_background_qntm_mult.9.png
new file mode 100644
index 0000000..385734e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/popup_background_qntm_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_background_qntm_mult.9.png b/core/res/res/drawable-mdpi/popup_background_qntm_mult.9.png
new file mode 100644
index 0000000..e920499
--- /dev/null
+++ b/core/res/res/drawable-mdpi/popup_background_qntm_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/popup_background_qntm_mult.9.png b/core/res/res/drawable-xhdpi/popup_background_qntm_mult.9.png
new file mode 100644
index 0000000..a081ceb
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/popup_background_qntm_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/popup_background_qntm_mult.9.png b/core/res/res/drawable-xxhdpi/popup_background_qntm_mult.9.png
new file mode 100644
index 0000000..fb7d715
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/popup_background_qntm_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable/popup_background_quantum.xml b/core/res/res/drawable/popup_background_quantum.xml
index 7e5b003..a4d0291 100644
--- a/core/res/res/drawable/popup_background_quantum.xml
+++ b/core/res/res/drawable/popup_background_quantum.xml
@@ -14,12 +14,7 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
-
- <corners
- android:radius="2dp" />
- <solid
- android:color="?attr/colorBackground" />
-
-</shape>
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/popup_background_qntm_mult"
+ android:tint="?attr/colorBackground"
+ android:tintMode="multiply" />
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index 705143c..63df5be 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -17,12 +17,15 @@
<style name="Theme.DeviceDefault" parent="Theme.Micro" />
<style name="Theme.DeviceDefault.NoActionBar" parent="Theme.Micro" />
<style name="Theme.DeviceDefault.Dialog" parent="Theme.Micro.Dialog" />
+ <style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Micro.Dialog" />
<style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Micro.Dialog.Alert" />
<style name="Theme.DeviceDefault.Light" parent="Theme.Micro.Light" />
<style name="Theme.DeviceDefault.Light.NoActionBar" parent="Theme.Micro.Light" />
<style name="Theme.DeviceDefault.Light.DarkActionBar" parent="Theme.Micro.Light" />
<style name="Theme.DeviceDefault.Light.Dialog" parent="Theme.Micro.Dialog" />
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="Theme.Micro.Dialog" />
<style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Micro.Dialog.Alert" />
+ <style name="Theme.DeviceDefault.Wallpaper" parent="Theme.Micro" />
</resources>
diff --git a/core/res/res/values/colors_quantum.xml b/core/res/res/values/colors_quantum.xml
index 7171450..556463e 100644
--- a/core/res/res/values/colors_quantum.xml
+++ b/core/res/res/values/colors_quantum.xml
@@ -16,11 +16,11 @@
<!-- Colors specific to Quantum themes. -->
<resources>
- <color name="background_quantum_dark">@color/black</color>
+ <color name="background_quantum_dark">#ff303030</color>
<color name="background_quantum_light">@color/white</color>
- <color name="bright_foreground_quantum_dark">@color/background_quantum_light</color>
- <color name="bright_foreground_quantum_light">@color/background_quantum_dark</color>
+ <color name="bright_foreground_quantum_dark">@color/white</color>
+ <color name="bright_foreground_quantum_light">@color/black</color>
<!-- TODO: This is 50% alpha black -->
<color name="bright_foreground_disabled_quantum_dark">#80000000</color>
<!-- TODO: This is 50% alpha white -->
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 1baaaa4..8eb83e4 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -791,11 +791,17 @@
/**
* Poll for a timestamp on demand.
- *
- * Use if you need to get the most recent timestamp outside of the event callback handler.
- * Calling this method too often may be inefficient;
- * if you need a high-resolution mapping between frame position and presentation time,
+ * <p>
+ * If you need to track timestamps during initial warmup or after a routing or mode change,
+ * you should request a new timestamp once per second until the reported timestamps
+ * show that the audio clock is stable.
+ * Thereafter, query for a new timestamp approximately once every 10 seconds to once per minute.
+ * Calling this method more often is inefficient.
+ * It is also counter-productive to call this method more often than recommended,
+ * because the short-term differences between successive timestamp reports are not meaningful.
+ * If you need a high-resolution mapping between frame position and presentation time,
* consider implementing that at application level, based on low-resolution timestamps.
+ * <p>
* The audio data at the returned position may either already have been
* presented, or may have not yet been presented but is committed to be presented.
* It is not possible to request the time corresponding to a particular position,
@@ -811,6 +817,8 @@
* be presented.
* In the case that no timestamp is available, any supplied instance is left unaltered.
*/
+ // Add this text when the "on new timestamp" API is added:
+ // Use if you need to get the most recent timestamp outside of the event callback handler.
public boolean getTimestamp(AudioTimestamp timestamp)
{
if (timestamp == null) {
diff --git a/media/lib/signer/Android.mk b/media/lib/signer/Android.mk
index 4c3772f..bca643a 100644
--- a/media/lib/signer/Android.mk
+++ b/media/lib/signer/Android.mk
@@ -25,7 +25,7 @@
LOCAL_SRC_FILES := \
$(call all-java-files-under, java)
-include $(BUILD_STATIC_JAVA_LIBRARY)
+include $(BUILD_JAVA_LIBRARY)
# ==== com.android.mediadrm.signer.xml lib def ========================
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 6b7463c..88de17a 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -18,7 +18,6 @@
import android.net.Uri;
import android.os.Bundle;
-import android.util.Log;
import java.util.HashSet;
import java.util.Set;
@@ -28,8 +27,6 @@
*/
public abstract class Connection {
- private static String TAG = Connection.class.getSimpleName();
-
public interface Listener {
void onStateChanged(Connection c, int state);
void onAudioStateChanged(Connection c, CallAudioState state);
@@ -146,7 +143,7 @@
* @hide
*/
public final void playDtmfTone(char c) {
- Log.d(TAG, "playDtmfTone " + c);
+ Log.d(this, "playDtmfTone %c", c);
onPlayDtmfTone(c);
}
@@ -156,7 +153,7 @@
* @hide
*/
public final void stopDtmfTone() {
- Log.d(TAG, "stopDtmfTone");
+ Log.d(this, "stopDtmfTone");
onStopDtmfTone();
}
@@ -168,7 +165,7 @@
* @hide
*/
public final void disconnect() {
- Log.d(TAG, "disconnect");
+ Log.d(this, "disconnect");
onDisconnect();
}
@@ -180,7 +177,7 @@
* @hide
*/
public final void abort() {
- Log.d(TAG, "abort");
+ Log.d(this, "abort");
onAbort();
}
@@ -192,7 +189,7 @@
* @hide
*/
public final void hold() {
- Log.d(TAG, "hold");
+ Log.d(this, "hold");
onHold();
}
@@ -204,7 +201,7 @@
* @hide
*/
public final void unhold() {
- Log.d(TAG, "unhold");
+ Log.d(this, "unhold");
onUnhold();
}
@@ -216,7 +213,7 @@
* @hide
*/
public final void answer() {
- Log.d(TAG, "answer");
+ Log.d(this, "answer");
if (mState == State.RINGING) {
onAnswer();
}
@@ -230,7 +227,7 @@
* @hide
*/
public final void reject() {
- Log.d(TAG, "reject");
+ Log.d(this, "reject");
if (mState == State.RINGING) {
onReject();
}
@@ -242,7 +239,7 @@
* @param state The new audio state.
*/
public void setAudioState(CallAudioState state) {
- Log.d(TAG, "setAudioState " + state);
+ Log.d(this, "setAudioState %s", state);
onSetAudioState(state);
}
@@ -265,7 +262,7 @@
case State.DISCONNECTED:
return "DISCONNECTED";
default:
- Log.wtf(TAG, "Unknown state " + state);
+ Log.wtf(Connection.class, "Unknown state %d", state);
return "UNKNOWN";
}
}
@@ -276,7 +273,7 @@
* @param handle The new handle.
*/
protected void setHandle(Uri handle) {
- Log.d(TAG, "setHandle " + handle);
+ Log.d(this, "setHandle %s", handle);
// TODO: Enforce super called
mHandle = handle;
for (Listener l : mListeners) {
@@ -325,7 +322,7 @@
*/
protected void setDisconnected(int cause, String message) {
setState(State.DISCONNECTED);
- Log.d(TAG, "Disconnected with cause " + cause + " message " + message);
+ Log.d(this, "Disconnected with cause %d message %s", cause, message);
for (Listener l : mListeners) {
l.onDisconnected(this, cause, message);
}
@@ -403,7 +400,7 @@
protected void onReject() {}
private void setState(int state) {
- Log.d(TAG, "setState: " + stateToString(state));
+ Log.d(this, "setState: %s", stateToString(state));
this.mState = state;
for (Listener l : mListeners) {
l.onStateChanged(this, state);
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index aba4579..9ace36f 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -18,7 +18,6 @@
import android.net.Uri;
import android.os.Bundle;
-import android.util.Log;
import java.util.HashMap;
import java.util.Map;
@@ -28,13 +27,8 @@
* processes running on an Android device.
*/
public abstract class ConnectionService extends CallService {
- private static final String TAG = ConnectionService.class.getSimpleName();
-
- // STOPSHIP: Debug Logging should be conditional on a debug flag or use a set of
- // logging functions that make it automaticaly so.
-
// Flag controlling whether PII is emitted into the logs
- private static final boolean PII_DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
private static final Connection NULL_CONNECTION = new Connection() {};
@@ -46,7 +40,7 @@
@Override
public void onStateChanged(Connection c, int state) {
String id = mIdByConnection.get(c);
- Log.d(TAG, "Adapter set state " + id + " " + Connection.stateToString(state));
+ Log.d(this, "Adapter set state %d %s", id, Connection.stateToString(state));
switch (state) {
case Connection.State.ACTIVE:
getAdapter().setActive(id);
@@ -72,7 +66,7 @@
@Override
public void onDisconnected(Connection c, int cause, String message) {
String id = mIdByConnection.get(c);
- Log.d(TAG, "Adapter set disconnected " + cause + " " + message);
+ Log.d(this, "Adapter set disconnected %d %s", cause, message);
getAdapter().setDisconnected(id, cause, message);
}
@@ -99,21 +93,21 @@
@Override
public final void isCompatibleWith(final CallInfo callInfo) {
- Log.d(TAG, "isCompatibleWith " + callInfo);
+ Log.d(this, "isCompatibleWith %s", callInfo);
onFindSubscriptions(
callInfo.getHandle(),
new Response<Uri, Subscription>() {
@Override
public void onResult(Uri handle, Subscription... result) {
boolean isCompatible = result.length > 0;
- Log.d(TAG, "adapter setIsCompatibleWith "
+ Log.d(this, "adapter setIsCompatibleWith "
+ callInfo.getId() + " " + isCompatible);
getAdapter().setIsCompatibleWith(callInfo.getId(), isCompatible);
}
@Override
public void onError(Uri handle, String reason) {
- Log.wtf(TAG, "Error in onFindSubscriptions " + callInfo.getHandle()
+ Log.w(this, "Error in onFindSubscriptions " + callInfo.getHandle()
+ " error: " + reason);
getAdapter().setIsCompatibleWith(callInfo.getId(), false);
}
@@ -123,7 +117,7 @@
@Override
public final void call(final CallInfo callInfo) {
- Log.d(TAG, "call " + callInfo);
+ Log.d(this, "call %s", callInfo);
onCreateConnections(
new ConnectionRequest(
callInfo.getHandle(),
@@ -132,7 +126,7 @@
@Override
public void onResult(ConnectionRequest request, Connection... result) {
if (result.length != 1) {
- Log.d(TAG, "adapter handleFailedOutgoingCall " + callInfo);
+ Log.d(this, "adapter handleFailedOutgoingCall %s", callInfo);
getAdapter().handleFailedOutgoingCall(
callInfo.getId(),
"Created " + result.length + " Connections, expected 1");
@@ -141,8 +135,7 @@
}
} else {
addConnection(callInfo.getId(), result[0]);
- Log.d(TAG, "adapter handleSuccessfulOutgoingCall "
- + callInfo.getId());
+ Log.d(this, "adapter handleSuccessfulOutgoingCall %s", callInfo.getId());
getAdapter().handleSuccessfulOutgoingCall(callInfo.getId());
}
}
@@ -157,13 +150,13 @@
@Override
public final void abort(String callId) {
- Log.d(TAG, "abort " + callId);
+ Log.d(this, "abort %s", callId);
findConnectionForAction(callId, "abort").abort();
}
@Override
public final void setIncomingCallId(final String callId, Bundle extras) {
- Log.d(TAG, "setIncomingCallId " + callId + " " + extras);
+ Log.d(this, "setIncomingCallId %s %s", callId, extras);
onCreateIncomingConnection(
new ConnectionRequest(
null, // TODO: Can we obtain this from "extras"?
@@ -172,7 +165,7 @@
@Override
public void onResult(ConnectionRequest request, Connection... result) {
if (result.length != 1) {
- Log.d(TAG, "adapter handleFailedOutgoingCall " + callId);
+ Log.d(this, "adapter handleFailedOutgoingCall %s", callId);
getAdapter().handleFailedOutgoingCall(
callId,
"Created " + result.length + " Connections, expected 1");
@@ -181,7 +174,7 @@
}
} else {
addConnection(callId, result[0]);
- Log.d(TAG, "adapter notifyIncomingCall " + callId);
+ Log.d(this, "adapter notifyIncomingCall %s", callId);
// TODO: Uri.EMPTY is because CallInfo crashes when Parceled with a
// null URI ... need to fix that at its cause!
getAdapter().notifyIncomingCall(new CallInfo(
@@ -194,7 +187,7 @@
@Override
public void onError(ConnectionRequest request, String reason) {
- Log.d(TAG, "adapter failed setIncomingCallId " + request + " " + reason);
+ Log.d(this, "adapter failed setIncomingCallId %s %s", request, reason);
}
}
);
@@ -202,49 +195,49 @@
@Override
public final void answer(String callId) {
- Log.d(TAG, "answer " + callId);
+ Log.d(this, "answer %s", callId);
findConnectionForAction(callId, "answer").answer();
}
@Override
public final void reject(String callId) {
- Log.d(TAG, "reject " + callId);
+ Log.d(this, "reject %s", callId);
findConnectionForAction(callId, "reject").reject();
}
@Override
public final void disconnect(String callId) {
- Log.d(TAG, "disconnect " + callId);
+ Log.d(this, "disconnect %s", callId);
findConnectionForAction(callId, "disconnect").disconnect();
}
@Override
public final void hold(String callId) {
- Log.d(TAG, "hold " + callId);
+ Log.d(this, "hold %s", callId);
findConnectionForAction(callId, "hold").hold();
}
@Override
public final void unhold(String callId) {
- Log.d(TAG, "unhold " + callId);
+ Log.d(this, "unhold %s", callId);
findConnectionForAction(callId, "unhold").unhold();
}
@Override
public final void playDtmfTone(String callId, char digit) {
- Log.d(TAG, "playDtmfTone " + callId + " " + Character.toString(digit));
+ Log.d(this, "playDtmfTone %s %c", callId, digit);
findConnectionForAction(callId, "playDtmfTone").playDtmfTone(digit);
}
@Override
public final void stopDtmfTone(String callId) {
- Log.d(TAG, "stopDtmfTone " + callId);
+ Log.d(this, "stopDtmfTone %s", callId);
findConnectionForAction(callId, "stopDtmfTone").stopDtmfTone();
}
@Override
public final void onAudioStateChanged(String callId, CallAudioState audioState) {
- Log.d(TAG, "onAudioStateChanged " + callId + " " + audioState);
+ Log.d(this, "onAudioStateChanged %s %s", callId, audioState);
findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState);
}
@@ -318,7 +311,7 @@
case Connection.State.DISCONNECTED:
return CallState.DISCONNECTED;
default:
- Log.wtf(TAG, "Unknown Connection.State " + connectionState);
+ Log.wtf(this, "Unknown Connection.State %d", connectionState);
return CallState.NEW;
}
}
@@ -339,7 +332,7 @@
if (mConnectionById.containsKey(callId)) {
return mConnectionById.get(callId);
}
- Log.wtf(TAG, action + " - Cannot find Connection \"" + callId + "\"");
+ Log.w(this, "%s - Cannot find Connection %s", action, callId);
return NULL_CONNECTION;
}
}
\ No newline at end of file
diff --git a/telecomm/java/android/telecomm/Log.java b/telecomm/java/android/telecomm/Log.java
new file mode 100644
index 0000000..b8dfb11
--- /dev/null
+++ b/telecomm/java/android/telecomm/Log.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2014, 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.
+ */
+
+package android.telecomm;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.IllegalFormatException;
+import java.util.Locale;
+
+/**
+ * Manages logging for the entire module.
+ *
+ * @hide
+ */
+final public class Log {
+
+ // Generic tag for all Telecomm Framework logging
+ private static final String TAG = "TelecommFramework";
+
+ public static final boolean FORCE_LOGGING = true; /* STOP SHIP if true */
+ public static final boolean DEBUG = isLoggable(android.util.Log.DEBUG);
+ public static final boolean INFO = isLoggable(android.util.Log.INFO);
+ public static final boolean VERBOSE = isLoggable(android.util.Log.VERBOSE);
+ public static final boolean WARN = isLoggable(android.util.Log.WARN);
+ public static final boolean ERROR = isLoggable(android.util.Log.ERROR);
+
+ private Log() {}
+
+ public static boolean isLoggable(int level) {
+ return FORCE_LOGGING || android.util.Log.isLoggable(TAG, level);
+ }
+
+ public static void d(String prefix, String format, Object... args) {
+ if (DEBUG) {
+ android.util.Log.d(TAG, buildMessage(prefix, format, args));
+ }
+ }
+
+ public static void d(Object objectPrefix, String format, Object... args) {
+ if (DEBUG) {
+ android.util.Log.d(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
+ }
+ }
+
+ public static void i(String prefix, String format, Object... args) {
+ if (INFO) {
+ android.util.Log.i(TAG, buildMessage(prefix, format, args));
+ }
+ }
+
+ public static void i(Object objectPrefix, String format, Object... args) {
+ if (INFO) {
+ android.util.Log.i(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
+ }
+ }
+
+ public static void v(String prefix, String format, Object... args) {
+ if (VERBOSE) {
+ android.util.Log.v(TAG, buildMessage(prefix, format, args));
+ }
+ }
+
+ public static void v(Object objectPrefix, String format, Object... args) {
+ if (VERBOSE) {
+ android.util.Log.v(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
+ }
+ }
+
+ public static void w(String prefix, String format, Object... args) {
+ if (WARN) {
+ android.util.Log.w(TAG, buildMessage(prefix, format, args));
+ }
+ }
+
+ public static void w(Object objectPrefix, String format, Object... args) {
+ if (WARN) {
+ android.util.Log.w(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
+ }
+ }
+
+ public static void e(String prefix, Throwable tr, String format, Object... args) {
+ if (ERROR) {
+ android.util.Log.e(TAG, buildMessage(prefix, format, args), tr);
+ }
+ }
+
+ public static void e(Object objectPrefix, Throwable tr, String format, Object... args) {
+ if (ERROR) {
+ android.util.Log.e(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args),
+ tr);
+ }
+ }
+
+ public static void wtf(String prefix, Throwable tr, String format, Object... args) {
+ android.util.Log.wtf(TAG, buildMessage(prefix, format, args), tr);
+ }
+
+ public static void wtf(Object objectPrefix, Throwable tr, String format, Object... args) {
+ android.util.Log.wtf(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args),
+ tr);
+ }
+
+ public static void wtf(String prefix, String format, Object... args) {
+ String msg = buildMessage(prefix, format, args);
+ android.util.Log.wtf(TAG, msg, new IllegalStateException(msg));
+ }
+
+ public static void wtf(Object objectPrefix, String format, Object... args) {
+ String msg = buildMessage(getPrefixFromObject(objectPrefix), format, args);
+ android.util.Log.wtf(TAG, msg, new IllegalStateException(msg));
+ }
+
+ /**
+ * Redact personally identifiable information for production users.
+ * If we are running in verbose mode, return the original string, otherwise
+ * return a SHA-1 hash of the input string.
+ */
+ public static String pii(Object pii) {
+ if (pii == null || VERBOSE) {
+ return String.valueOf(pii);
+ }
+ return "[" + secureHash(String.valueOf(pii).getBytes()) + "]";
+ }
+
+ private static String secureHash(byte[] input) {
+ MessageDigest messageDigest;
+ try {
+ messageDigest = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ }
+ messageDigest.update(input);
+ byte[] result = messageDigest.digest();
+ return encodeHex(result);
+ }
+
+ private static String encodeHex(byte[] bytes) {
+ StringBuffer hex = new StringBuffer(bytes.length * 2);
+
+ for (int i = 0; i < bytes.length; i++) {
+ int byteIntValue = bytes[i] & 0xff;
+ if (byteIntValue < 0x10) {
+ hex.append("0");
+ }
+ hex.append(Integer.toString(byteIntValue, 16));
+ }
+
+ return hex.toString();
+ }
+
+ private static String getPrefixFromObject(Object obj) {
+ return obj == null ? "<null>" : obj.getClass().getSimpleName();
+ }
+
+ private static String buildMessage(String prefix, String format, Object... args) {
+ String msg;
+ try {
+ msg = (args == null || args.length == 0) ? format
+ : String.format(Locale.US, format, args);
+ } catch (IllegalFormatException ife) {
+ wtf("Log", ife, "IllegalFormatException: formatString='%s' numArgs=%d", format,
+ args.length);
+ msg = format + " (An error occurred while formatting the message.)";
+ }
+ return String.format(Locale.US, "%s: %s", prefix, msg);
+ }
+}