Merge "Add OBB flags to support overlays" into gingerbread
This commit is contained in:
@@ -25,6 +25,9 @@ import android.os.Parcelable;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class ObbInfo implements Parcelable {
|
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.
|
* The name of the package to which the OBB file belongs.
|
||||||
*/
|
*/
|
||||||
@@ -35,13 +38,26 @@ public class ObbInfo implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public int version;
|
public int version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The flags relating to the OBB.
|
||||||
|
*/
|
||||||
|
public int flags;
|
||||||
|
|
||||||
public ObbInfo() {
|
public ObbInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ObbInfo{"
|
StringBuilder sb = new StringBuilder();
|
||||||
+ Integer.toHexString(System.identityHashCode(this))
|
sb.append("ObbInfo{");
|
||||||
+ " packageName=" + packageName + ",version=" + version + "}";
|
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() {
|
public int describeContents() {
|
||||||
@@ -51,6 +67,7 @@ public class ObbInfo implements Parcelable {
|
|||||||
public void writeToParcel(Parcel dest, int parcelableFlags) {
|
public void writeToParcel(Parcel dest, int parcelableFlags) {
|
||||||
dest.writeString(packageName);
|
dest.writeString(packageName);
|
||||||
dest.writeInt(version);
|
dest.writeInt(version);
|
||||||
|
dest.writeInt(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Parcelable.Creator<ObbInfo> CREATOR
|
public static final Parcelable.Creator<ObbInfo> CREATOR
|
||||||
@@ -67,5 +84,6 @@ public class ObbInfo implements Parcelable {
|
|||||||
private ObbInfo(Parcel source) {
|
private ObbInfo(Parcel source) {
|
||||||
packageName = source.readString();
|
packageName = source.readString();
|
||||||
version = source.readInt();
|
version = source.readInt();
|
||||||
|
flags = source.readInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -304,6 +304,8 @@ public class StorageManager
|
|||||||
* file matches a package ID that is owned by the calling program's UID.
|
* 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
|
* That is, shared UID applications can obtain access to any other
|
||||||
* application's OBB that shares its UID.
|
* 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 filename the path to the OBB file
|
||||||
* @param key decryption key
|
* @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.
|
* 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
|
* That is, shared UID applications can obtain access to any other
|
||||||
* application's OBB that shares its UID.
|
* 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 filename path to the OBB file
|
||||||
* @param force whether to kill any programs using this in order to unmount
|
* @param force whether to kill any programs using this in order to unmount
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ static struct {
|
|||||||
|
|
||||||
jfieldID packageName;
|
jfieldID packageName;
|
||||||
jfieldID version;
|
jfieldID version;
|
||||||
|
jfieldID flags;
|
||||||
} gObbInfoClassInfo;
|
} gObbInfoClassInfo;
|
||||||
|
|
||||||
static jboolean android_content_res_ObbScanner_getObbInfo(JNIEnv* env, jobject clazz, jstring file,
|
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;");
|
"packageName", "Ljava/lang/String;");
|
||||||
GET_FIELD_ID(gObbInfoClassInfo.version, gObbInfoClassInfo.clazz,
|
GET_FIELD_ID(gObbInfoClassInfo.version, gObbInfoClassInfo.clazz,
|
||||||
"version", "I");
|
"version", "I");
|
||||||
|
GET_FIELD_ID(gObbInfoClassInfo.flags, gObbInfoClassInfo.clazz,
|
||||||
|
"flags", "I");
|
||||||
|
|
||||||
return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
|
return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
|
||||||
NELEM(gMethods));
|
NELEM(gMethods));
|
||||||
|
|||||||
@@ -18,12 +18,16 @@
|
|||||||
#define OBBFILE_H_
|
#define OBBFILE_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
#include <utils/RefBase.h>
|
#include <utils/RefBase.h>
|
||||||
#include <utils/String8.h>
|
#include <utils/String8.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
|
// OBB flags (bit 0)
|
||||||
|
#define OBB_OVERLAY (1 << 0)
|
||||||
|
|
||||||
class ObbFile : public RefBase {
|
class ObbFile : public RefBase {
|
||||||
protected:
|
protected:
|
||||||
virtual ~ObbFile();
|
virtual ~ObbFile();
|
||||||
@@ -46,18 +50,38 @@ public:
|
|||||||
return mPackageName;
|
return mPackageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getVersion() const {
|
|
||||||
return mVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPackageName(String8 packageName) {
|
void setPackageName(String8 packageName) {
|
||||||
mPackageName = packageName;
|
mPackageName = packageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t getVersion() const {
|
||||||
|
return mVersion;
|
||||||
|
}
|
||||||
|
|
||||||
void setVersion(int32_t version) {
|
void setVersion(int32_t version) {
|
||||||
mVersion = 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) {
|
static inline uint32_t get4LE(const unsigned char* buf) {
|
||||||
return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||||
}
|
}
|
||||||
@@ -76,6 +100,9 @@ private:
|
|||||||
/* Package version this ObbFile is associated with */
|
/* Package version this ObbFile is associated with */
|
||||||
int32_t mVersion;
|
int32_t mVersion;
|
||||||
|
|
||||||
|
/* Flags for this OBB type. */
|
||||||
|
int32_t mFlags;
|
||||||
|
|
||||||
const char* mFileName;
|
const char* mFileName;
|
||||||
|
|
||||||
size_t mFileSize;
|
size_t mFileSize;
|
||||||
|
|||||||
@@ -29,12 +29,13 @@
|
|||||||
|
|
||||||
#define kFooterTagSize 8 /* last two 32-bit integers */
|
#define kFooterTagSize 8 /* last two 32-bit integers */
|
||||||
|
|
||||||
#define kFooterMinSize 21 /* 32-bit signature version
|
#define kFooterMinSize 25 /* 32-bit signature version (4 bytes)
|
||||||
* 32-bit package version
|
* 32-bit package version (4 bytes)
|
||||||
* 32-bit package name size
|
* 32-bit flags (4 bytes)
|
||||||
* 1-character package name
|
* 32-bit package name size (4-bytes)
|
||||||
* 32-bit footer size
|
* >=1-character package name (1 byte)
|
||||||
* 32-bit footer marker
|
* 32-bit footer size (4 bytes)
|
||||||
|
* 32-bit footer marker (4 bytes)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define kMaxBufSize 32768 /* Maximum file read buffer */
|
#define kMaxBufSize 32768 /* Maximum file read buffer */
|
||||||
@@ -45,8 +46,9 @@
|
|||||||
|
|
||||||
/* offsets in version 1 of the header */
|
/* offsets in version 1 of the header */
|
||||||
#define kPackageVersionOffset 4
|
#define kPackageVersionOffset 4
|
||||||
#define kPackageNameLenOffset 8
|
#define kFlagsOffset 8
|
||||||
#define kPackageNameOffset 12
|
#define kPackageNameLenOffset 12
|
||||||
|
#define kPackageNameOffset 16
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
|
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
|
||||||
@@ -78,7 +80,10 @@ typedef off64_t my_off64_t;
|
|||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
ObbFile::ObbFile() :
|
ObbFile::ObbFile() :
|
||||||
mVersion(-1) {
|
mPackageName(""),
|
||||||
|
mVersion(-1),
|
||||||
|
mFlags(0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ObbFile::~ObbFile() {
|
ObbFile::~ObbFile() {
|
||||||
@@ -199,6 +204,7 @@ bool ObbFile::parseObbFile(int fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
|
mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
|
||||||
|
mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
|
||||||
|
|
||||||
uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
|
uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
|
||||||
if (packageNameLen <= 0
|
if (packageNameLen <= 0
|
||||||
@@ -268,6 +274,12 @@ bool ObbFile::writeTo(int fd)
|
|||||||
return false;
|
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();
|
size_t packageNameLen = mPackageName.size();
|
||||||
put4LE(intBuf, packageNameLen);
|
put4LE(intBuf, packageNameLen);
|
||||||
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
||||||
@@ -280,7 +292,7 @@ bool ObbFile::writeTo(int fd)
|
|||||||
return false;
|
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)) {
|
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
||||||
LOGW("couldn't write footer size: %s", strerror(errno));
|
LOGW("couldn't write footer size: %s", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ static const char* gProgVersion = "1.0";
|
|||||||
static int wantUsage = 0;
|
static int wantUsage = 0;
|
||||||
static int wantVersion = 0;
|
static int wantVersion = 0;
|
||||||
|
|
||||||
#define ADD_OPTS "n:v:f:c:"
|
#define ADD_OPTS "n:v:o"
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
{"help", no_argument, &wantUsage, 1},
|
{"help", no_argument, &wantUsage, 1},
|
||||||
{"version", no_argument, &wantVersion, 1},
|
{"version", no_argument, &wantVersion, 1},
|
||||||
@@ -37,8 +37,7 @@ static const struct option longopts[] = {
|
|||||||
/* Args for "add" */
|
/* Args for "add" */
|
||||||
{"name", required_argument, NULL, 'n'},
|
{"name", required_argument, NULL, 'n'},
|
||||||
{"version", required_argument, NULL, 'v'},
|
{"version", required_argument, NULL, 'v'},
|
||||||
{"filesystem", required_argument, NULL, 'f'},
|
{"overlay", optional_argument, NULL, 'o'},
|
||||||
{"crypto", required_argument, NULL, 'c'},
|
|
||||||
|
|
||||||
{NULL, 0, NULL, '\0'}
|
{NULL, 0, NULL, '\0'}
|
||||||
};
|
};
|
||||||
@@ -46,8 +45,7 @@ static const struct option longopts[] = {
|
|||||||
struct package_info_t {
|
struct package_info_t {
|
||||||
char* packageName;
|
char* packageName;
|
||||||
int packageVersion;
|
int packageVersion;
|
||||||
char* filesystem;
|
bool overlay;
|
||||||
char* crypto;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -77,6 +75,7 @@ void doAdd(const char* filename, struct package_info_t* info) {
|
|||||||
|
|
||||||
obb->setPackageName(String8(info->packageName));
|
obb->setPackageName(String8(info->packageName));
|
||||||
obb->setVersion(info->packageVersion);
|
obb->setVersion(info->packageVersion);
|
||||||
|
obb->setOverlay(info->overlay);
|
||||||
|
|
||||||
if (!obb->writeTo(filename)) {
|
if (!obb->writeTo(filename)) {
|
||||||
fprintf(stderr, "ERROR: %s: couldn't write OBB signature: %s\n",
|
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("OBB info for '%s':\n", filename);
|
||||||
printf("Package name: %s\n", obb->getPackageName().string());
|
printf("Package name: %s\n", obb->getPackageName().string());
|
||||||
printf(" Version: %d\n", obb->getVersion());
|
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':
|
case 'n':
|
||||||
package_info.packageName = optarg;
|
package_info.packageName = optarg;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v': {
|
||||||
char *end;
|
char *end;
|
||||||
package_info.packageVersion = strtol(optarg, &end, 10);
|
package_info.packageVersion = strtol(optarg, &end, 10);
|
||||||
if (*optarg == '\0' || *end != '\0') {
|
if (*optarg == '\0' || *end != '\0') {
|
||||||
@@ -152,11 +153,9 @@ int main(int argc, char* const argv[])
|
|||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'f':
|
}
|
||||||
package_info.filesystem = optarg;
|
case 'o':
|
||||||
break;
|
package_info.overlay = true;
|
||||||
case 'c':
|
|
||||||
package_info.crypto = optarg;
|
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
wantUsage = 1;
|
wantUsage = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user