Merge change 4696 into donut

* changes:
  Fix targetSdkVersion, make resize mode a flag, delayed dexopt, easy ApplicationInfo.
diff --git a/include/utils/BackupHelpers.h b/include/utils/BackupHelpers.h
index fa7f8d5..c78b99a 100644
--- a/include/utils/BackupHelpers.h
+++ b/include/utils/BackupHelpers.h
@@ -19,6 +19,7 @@
 
 #include <utils/Errors.h>
 #include <utils/String8.h>
+#include <utils/KeyedVector.h>
 
 namespace android {
 
@@ -32,6 +33,27 @@
     int dataSize; // size of the data, not including the padding, -1 means delete
 } entity_header_v1;
 
+struct SnapshotHeader {
+    int magic0;
+    int fileCount;
+    int magic1;
+    int totalSize;
+};
+
+struct FileState {
+    int modTime_sec;
+    int modTime_nsec;
+    int size;
+    int crc32;
+    int nameLen;
+};
+
+struct FileRec {
+    String8 file;
+    bool deleted;
+    FileState s;
+};
+
 
 /**
  * Writes the data.
@@ -94,11 +116,25 @@
         int type;
         entity_header_v1 entity;
     } m_header;
+    String8 m_key;
 };
 
 int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
         char const* const* files, char const* const *keys, int fileCount);
 
+class RestoreHelperBase
+{
+public:
+    RestoreHelperBase();
+    ~RestoreHelperBase();
+
+    status_t WriteFile(const String8& filename, BackupDataReader* in);
+    status_t WriteSnapshot(int fd);
+
+private:
+    void* m_buf;
+    KeyedVector<String8,FileRec> m_files;
+};
 
 #define TEST_BACKUP_HELPERS 1
 
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index f14d7e9..971189f 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -193,6 +193,14 @@
         LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
         strcpy(property, "160");
     }
+
+    /* Override the property value if qemu.sf.lcd_density is defined. */
+    {
+        char  qemu_property[PROPERTY_VALUE_MAX];
+        if (property_get("qemu.sf.lcd_density", qemu_property, NULL) > 0) {
+            strlcpy(property, qemu_property, sizeof property);
+        }
+    }
     mDensity = atoi(property) * (1.0f/160.0f);
 
 
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
index 34b37ed..6a7f056 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/utils/BackupData.cpp
@@ -205,12 +205,17 @@
     amt = read(m_fd, &m_header, sizeof(m_header));
     *done = m_done = (amt == 0);
     CHECK_SIZE(amt, sizeof(m_header));
+    m_pos += sizeof(m_header);
+    if (type) {
+        *type = m_header.type;
+    }
 
     // validate and fix up the fields.
     m_header.type = fromlel(m_header.type);
     switch (m_header.type)
     {
         case BACKUP_HEADER_ENTITY_V1:
+        {
             m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
             if (m_header.entity.keyLen <= 0) {
                 LOGD("Entity header at %d has keyLen<=0: 0x%08x\n", (int)m_pos,
@@ -219,15 +224,27 @@
             }
             m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
             m_entityCount++;
+
+            // read the rest of the header (filename)
+            size_t size = m_header.entity.keyLen;
+            char* buf = m_key.lockBuffer(size);
+            if (buf == NULL) {
+                m_status = ENOMEM;
+                return m_status;
+            }
+            int amt = read(m_fd, buf, size+1);
+            CHECK_SIZE(amt, (int)size+1);
+            m_key.unlockBuffer(size);
+            m_pos += size+1;
+            SKIP_PADDING();
+            m_dataEndPos = m_pos + m_header.entity.dataSize;
+
             break;
+        }
         default:
             LOGD("Chunk header at %d has invalid type: 0x%08x", (int)m_pos, (int)m_header.type);
             m_status = EINVAL;
     }
-    m_pos += sizeof(m_header);
-    if (type) {
-        *type = m_header.type;
-    }
     
     return m_status;
 }
@@ -247,20 +264,8 @@
     if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
         return EINVAL;
     }
-    size_t size = m_header.entity.keyLen;
-    char* buf = key->lockBuffer(size);
-    if (key == NULL) {
-        key->unlockBuffer();
-        m_status = ENOMEM;
-        return m_status;
-    }
-    int amt = read(m_fd, buf, size+1);
-    CHECK_SIZE(amt, (int)size+1);
-    key->unlockBuffer(size);
-    m_pos += size+1;
+    *key = m_key;
     *dataSize = m_header.entity.dataSize;
-    SKIP_PADDING();
-    m_dataEndPos = m_pos + *dataSize;
     return NO_ERROR;
 }
 
@@ -285,20 +290,24 @@
 BackupDataReader::ReadEntityData(void* data, size_t size)
 {
     if (m_status != NO_ERROR) {
-        return m_status;
+        return -1;
     }
     int remaining = m_dataEndPos - m_pos;
     //LOGD("ReadEntityData size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n",
     //        size, m_pos, m_dataEndPos, remaining);
-    if (size > remaining) {
-        size = remaining;
-    }
     if (remaining <= 0) {
         return 0;
     }
+    if (size > remaining) {
+        size = remaining;
+    }
+    //LOGD("   reading %d bytes", size);
     int amt = read(m_fd, data, size);
-    CHECK_SIZE(amt, (int)size);
-    m_pos += size;
+    if (amt < 0) {
+        m_status = errno;
+        return -1;
+    }
+    m_pos += amt;
     return amt;
 }
 
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index c1d5404..d65a457 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -47,27 +47,6 @@
 #define LOGP(x...) LOGD(x)
 #endif
 
