am 5502f04c: Merge change 4709 into donut

Merge commit '5502f04c1dcf2b1918858bacb99fb0480a711707'

* commit '5502f04c1dcf2b1918858bacb99fb0480a711707':
  backup stuff
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 5caa015..3ef8666 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -80,28 +80,35 @@
             byte[] buf = new byte[bufSize];
             while (changeSet.readNextHeader()) {
                 String key = changeSet.getKey();
+                String base64Key = new String(Base64.encode(key.getBytes()));
+                File entityFile = new File(packageDir, base64Key);
+
                 int dataSize = changeSet.getDataSize();
 
-                String base64Key = new String(Base64.encode(key.getBytes()));
                 if (DEBUG) Log.v(TAG, "Got change set key=" + key + " size=" + dataSize
                         + " key64=" + base64Key);
-                if (dataSize > bufSize) {
-                    bufSize = dataSize;
-                    buf = new byte[bufSize];
-                }
-                changeSet.readEntityData(buf, 0, dataSize);
-                if (DEBUG) Log.v(TAG, "  + data size " + dataSize);
 
-                File entityFile = new File(packageDir, base64Key);
-                FileOutputStream entity = new FileOutputStream(entityFile);
-                try {
-                    entity.write(buf, 0, dataSize);
-                } catch (IOException e) {
-                    Log.e(TAG, "Unable to update key file "
-                            + entityFile.getAbsolutePath());
-                    err = -1;
-                } finally {
-                    entity.close();
+                if (dataSize >= 0) {
+                    FileOutputStream entity = new FileOutputStream(entityFile);
+
+                    if (dataSize > bufSize) {
+                        bufSize = dataSize;
+                        buf = new byte[bufSize];
+                    }
+                    changeSet.readEntityData(buf, 0, dataSize);
+                    if (DEBUG) Log.v(TAG, "  data size " + dataSize);
+
+                    try {
+                        entity.write(buf, 0, dataSize);
+                    } catch (IOException e) {
+                        Log.e(TAG, "Unable to update key file "
+                                + entityFile.getAbsolutePath());
+                        err = -1;
+                    } finally {
+                        entity.close();
+                    }
+                } else {
+                    entityFile.delete();
                 }
             }
         } catch (IOException e) {
@@ -172,7 +179,8 @@
                     int size = (int) f.length();
                     byte[] buf = new byte[size];
                     in.read(buf);
-                    out.writeEntityHeader(f.getName(), size);
+                    String key = new String(Base64.decode(f.getName()));
+                    out.writeEntityHeader(key, size);
                     out.writeEntityData(buf, size);
                 }
             } catch (Exception e) {
diff --git a/include/utils/BackupHelpers.h b/include/utils/BackupHelpers.h
index fc701fd..c78b99a 100644
--- a/include/utils/BackupHelpers.h
+++ b/include/utils/BackupHelpers.h
@@ -116,6 +116,7 @@
         int type;
         entity_header_v1 entity;
     } m_header;
+    String8 m_key;
 };
 
 int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
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 99687bc..d65a457 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -414,14 +414,15 @@
     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, mode);
-    if (fd != -1) {
+    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;
     }
     
@@ -429,6 +430,7 @@
         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);
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 6ee8260..51bee25 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -164,6 +164,7 @@
         // Set up our transport options and initialize the default transport
         // TODO: Have transports register themselves somehow?
         // TODO: Don't create transports that we don't need to?
+        //mTransportId = BackupManager.TRANSPORT_LOCAL;
         mTransportId = BackupManager.TRANSPORT_GOOGLE;
         mLocalTransport = new LocalTransport(context);  // This is actually pretty cheap
         mGoogleTransport = null;