am 54d41379: Merge "Add OBB flags to support overlays" into gingerbread

Merge commit '54d41379357d1d800d0a7bd7c5dc56111710482a' into gingerbread-plus-aosp

* commit '54d41379357d1d800d0a7bd7c5dc56111710482a':
  Add OBB flags to support overlays
This commit is contained in:
Kenny Root
2010-08-19 09:11:31 -07:00
committed by Android Git Automerger
6 changed files with 91 additions and 28 deletions

View File

@ -25,6 +25,9 @@ import android.os.Parcelable;
* @hide
*/
public class ObbInfo implements Parcelable {
/** Flag noting that this OBB is an overlay patch for a base OBB. */
public static final int OBB_OVERLAY = 1 << 0;
/**
* The name of the package to which the OBB file belongs.
*/
@ -35,13 +38,26 @@ public class ObbInfo implements Parcelable {
*/
public int version;
/**
* The flags relating to the OBB.
*/
public int flags;
public ObbInfo() {
}
public String toString() {
return "ObbInfo{"
+ Integer.toHexString(System.identityHashCode(this))
+ " packageName=" + packageName + ",version=" + version + "}";
StringBuilder sb = new StringBuilder();
sb.append("ObbInfo{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(" packageName=");
sb.append(packageName);
sb.append(",version=");
sb.append(version);
sb.append(",flags=");
sb.append(flags);
sb.append('}');
return sb.toString();
}
public int describeContents() {
@ -51,6 +67,7 @@ public class ObbInfo implements Parcelable {
public void writeToParcel(Parcel dest, int parcelableFlags) {
dest.writeString(packageName);
dest.writeInt(version);
dest.writeInt(flags);
}
public static final Parcelable.Creator<ObbInfo> CREATOR
@ -67,5 +84,6 @@ public class ObbInfo implements Parcelable {
private ObbInfo(Parcel source) {
packageName = source.readString();
version = source.readInt();
flags = source.readInt();
}
}

View File

@ -304,6 +304,8 @@ public class StorageManager
* file matches a package ID that is owned by the calling program's UID.
* That is, shared UID applications can obtain access to any other
* application's OBB that shares its UID.
* <p>
* STOPSHIP document more; discuss lack of guarantees of security
*
* @param filename the path to the OBB file
* @param key decryption key
@ -328,6 +330,8 @@ public class StorageManager
* file matches a package ID that is owned by the calling program's UID.
* That is, shared UID applications can obtain access to any other
* application's OBB that shares its UID.
* <p>
* STOPSHIP document more; discuss lack of guarantees of security
*
* @param filename path to the OBB file
* @param force whether to kill any programs using this in order to unmount

View File

@ -31,6 +31,7 @@ static struct {
jfieldID packageName;
jfieldID version;
jfieldID flags;
} gObbInfoClassInfo;
static jboolean android_content_res_ObbScanner_getObbInfo(JNIEnv* env, jobject clazz, jstring file,
@ -85,6 +86,8 @@ int register_android_content_res_ObbScanner(JNIEnv* env)
"packageName", "Ljava/lang/String;");
GET_FIELD_ID(gObbInfoClassInfo.version, gObbInfoClassInfo.clazz,
"version", "I");
GET_FIELD_ID(gObbInfoClassInfo.flags, gObbInfoClassInfo.clazz,
"flags", "I");
return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
NELEM(gMethods));

View File

@ -18,12 +18,16 @@
#define OBBFILE_H_
#include <stdint.h>
#include <strings.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
namespace android {
// OBB flags (bit 0)
#define OBB_OVERLAY (1 << 0)
class ObbFile : public RefBase {
protected:
virtual ~ObbFile();
@ -46,18 +50,38 @@ public:
return mPackageName;
}
int32_t getVersion() const {
return mVersion;
}
void setPackageName(String8 packageName) {
mPackageName = packageName;
}
int32_t getVersion() const {
return mVersion;
}
void setVersion(int32_t version) {
mVersion = version;
}
int32_t getFlags() const {
return mFlags;
}
void setFlags(int32_t flags) {
mFlags = flags;
}
bool isOverlay() {
return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;
}
void setOverlay(bool overlay) {
if (overlay) {
mFlags |= OBB_OVERLAY;
} else {
mFlags &= ~OBB_OVERLAY;
}
}
static inline uint32_t get4LE(const unsigned char* buf) {
return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
}
@ -76,6 +100,9 @@ private:
/* Package version this ObbFile is associated with */
int32_t mVersion;
/* Flags for this OBB type. */
int32_t mFlags;
const char* mFileName;
size_t mFileSize;

View File

@ -29,12 +29,13 @@
#define kFooterTagSize 8 /* last two 32-bit integers */
#define kFooterMinSize 21 /* 32-bit signature version
* 32-bit package version
* 32-bit package name size
* 1-character package name
* 32-bit footer size
* 32-bit footer marker
#define kFooterMinSize 25 /* 32-bit signature version (4 bytes)
* 32-bit package version (4 bytes)
* 32-bit flags (4 bytes)
* 32-bit package name size (4-bytes)
* >=1-character package name (1 byte)
* 32-bit footer size (4 bytes)
* 32-bit footer marker (4 bytes)
*/
#define kMaxBufSize 32768 /* Maximum file read buffer */
@ -45,8 +46,9 @@
/* offsets in version 1 of the header */
#define kPackageVersionOffset 4
#define kPackageNameLenOffset 8
#define kPackageNameOffset 12
#define kFlagsOffset 8
#define kPackageNameLenOffset 12
#define kPackageNameOffset 16
/*
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
@ -78,7 +80,10 @@ typedef off64_t my_off64_t;
namespace android {
ObbFile::ObbFile() :
mVersion(-1) {
mPackageName(""),
mVersion(-1),
mFlags(0)
{
}
ObbFile::~ObbFile() {
@ -199,6 +204,7 @@ bool ObbFile::parseObbFile(int fd)
}
mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
if (packageNameLen <= 0
@ -268,6 +274,12 @@ bool ObbFile::writeTo(int fd)
return false;
}
put4LE(intBuf, mFlags);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
LOGW("couldn't write package version");
return false;
}
size_t packageNameLen = mPackageName.size();
put4LE(intBuf, packageNameLen);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
@ -280,7 +292,7 @@ bool ObbFile::writeTo(int fd)
return false;
}
put4LE(intBuf, 3*sizeof(uint32_t) + packageNameLen);
put4LE(intBuf, kPackageNameOffset + packageNameLen);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
LOGW("couldn't write footer size: %s", strerror(errno));
return false;

View File

@ -29,7 +29,7 @@ static const char* gProgVersion = "1.0";
static int wantUsage = 0;
static int wantVersion = 0;
#define ADD_OPTS "n:v:f:c:"
#define ADD_OPTS "n:v:o"
static const struct option longopts[] = {
{"help", no_argument, &wantUsage, 1},
{"version", no_argument, &wantVersion, 1},
@ -37,8 +37,7 @@ static const struct option longopts[] = {
/* Args for "add" */
{"name", required_argument, NULL, 'n'},
{"version", required_argument, NULL, 'v'},
{"filesystem", required_argument, NULL, 'f'},
{"crypto", required_argument, NULL, 'c'},
{"overlay", optional_argument, NULL, 'o'},
{NULL, 0, NULL, '\0'}
};
@ -46,8 +45,7 @@ static const struct option longopts[] = {
struct package_info_t {
char* packageName;
int packageVersion;
char* filesystem;
char* crypto;
bool overlay;
};
/*
@ -77,6 +75,7 @@ void doAdd(const char* filename, struct package_info_t* info) {
obb->setPackageName(String8(info->packageName));
obb->setVersion(info->packageVersion);
obb->setOverlay(info->overlay);
if (!obb->writeTo(filename)) {
fprintf(stderr, "ERROR: %s: couldn't write OBB signature: %s\n",
@ -112,6 +111,8 @@ void doInfo(const char* filename) {
printf("OBB info for '%s':\n", filename);
printf("Package name: %s\n", obb->getPackageName().string());
printf(" Version: %d\n", obb->getVersion());
printf(" Flags: 0x%08x\n", obb->getFlags());
printf(" Overlay: %s\n", obb->isOverlay() ? "true" : "false");
}
/*
@ -143,7 +144,7 @@ int main(int argc, char* const argv[])
case 'n':
package_info.packageName = optarg;
break;
case 'v':
case 'v': {
char *end;
package_info.packageVersion = strtol(optarg, &end, 10);
if (*optarg == '\0' || *end != '\0') {
@ -152,11 +153,9 @@ int main(int argc, char* const argv[])
goto bail;
}
break;
case 'f':
package_info.filesystem = optarg;
break;
case 'c':
package_info.crypto = optarg;
}
case 'o':
package_info.overlay = true;
break;
case '?':
wantUsage = 1;