-struct SnapshotHeader {
-    int magic0;
-    int fileCount;
-    int magic1;
-    int totalSize;
-};
-
-struct FileState {
-    int modTime_sec;
-    int modTime_nsec;
-    int size;
-    int crc32;
-    int nameLen;
-};
-
-struct FileRec {
-    char const* file; // this object does not own this string
-    bool deleted;
-    FileState s;
-};
-
 const static int ROUND_UP[4] = { 0, 3, 2, 1 };
 
 static inline int
@@ -310,7 +289,8 @@
     for (int i=0; i<fileCount; i++) {
         String8 key(keys[i]);
         FileRec r;
-        char const* file = r.file = files[i];
+        char const* file = files[i];
+        r.file = file;
         struct stat st;
 
         err = stat(file, &st);
@@ -351,20 +331,20 @@
         }
         else if (cmp > 0) {
             // file added
-            LOGP("file added: %s", g.file);
-            write_update_file(dataStream, q, g.file);
+            LOGP("file added: %s", g.file.string());
+            write_update_file(dataStream, q, g.file.string());
             m++;
         }
         else {
             // both files exist, check them
             const FileState& f = oldSnapshot.valueAt(n);
 
-            int fd = open(g.file, O_RDONLY);
+            int fd = open(g.file.string(), O_RDONLY);
             if (fd < 0) {
                 // We can't open the file.  Don't report it as a delete either.  Let the
                 // server keep the old version.  Maybe they'll be able to deal with it
                 // on restore.
-                LOGP("Unable to open file %s - skipping", g.file);
+                LOGP("Unable to open file %s - skipping", g.file.string());
             } else {
                 g.s.crc32 = compute_crc32(fd);
 
@@ -375,7 +355,7 @@
                         g.s.modTime_sec, g.s.modTime_nsec, g.s.size, g.s.crc32);
                 if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
                         || f.size != g.s.size || f.crc32 != g.s.crc32) {
-                    write_update_file(dataStream, fd, p, g.file);
+                    write_update_file(dataStream, fd, p, g.file.string());
                 }
 
                 close(fd);
@@ -395,7 +375,7 @@
     while (m<fileCount) {
         const String8& q = newSnapshot.keyAt(m);
         FileRec& g = newSnapshot.editValueAt(m);
-        write_update_file(dataStream, q, g.file);
+        write_update_file(dataStream, q, g.file.string());
         m++;
     }
 
@@ -404,6 +384,86 @@
     return 0;
 }
 
+#define RESTORE_BUF_SIZE (8*1024)
+
+RestoreHelperBase::RestoreHelperBase()
+{
+    m_buf = malloc(RESTORE_BUF_SIZE);
+}
+
+RestoreHelperBase::~RestoreHelperBase()
+{
+    free(m_buf);
+}
+
+status_t
+RestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
+{
+    ssize_t err;
+    size_t dataSize;
+    String8 key;
+    int fd;
+    void* buf = m_buf;
+    ssize_t amt;
+    int mode;
+    int crc;
+    struct stat st;
+    FileRec r;
+
+    err = in->ReadEntityHeader(&key, &dataSize);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    // TODO: World readable/writable for now.
+    mode = 0666;
+
+    // Write the file and compute the crc
+    crc = crc32(0L, Z_NULL, 0);
+    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
+    if (fd == -1) {
+        LOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
+        return errno;
+    }
+    
+    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
+        err = write(fd, buf, amt);
+        if (err != amt) {
+            close(fd);
+            LOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
+            return errno;
+        }
+        crc = crc32(crc, (Bytef*)buf, amt);
+    }
+
+    close(fd);
+
+    // Record for the snapshot
+    err = stat(filename.string(), &st);
+    if (err != 0) {
+        LOGW("Error stating file that we just created %s", filename.string());
+        return errno;
+    }
+
+    r.file = filename;
+    r.deleted = false;
+    r.s.modTime_sec = st.st_mtime;
+    r.s.modTime_nsec = 0; // workaround sim breakage
+    //r.s.modTime_nsec = st.st_mtime_nsec;
+    r.s.size = st.st_size;
+    r.s.crc32 = crc;
+
+    m_files.add(key, r);
+
+    return NO_ERROR;
+}
+
+status_t
+RestoreHelperBase::WriteSnapshot(int fd)
+{
+    return write_snapshot_file(fd, m_files);;
+}
+
 #if TEST_BACKUP_HELPERS
 
 #define SCRATCH_DIR "/data/backup_helper_test/"
@@ -560,7 +620,6 @@
     FileState states[4];
     FileRec r;
     r.deleted = false;
-    r.file = NULL;
 
     states[0].modTime_sec = 0xfedcba98;
     states[0].modTime_nsec = 0xdeadbeef;