Add API to call to vold for mounting OBBs
* Unhide StorageService class; hide all the USB-related items * Add application-visible API to StorageManager for OBB files * Add class for parceling OBB info across binders (ObbInfo) * Add a JNI glue class to libutils/ObbFile (ObbScanner) * Add API to MountService to deal with calling into vold and checking permissions Change-Id: I33ecf9606b8ff535f3a2ada83931da6bbef41cfd
This commit is contained in:
@ -38302,6 +38302,17 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="STORAGE_SERVICE"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value=""storage""
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="TELEPHONY_SERVICE"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
@ -125618,6 +125629,74 @@
|
||||
</method>
|
||||
</class>
|
||||
</package>
|
||||
<package name="android.os.storage"
|
||||
>
|
||||
<class name="StorageManager"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<method name="getMountedObbPath"
|
||||
return="java.lang.String"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="filename" type="java.lang.String">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="isObbMounted"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="filename" type="java.lang.String">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="mountObb"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="filename" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="key" type="java.lang.String">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="unmountObb"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="filename" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="force" type="boolean">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
</package>
|
||||
<package name="android.preference"
|
||||
>
|
||||
<class name="CheckBoxPreference"
|
||||
|
@ -1372,9 +1372,8 @@ public abstract class Context {
|
||||
public static final String SENSOR_SERVICE = "sensor";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Use with {@link #getSystemService} to retrieve a {@link
|
||||
* android.os.storage.StorageManager} for accesssing system storage
|
||||
* android.os.storage.StorageManager} for accessing system storage
|
||||
* functions.
|
||||
*
|
||||
* @see #getSystemService
|
||||
|
19
core/java/android/content/res/ObbInfo.aidl
Executable file
19
core/java/android/content/res/ObbInfo.aidl
Executable file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
parcelable ObbInfo;
|
71
core/java/android/content/res/ObbInfo.java
Normal file
71
core/java/android/content/res/ObbInfo.java
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* Basic information about a Opaque Binary Blob (OBB) that reflects
|
||||
* the info from the footer on the OBB file.
|
||||
* @hide
|
||||
*/
|
||||
public class ObbInfo implements Parcelable {
|
||||
/**
|
||||
* The name of the package to which the OBB file belongs.
|
||||
*/
|
||||
public String packageName;
|
||||
|
||||
/**
|
||||
* The version of the package to which the OBB file belongs.
|
||||
*/
|
||||
public int version;
|
||||
|
||||
public ObbInfo() {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ObbInfo{"
|
||||
+ Integer.toHexString(System.identityHashCode(this))
|
||||
+ " packageName=" + packageName + ",version=" + version + "}";
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel dest, int parcelableFlags) {
|
||||
dest.writeString(packageName);
|
||||
dest.writeInt(version);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<ObbInfo> CREATOR
|
||||
= new Parcelable.Creator<ObbInfo>() {
|
||||
public ObbInfo createFromParcel(Parcel source) {
|
||||
return new ObbInfo(source);
|
||||
}
|
||||
|
||||
public ObbInfo[] newArray(int size) {
|
||||
return new ObbInfo[size];
|
||||
}
|
||||
};
|
||||
|
||||
private ObbInfo(Parcel source) {
|
||||
packageName = source.readString();
|
||||
version = source.readInt();
|
||||
}
|
||||
}
|
40
core/java/android/content/res/ObbScanner.java
Normal file
40
core/java/android/content/res/ObbScanner.java
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
/**
|
||||
* Class to scan Opaque Binary Blob (OBB) files.
|
||||
* @hide
|
||||
*/
|
||||
public class ObbScanner {
|
||||
// Don't allow others to instantiate this class
|
||||
private ObbScanner() {}
|
||||
|
||||
public static ObbInfo getObbInfo(String filePath) {
|
||||
if (filePath == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ObbInfo obbInfo = new ObbInfo();
|
||||
if (!getObbInfo_native(filePath, obbInfo)) {
|
||||
throw new IllegalArgumentException("Could not read OBB file: " + filePath);
|
||||
}
|
||||
return obbInfo;
|
||||
}
|
||||
|
||||
private native static boolean getObbInfo_native(String filePath, ObbInfo obbInfo);
|
||||
}
|
@ -152,4 +152,26 @@ interface IMountService
|
||||
* processing the media status update request.
|
||||
*/
|
||||
void finishMediaUpdate();
|
||||
|
||||
/**
|
||||
* Mounts an Opaque Binary Blob (OBB) with the specified decryption key and only
|
||||
* allows the calling process's UID access to the contents.
|
||||
*/
|
||||
int mountObb(String filename, String key);
|
||||
|
||||
/**
|
||||
* Unmounts an Opaque Binary Blob (OBB). When the force flag is specified, any
|
||||
* program using it will be forcibly killed to unmount the image.
|
||||
*/
|
||||
int unmountObb(String filename, boolean force);
|
||||
|
||||
/**
|
||||
* Checks whether the specified Opaque Binary Blob (OBB) is mounted somewhere.
|
||||
*/
|
||||
boolean isObbMounted(String filename);
|
||||
|
||||
/**
|
||||
* Gets the path to the mounted Opaque Binary Blob (OBB).
|
||||
*/
|
||||
String getMountedObbPath(String filename);
|
||||
}
|
||||
|
@ -44,9 +44,6 @@ import java.util.List;
|
||||
* Get an instance of this class by calling
|
||||
* {@link android.content.Context#getSystemService(java.lang.String)} with an argument
|
||||
* of {@link android.content.Context#STORAGE_SERVICE}.
|
||||
*
|
||||
* @hide
|
||||
*
|
||||
*/
|
||||
|
||||
public class StorageManager
|
||||
@ -209,6 +206,7 @@ public class StorageManager
|
||||
*
|
||||
* @param listener A {@link android.os.storage.StorageEventListener StorageEventListener} object.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void registerListener(StorageEventListener listener) {
|
||||
if (listener == null) {
|
||||
@ -225,6 +223,7 @@ public class StorageManager
|
||||
*
|
||||
* @param listener A {@link android.os.storage.StorageEventListener StorageEventListener} object.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void unregisterListener(StorageEventListener listener) {
|
||||
if (listener == null) {
|
||||
@ -245,6 +244,8 @@ public class StorageManager
|
||||
|
||||
/**
|
||||
* Enables USB Mass Storage (UMS) on the device.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void enableUsbMassStorage() {
|
||||
try {
|
||||
@ -256,6 +257,8 @@ public class StorageManager
|
||||
|
||||
/**
|
||||
* Disables USB Mass Storage (UMS) on the device.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void disableUsbMassStorage() {
|
||||
try {
|
||||
@ -268,6 +271,8 @@ public class StorageManager
|
||||
/**
|
||||
* Query if a USB Mass Storage (UMS) host is connected.
|
||||
* @return true if UMS host is connected.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean isUsbMassStorageConnected() {
|
||||
try {
|
||||
@ -281,6 +286,8 @@ public class StorageManager
|
||||
/**
|
||||
* Query if a USB Mass Storage (UMS) is enabled on the device.
|
||||
* @return true if UMS host is enabled.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean isUsbMassStorageEnabled() {
|
||||
try {
|
||||
@ -290,4 +297,55 @@ public class StorageManager
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mount an OBB file.
|
||||
*/
|
||||
public boolean mountObb(String filename, String key) {
|
||||
try {
|
||||
return mMountService.mountObb(filename, key)
|
||||
== StorageResultCode.OperationSucceeded;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to mount OBB", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mount an OBB file.
|
||||
*/
|
||||
public boolean unmountObb(String filename, boolean force) {
|
||||
try {
|
||||
return mMountService.unmountObb(filename, force)
|
||||
== StorageResultCode.OperationSucceeded;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to mount OBB", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isObbMounted(String filename) {
|
||||
try {
|
||||
return mMountService.isObbMounted(filename);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to check if OBB is mounted", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the mounted path of an OBB file.
|
||||
*/
|
||||
public String getMountedObbPath(String filename) {
|
||||
try {
|
||||
return mMountService.getMountedObbPath(filename);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to find mounted path for OBB", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package com.android.internal.app;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.content.pm.PackageInfoLite;
|
||||
import android.content.res.ObbInfo;
|
||||
|
||||
interface IMediaContainerService {
|
||||
String copyResourceToContainer(in Uri packageURI,
|
||||
@ -28,4 +29,5 @@ interface IMediaContainerService {
|
||||
in ParcelFileDescriptor outStream);
|
||||
PackageInfoLite getMinimalPackageInfo(in Uri fileUri, int flags);
|
||||
boolean checkFreeStorage(boolean external, in Uri fileUri);
|
||||
}
|
||||
ObbInfo getObbInfo(in Uri fileUri);
|
||||
}
|
||||
|
@ -134,7 +134,8 @@ LOCAL_SRC_FILES:= \
|
||||
android_backup_BackupDataInput.cpp \
|
||||
android_backup_BackupDataOutput.cpp \
|
||||
android_backup_FileBackupHelperBase.cpp \
|
||||
android_backup_BackupHelperDispatcher.cpp
|
||||
android_backup_BackupHelperDispatcher.cpp \
|
||||
android_content_res_ObbScanner.cpp
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(JNI_H_INCLUDE) \
|
||||
|
@ -166,6 +166,7 @@ extern int register_android_view_InputChannel(JNIEnv* env);
|
||||
extern int register_android_view_InputQueue(JNIEnv* env);
|
||||
extern int register_android_view_KeyEvent(JNIEnv* env);
|
||||
extern int register_android_view_MotionEvent(JNIEnv* env);
|
||||
extern int register_android_content_res_ObbScanner(JNIEnv* env);
|
||||
|
||||
static AndroidRuntime* gCurRuntime = NULL;
|
||||
|
||||
@ -1298,6 +1299,8 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_view_InputQueue),
|
||||
REG_JNI(register_android_view_KeyEvent),
|
||||
REG_JNI(register_android_view_MotionEvent),
|
||||
|
||||
REG_JNI(register_android_content_res_ObbScanner),
|
||||
};
|
||||
|
||||
/*
|
||||
|
94
core/jni/android_content_res_ObbScanner.cpp
Normal file
94
core/jni/android_content_res_ObbScanner.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2010, 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "ObbScanner"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/ObbFile.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "utils/misc.h"
|
||||
#include "android_runtime/AndroidRuntime.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
static struct {
|
||||
jclass clazz;
|
||||
|
||||
jfieldID packageName;
|
||||
jfieldID version;
|
||||
} gObbInfoClassInfo;
|
||||
|
||||
static jboolean android_content_res_ObbScanner_getObbInfo(JNIEnv* env, jobject clazz, jstring file,
|
||||
jobject obbInfo)
|
||||
{
|
||||
const char* filePath = env->GetStringUTFChars(file, JNI_FALSE);
|
||||
|
||||
sp<ObbFile> obb = new ObbFile();
|
||||
if (!obb->readFrom(filePath)) {
|
||||
env->ReleaseStringUTFChars(file, filePath);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
env->ReleaseStringUTFChars(file, filePath);
|
||||
|
||||
const char* packageNameStr = obb->getPackageName().string();
|
||||
|
||||
jstring packageName = env->NewStringUTF(packageNameStr);
|
||||
if (packageName == NULL) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
env->SetObjectField(obbInfo, gObbInfoClassInfo.packageName, packageName);
|
||||
env->SetIntField(obbInfo, gObbInfoClassInfo.version, obb->getVersion());
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* JNI registration.
|
||||
*/
|
||||
static JNINativeMethod gMethods[] = {
|
||||
/* name, signature, funcPtr */
|
||||
{ "getObbInfo_native", "(Ljava/lang/String;Landroid/content/res/ObbInfo;)Z",
|
||||
(void*) android_content_res_ObbScanner_getObbInfo },
|
||||
};
|
||||
|
||||
#define FIND_CLASS(var, className) \
|
||||
var = env->FindClass(className); \
|
||||
LOG_FATAL_IF(! var, "Unable to find class " className); \
|
||||
var = jclass(env->NewGlobalRef(var));
|
||||
|
||||
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
|
||||
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
|
||||
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
|
||||
|
||||
int register_android_content_res_ObbScanner(JNIEnv* env)
|
||||
{
|
||||
FIND_CLASS(gObbInfoClassInfo.clazz, "android/content/res/ObbInfo");
|
||||
|
||||
GET_FIELD_ID(gObbInfoClassInfo.packageName, gObbInfoClassInfo.clazz,
|
||||
"packageName", "Ljava/lang/String;");
|
||||
GET_FIELD_ID(gObbInfoClassInfo.version, gObbInfoClassInfo.clazz,
|
||||
"version", "I");
|
||||
|
||||
return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
|
||||
NELEM(gMethods));
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
@ -23,11 +23,14 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.ObbInfo;
|
||||
import android.content.res.ObbScanner;
|
||||
import android.net.Uri;
|
||||
import android.os.storage.IMountService;
|
||||
import android.os.storage.IMountServiceListener;
|
||||
import android.os.storage.IMountShutdownObserver;
|
||||
import android.os.storage.StorageResultCode;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
@ -53,7 +56,8 @@ class MountService extends IMountService.Stub
|
||||
private static final boolean LOCAL_LOGD = false;
|
||||
private static final boolean DEBUG_UNMOUNT = false;
|
||||
private static final boolean DEBUG_EVENTS = false;
|
||||
|
||||
private static final boolean DEBUG_OBB = true;
|
||||
|
||||
private static final String TAG = "MountService";
|
||||
|
||||
/*
|
||||
@ -130,6 +134,12 @@ class MountService extends IMountService.Stub
|
||||
*/
|
||||
final private HashSet<String> mAsecMountSet = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* Private hash of currently mounted filesystem images.
|
||||
*/
|
||||
final private HashSet<String> mObbMountSet = new HashSet<String>();
|
||||
|
||||
// Handler messages
|
||||
private static final int H_UNMOUNT_PM_UPDATE = 1;
|
||||
private static final int H_UNMOUNT_PM_DONE = 2;
|
||||
private static final int H_UNMOUNT_MS = 3;
|
||||
@ -287,7 +297,7 @@ class MountService extends IMountService.Stub
|
||||
Slog.w(TAG, "Waiting too long for mReady!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
@ -344,7 +354,7 @@ class MountService extends IMountService.Stub
|
||||
|
||||
MountServiceBinderListener(IMountServiceListener listener) {
|
||||
mListener = listener;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void binderDied() {
|
||||
@ -1327,5 +1337,145 @@ class MountService extends IMountService.Stub
|
||||
public void finishMediaUpdate() {
|
||||
mHandler.sendEmptyMessage(H_UNMOUNT_PM_DONE);
|
||||
}
|
||||
|
||||
private boolean isCallerOwnerOfPackage(String packageName) {
|
||||
final int callerUid = Binder.getCallingUid();
|
||||
return isUidOwnerOfPackage(packageName, callerUid);
|
||||
}
|
||||
|
||||
private boolean isUidOwnerOfPackage(String packageName, int callerUid) {
|
||||
if (packageName == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int packageUid = mPms.getPackageUid(packageName);
|
||||
|
||||
if (DEBUG_OBB) {
|
||||
Slog.d(TAG, "packageName = " + packageName + ", packageUid = " +
|
||||
packageUid + ", callerUid = " + callerUid);
|
||||
}
|
||||
|
||||
return callerUid == packageUid;
|
||||
}
|
||||
|
||||
public String getMountedObbPath(String filename) {
|
||||
waitForReady();
|
||||
warnOnNotMounted();
|
||||
|
||||
// XXX replace with call to IMediaContainerService
|
||||
ObbInfo obbInfo = ObbScanner.getObbInfo(filename);
|
||||
if (!isCallerOwnerOfPackage(obbInfo.packageName)) {
|
||||
throw new IllegalArgumentException("Caller package does not match OBB file");
|
||||
}
|
||||
|
||||
try {
|
||||
ArrayList<String> rsp = mConnector.doCommand(String.format("obb path %s", filename));
|
||||
String []tok = rsp.get(0).split(" ");
|
||||
int code = Integer.parseInt(tok[0]);
|
||||
if (code != VoldResponseCode.AsecPathResult) {
|
||||
throw new IllegalStateException(String.format("Unexpected response code %d", code));
|
||||
}
|
||||
return tok[1];
|
||||
} catch (NativeDaemonConnectorException e) {
|
||||
int code = e.getCode();
|
||||
if (code == VoldResponseCode.OpFailedStorageNotFound) {
|
||||
throw new IllegalArgumentException(String.format("OBB '%s' not found", filename));
|
||||
} else {
|
||||
throw new IllegalStateException(String.format("Unexpected response code %d", code));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isObbMounted(String filename) {
|
||||
waitForReady();
|
||||
warnOnNotMounted();
|
||||
|
||||
// XXX replace with call to IMediaContainerService
|
||||
ObbInfo obbInfo = ObbScanner.getObbInfo(filename);
|
||||
if (!isCallerOwnerOfPackage(obbInfo.packageName)) {
|
||||
throw new IllegalArgumentException("Caller package does not match OBB file");
|
||||
}
|
||||
|
||||
synchronized (mObbMountSet) {
|
||||
return mObbMountSet.contains(filename);
|
||||
}
|
||||
}
|
||||
|
||||
public int mountObb(String filename, String key) {
|
||||
waitForReady();
|
||||
warnOnNotMounted();
|
||||
|
||||
synchronized (mObbMountSet) {
|
||||
if (mObbMountSet.contains(filename)) {
|
||||
return StorageResultCode.OperationFailedStorageMounted;
|
||||
}
|
||||
}
|
||||
|
||||
final int callerUid = Binder.getCallingUid();
|
||||
|
||||
// XXX replace with call to IMediaContainerService
|
||||
ObbInfo obbInfo = ObbScanner.getObbInfo(filename);
|
||||
if (!isUidOwnerOfPackage(obbInfo.packageName, callerUid)) {
|
||||
throw new IllegalArgumentException("Caller package does not match OBB file");
|
||||
}
|
||||
|
||||
if (key == null) {
|
||||
key = "none";
|
||||
}
|
||||
|
||||
int rc = StorageResultCode.OperationSucceeded;
|
||||
String cmd = String.format("obb mount %s %s %d", filename, key, callerUid);
|
||||
try {
|
||||
mConnector.doCommand(cmd);
|
||||
} catch (NativeDaemonConnectorException e) {
|
||||
int code = e.getCode();
|
||||
if (code != VoldResponseCode.OpFailedStorageBusy) {
|
||||
rc = StorageResultCode.OperationFailedInternalError;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == StorageResultCode.OperationSucceeded) {
|
||||
synchronized (mObbMountSet) {
|
||||
mObbMountSet.add(filename);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public int unmountObb(String filename, boolean force) {
|
||||
waitForReady();
|
||||
warnOnNotMounted();
|
||||
|
||||
ObbInfo obbInfo = ObbScanner.getObbInfo(filename);
|
||||
if (!isCallerOwnerOfPackage(obbInfo.packageName)) {
|
||||
throw new IllegalArgumentException("Caller package does not match OBB file");
|
||||
}
|
||||
|
||||
synchronized (mObbMountSet) {
|
||||
if (!mObbMountSet.contains(filename)) {
|
||||
return StorageResultCode.OperationFailedStorageNotMounted;
|
||||
}
|
||||
}
|
||||
|
||||
int rc = StorageResultCode.OperationSucceeded;
|
||||
String cmd = String.format("obb unmount %s%s", filename, (force ? " force" : ""));
|
||||
try {
|
||||
mConnector.doCommand(cmd);
|
||||
} catch (NativeDaemonConnectorException e) {
|
||||
int code = e.getCode();
|
||||
if (code == VoldResponseCode.OpFailedStorageBusy) {
|
||||
rc = StorageResultCode.OperationFailedStorageBusy;
|
||||
} else {
|
||||
rc = StorageResultCode.OperationFailedInternalError;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == StorageResultCode.OperationSucceeded) {
|
||||
synchronized (mObbMountSet) {
|
||||
mObbMountSet.remove(filename);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user