auto import from //depot/cupcake/@135843
diff --git a/libs/utils/Debug.cpp b/libs/utils/Debug.cpp
new file mode 100644
index 0000000..f7988ec
--- /dev/null
+++ b/libs/utils/Debug.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+#include <utils/Debug.h>
+
+#include <utils/misc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------
+
+static const char indentStr[] =
+"                                                                            "
+"                                                                            ";
+
+const char* stringForIndent(int32_t indentLevel)
+{
+    ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
+    return indentStr + (off < 0 ? 0 : off);
+}
+
+// ---------------------------------------------------------------------
+
+static void defaultPrintFunc(void* cookie, const char* txt)
+{
+    printf("%s", txt);
+}
+
+// ---------------------------------------------------------------------
+
+static inline int isident(int c)
+{
+    return isalnum(c) || c == '_';
+}
+
+static inline bool isasciitype(char c)
+{
+    if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
+    return false;
+}
+
+static inline char makehexdigit(uint32_t val)
+{
+    return "0123456789abcdef"[val&0xF];
+}
+
+static char* appendhexnum(uint32_t val, char* out)
+{
+    for( int32_t i=28; i>=0; i-=4 ) {
+        *out++ = makehexdigit( val>>i );
+    }
+    *out = 0;
+    return out;
+}
+
+static inline char makeupperhexdigit(uint32_t val)
+{
+    return "0123456789ABCDEF"[val&0xF];
+}
+
+static char* appendupperhexnum(uint32_t val, char* out)
+{
+    for( int32_t i=28; i>=0; i-=4 ) {
+        *out++ = makeupperhexdigit( val>>i );
+    }
+    *out = 0;
+    return out;
+}
+
+static char* appendcharornum(char c, char* out, bool skipzero = true)
+{
+    if (skipzero && c == 0) return out;
+
+    if (isasciitype(c)) {
+        *out++ = c;
+        return out;
+    }
+
+    *out++ = '\\';
+    *out++ = 'x';
+    *out++ = makehexdigit(c>>4);
+    *out++ = makehexdigit(c);
+    return out;
+}
+
+static char* typetostring(uint32_t type, char* out,
+                          bool fullContext = true,
+                          bool strict = false)
+{
+    char* pos = out;
+    char c[4];
+    c[0] = (char)((type>>24)&0xFF);
+    c[1] = (char)((type>>16)&0xFF);
+    c[2] = (char)((type>>8)&0xFF);
+    c[3] = (char)(type&0xFF);
+    bool valid;
+    if( !strict ) {
+        // now even less strict!
+        // valid = isasciitype(c[3]);
+        valid = true;
+        int32_t i = 0;
+        bool zero = true;
+        while (valid && i<3) {
+            if (c[i] == 0) {
+                if (!zero) valid = false;
+            } else {
+                zero = false;
+                //if (!isasciitype(c[i])) valid = false;
+            }
+            i++;
+        }
+        // if all zeros, not a valid type code.
+        if (zero) valid = false;
+    } else {
+        valid = isident(c[3]) ? true : false;
+        int32_t i = 0;
+        bool zero = true;
+        while (valid && i<3) {
+            if (c[i] == 0) {
+                if (!zero) valid = false;
+            } else {
+                zero = false;
+                if (!isident(c[i])) valid = false;
+            }
+            i++;
+        }
+    }
+    if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
+        if( fullContext ) *pos++ = '\'';
+        pos = appendcharornum(c[0], pos);
+        pos = appendcharornum(c[1], pos);
+        pos = appendcharornum(c[2], pos);
+        pos = appendcharornum(c[3], pos);
+        if( fullContext ) *pos++ = '\'';
+        *pos = 0;
+        return pos;
+    }
+    
+    if( fullContext ) {
+        *pos++ = '0';
+        *pos++ = 'x';
+    }
+    return appendhexnum(type, pos);
+}
+
+void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
+{
+    char buffer[32];
+    char* end = typetostring(typeCode, buffer);
+    *end = 0;
+    func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
+}
+
+void printHexData(int32_t indent, const void *buf, size_t length,
+    size_t bytesPerLine, int32_t singleLineBytesCutoff,
+    size_t alignment, bool cStyle,
+    debugPrintFunc func, void* cookie)
+{
+    if (alignment == 0) {
+        if (bytesPerLine >= 16) alignment = 4;
+        else if (bytesPerLine >= 8) alignment = 2;
+        else alignment = 1;
+    }
+    if (func == NULL) func = defaultPrintFunc;
+
+    size_t offset;
+    
+    unsigned char *pos = (unsigned char *)buf;
+    
+    if (pos == NULL) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        func(cookie, "(NULL)");
+        return;
+    }
+    
+    if (length == 0) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        func(cookie, "(empty)");
+        return;
+    }
+    
+    if ((int32_t)length < 0) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        char buf[64];
+        sprintf(buf, "(bad length: %d)", length);
+        func(cookie, buf);
+        return;
+    }
+    
+    char buffer[256];
+    static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
+    
+    if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
+    
+    const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
+    bool newLine = false;
+    if (cStyle) {
+        indent++;
+        func(cookie, "{\n");
+        newLine = true;
+    } else if (!oneLine) {
+        func(cookie, "\n");
+        newLine = true;
+    }
+    
+    for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
+        long remain = length;
+
+        char* c = buffer;
+        if (!oneLine && !cStyle) {
+            sprintf(c, "0x%08x: ", (int)offset);
+            c += 12;
+        }
+
+        size_t index;
+        size_t word;
+        
+        for (word = 0; word < bytesPerLine; ) {
+
+#ifdef HAVE_LITTLE_ENDIAN
+            const size_t startIndex = word+(alignment-(alignment?1:0));
+            const ssize_t dir = -1;
+#else
+            const size_t startIndex = word;
+            const ssize_t dir = 1;
+#endif
+
+            for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
+            
+                if (!cStyle) {
+                    if (index == 0 && word > 0 && alignment > 0) {
+                        *c++ = ' ';
+                    }
+                
+                    if (remain-- > 0) {
+                        const unsigned char val = *(pos+startIndex+(index*dir));
+                        *c++ = makehexdigit(val>>4);
+                        *c++ = makehexdigit(val);
+                    } else if (!oneLine) {
+                        *c++ = ' ';
+                        *c++ = ' ';
+                    }
+                } else {
+                    if (remain > 0) {
+                        if (index == 0 && word > 0) {
+                            *c++ = ',';
+                            *c++ = ' ';
+                        }
+                        if (index == 0) {
+                            *c++ = '0';
+                            *c++ = 'x';
+                        }
+                        const unsigned char val = *(pos+startIndex+(index*dir));
+                        *c++ = makehexdigit(val>>4);
+                        *c++ = makehexdigit(val);
+                        remain--;
+                    }
+                }
+            }
+            
+            word += index;
+        }
+
+        if (!cStyle) {
+            remain = length;
+            *c++ = ' ';
+            *c++ = '\'';
+            for (index = 0; index < bytesPerLine; index++) {
+
+                if (remain-- > 0) {
+                    const unsigned char val = pos[index];
+                    *c++ = (val >= ' ' && val < 127) ? val : '.';
+                } else if (!oneLine) {
+                    *c++ = ' ';
+                }
+            }
+            
+            *c++ = '\'';
+            if (length > bytesPerLine) *c++ = '\n';
+        } else {
+            if (remain > 0) *c++ = ',';
+            *c++ = '\n';
+        }
+
+        if (newLine && indent) func(cookie, stringForIndent(indent));
+        *c = 0;
+        func(cookie, buffer);
+        newLine = true;
+        
+        if (length <= bytesPerLine) break;
+        length -= bytesPerLine;
+    }
+
+    if (cStyle) {
+        if (indent > 0) func(cookie, stringForIndent(indent-1));
+        func(cookie, "};");
+    }
+}
+
+}; // namespace android
+