summaryrefslogtreecommitdiffstats
path: root/media/java
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@google.com>2010-10-14 18:03:25 -0400
committerMike Lockwood <lockwood@android.com>2010-11-15 11:46:51 -0500
commite2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6a (patch)
tree0f7de42a1ed233d704558830643e73acd954b940 /media/java
parent44d47ad56502a1ccb308a9ec2cd05120a53fac3d (diff)
downloadframeworks_base-e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6a.zip
frameworks_base-e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6a.tar.gz
frameworks_base-e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6a.tar.bz2
MTP: Partial implementation of the GetObjectPropList command
In this initial implementation we only support fetching one property at a time. Support depth = 0 (single object) or depth = 1 (all objects in a directory) Reimplemented GetObjectPropValue on top of GetObjectPropList, since the former is a special case of the latter. Change-Id: Ia76ee61741d6ee3902b5c5d9fc094cf86dfaf650 Signed-off-by: Mike Lockwood <lockwood@google.com>
Diffstat (limited to 'media/java')
-rw-r--r--media/java/android/media/MtpConstants.java24
-rw-r--r--media/java/android/media/MtpDatabase.java394
-rw-r--r--media/java/android/media/MtpPropertyList.java76
3 files changed, 355 insertions, 139 deletions
diff --git a/media/java/android/media/MtpConstants.java b/media/java/android/media/MtpConstants.java
index a7d33ce..b20cbd1 100644
--- a/media/java/android/media/MtpConstants.java
+++ b/media/java/android/media/MtpConstants.java
@@ -21,6 +21,30 @@ package android.media;
*/
public final class MtpConstants {
+// MTP Data Types
+ public static final int TYPE_UNDEFINED = 0x0000;
+ public static final int TYPE_INT8 = 0x0001;
+ public static final int TYPE_UINT8 = 0x0002;
+ public static final int TYPE_INT16 = 0x0003;
+ public static final int TYPE_UINT16 = 0x0004;
+ public static final int TYPE_INT32 = 0x0005;
+ public static final int TYPE_UINT32 = 0x0006;
+ public static final int TYPE_INT64 = 0x0007;
+ public static final int TYPE_UINT64 = 0x0008;
+ public static final int TYPE_INT128 = 0x0009;
+ public static final int TYPE_UINT128 = 0x000A;
+ public static final int TYPE_AINT8 = 0x4001;
+ public static final int TYPE_AUINT8 = 0x4002;
+ public static final int TYPE_AINT16 = 0x4003;
+ public static final int TYPE_AUINT16 = 0x4004;
+ public static final int TYPE_AINT32 = 0x4005;
+ public static final int TYPE_AUINT32 = 0x4006;
+ public static final int TYPE_AINT64 = 0x4007;
+ public static final int TYPE_AUINT64 = 0x4008;
+ public static final int TYPE_AINT128 = 0x4009;
+ public static final int TYPE_AUINT128 = 0x400A;
+ public static final int TYPE_STR = 0xFFFF;
+
// MTP Response Codes
public static final int RESPONSE_UNDEFINED = 0x2000;
public static final int RESPONSE_OK = 0x2001;
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 57ab3a1..0d09d4c 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -30,6 +30,7 @@ import android.provider.MediaStore.Files;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.MediaColumns;
import android.provider.Mtp;
+import android.text.format.Time;
import android.util.Log;
import java.io.File;
@@ -428,6 +429,26 @@ public class MtpDatabase {
}
}
+ private String queryAudio(int id, String column) {
+ Cursor c = null;
+ try {
+ c = mMediaProvider.query(Audio.Media.getContentUri(mVolumeName),
+ new String [] { Files.FileColumns._ID, column },
+ ID_WHERE, new String[] { Integer.toString(id) }, null);
+ if (c != null && c.moveToNext()) {
+ return c.getString(1);
+ } else {
+ return "";
+ }
+ } catch (Exception e) {
+ return null;
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
private String queryGenre(int id) {
Cursor c = null;
try {
@@ -450,7 +471,7 @@ public class MtpDatabase {
}
}
- private boolean queryInt(int id, String column, long[] outValue) {
+ private Long queryLong(int id, String column) {
Cursor c = null;
try {
// for now we are only reading properties from the "objects" table
@@ -458,17 +479,15 @@ public class MtpDatabase {
new String [] { Files.FileColumns._ID, column },
ID_WHERE, new String[] { Integer.toString(id) }, null);
if (c != null && c.moveToNext()) {
- outValue[0] = c.getLong(1);
- return true;
+ return new Long(c.getLong(1));
}
- return false;
} catch (Exception e) {
- return false;
} finally {
if (c != null) {
c.close();
}
}
+ return null;
}
private String nameFromPath(String path) {
@@ -485,197 +504,294 @@ public class MtpDatabase {
return path.substring(start, end);
}
- private int renameFile(int handle, String newName) {
- Cursor c = null;
-
- // first compute current path
- String path = null;
- String[] whereArgs = new String[] { Integer.toString(handle) };
- try {
- c = mMediaProvider.query(mObjectsUri, PATH_PROJECTION, ID_WHERE, whereArgs, null);
- if (c != null && c.moveToNext()) {
- path = externalToMediaPath(c.getString(1));
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getObjectFilePath", e);
- return MtpConstants.RESPONSE_GENERAL_ERROR;
- } finally {
- if (c != null) {
- c.close();
- }
- }
- if (path == null) {
- return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
- }
-
- // now rename the file. make sure this succeeds before updating database
- File oldFile = new File(path);
- int lastSlash = path.lastIndexOf('/');
- if (lastSlash <= 1) {
- return MtpConstants.RESPONSE_GENERAL_ERROR;
- }
- String newPath = path.substring(0, lastSlash + 1) + newName;
- File newFile = new File(newPath);
- boolean success = oldFile.renameTo(newFile);
- Log.d(TAG, "renaming "+ path + " to " + newPath + (success ? " succeeded" : " failed"));
- if (!success) {
- return MtpConstants.RESPONSE_GENERAL_ERROR;
- }
+ private String formatDateTime(long seconds) {
+ Time time = new Time(Time.TIMEZONE_UTC);
+ time.set(seconds * 1000);
+ String result = time.format("%Y-%m-%dT%H:%M:%SZ");
+ Log.d(TAG, "formatDateTime returning " + result);
+ return result;
+ }
- // finally update database
- ContentValues values = new ContentValues();
- values.put(Files.FileColumns.DATA, newPath);
- int updated = 0;
- try {
- // note - we are relying on a special case in MediaProvider.update() to update
- // the paths for all children in the case where this is a directory.
- updated = mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in mMediaProvider.update", e);
+ private MtpPropertyList getObjectPropertyList(int handle, int format, int property,
+ int groupCode, int depth) {
+ // FIXME - implement group support
+ // For now we only support a single property at a time
+ if (groupCode != 0) {
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED);
}
- if (updated == 0) {
- Log.e(TAG, "Unable to update path for " + path + " to " + newPath);
- // this shouldn't happen, but if it does we need to rename the file to its original name
- newFile.renameTo(oldFile);
- return MtpConstants.RESPONSE_GENERAL_ERROR;
+ if (depth > 1) {
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED);
}
- return MtpConstants.RESPONSE_OK;
- }
-
- private int getObjectProperty(int handle, int property,
- long[] outIntValue, char[] outStringValue) {
- Log.d(TAG, "getObjectProperty: " + property);
String column = null;
- boolean isString = false;
+ int type = MtpConstants.TYPE_UNDEFINED;
- switch (property) {
+ switch (property) {
case MtpConstants.PROPERTY_STORAGE_ID:
- outIntValue[0] = mStorageID;
- return MtpConstants.RESPONSE_OK;
- case MtpConstants.PROPERTY_OBJECT_FORMAT:
+ // no query needed until we support multiple storage units
+ // for now it is always mStorageID
+ type = MtpConstants.TYPE_UINT32;
+ break;
+ case MtpConstants.PROPERTY_OBJECT_FORMAT:
column = Files.FileColumns.FORMAT;
+ type = MtpConstants.TYPE_UINT16;
break;
case MtpConstants.PROPERTY_PROTECTION_STATUS:
// protection status is always 0
- outIntValue[0] = 0;
- return MtpConstants.RESPONSE_OK;
+ type = MtpConstants.TYPE_UINT16;
+ break;
case MtpConstants.PROPERTY_OBJECT_SIZE:
column = Files.FileColumns.SIZE;
+ type = MtpConstants.TYPE_UINT64;
break;
case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
- // special case - need to extract file name from full path
- String value = queryString(handle, Files.FileColumns.DATA);
- if (value != null) {
- value = nameFromPath(value);
- value.getChars(0, value.length(), outStringValue, 0);
- outStringValue[value.length()] = 0;
- return MtpConstants.RESPONSE_OK;
- } else {
- return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
- }
+ column = Files.FileColumns.DATA;
+ type = MtpConstants.TYPE_STR;
+ break;
case MtpConstants.PROPERTY_NAME:
- // first try title
- String name = queryString(handle, MediaColumns.TITLE);
- // then try name
- if (name == null) {
- name = queryString(handle, Audio.PlaylistsColumns.NAME);
- }
- // if title and name fail, extract name from full path
- if (name == null) {
- name = queryString(handle, Files.FileColumns.DATA);
- if (name != null) {
- name = nameFromPath(name);
- }
- }
- if (name != null) {
- name.getChars(0, name.length(), outStringValue, 0);
- outStringValue[name.length()] = 0;
- return MtpConstants.RESPONSE_OK;
- } else {
- return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
- }
+ column = MediaColumns.TITLE;
+ type = MtpConstants.TYPE_STR;
+ break;
case MtpConstants.PROPERTY_DATE_MODIFIED:
column = Files.FileColumns.DATE_MODIFIED;
+ type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_DATE_ADDED:
column = Files.FileColumns.DATE_ADDED;
+ type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
column = Audio.AudioColumns.YEAR;
+ type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_PARENT_OBJECT:
column = Files.FileColumns.PARENT;
+ type = MtpConstants.TYPE_UINT32;
break;
case MtpConstants.PROPERTY_PERSISTENT_UID:
// PUID is concatenation of storageID and object handle
- long puid = mStorageID;
- puid <<= 32;
- puid += handle;
- outIntValue[0] = puid;
- return MtpConstants.RESPONSE_OK;
+ type = MtpConstants.TYPE_UINT128;
+ break;
case MtpConstants.PROPERTY_DURATION:
column = Audio.AudioColumns.DURATION;
+ type = MtpConstants.TYPE_UINT32;
break;
case MtpConstants.PROPERTY_TRACK:
- if (queryInt(handle, Audio.AudioColumns.TRACK, outIntValue)) {
- // track is stored in lower 3 decimal digits
- outIntValue[0] %= 1000;
- return MtpConstants.RESPONSE_OK;
- } else {
- return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
- }
+ column = Audio.AudioColumns.TRACK;
+ type = MtpConstants.TYPE_UINT16;
+ break;
case MtpConstants.PROPERTY_DISPLAY_NAME:
column = MediaColumns.DISPLAY_NAME;
- isString = true;
+ type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_ARTIST:
- column = Audio.AudioColumns.ARTIST;
- isString = true;
+ type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_ALBUM_NAME:
- column = Audio.AudioColumns.ALBUM;
- isString = true;
+ type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_ALBUM_ARTIST:
column = Audio.AudioColumns.ALBUM_ARTIST;
- isString = true;
+ type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_GENRE:
- String genre = queryGenre(handle);
- if (genre != null) {
- genre.getChars(0, genre.length(), outStringValue, 0);
- outStringValue[genre.length()] = 0;
- return MtpConstants.RESPONSE_OK;
- } else {
- return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
- }
+ // genre requires a special query
+ type = MtpConstants.TYPE_STR;
+ break;
case MtpConstants.PROPERTY_COMPOSER:
column = Audio.AudioColumns.COMPOSER;
- isString = true;
+ type = MtpConstants.TYPE_STR;
break;
case MtpConstants.PROPERTY_DESCRIPTION:
column = Images.ImageColumns.DESCRIPTION;
- isString = true;
+ type = MtpConstants.TYPE_STR;
break;
default:
- return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED);
}
- if (isString) {
- String value = queryString(handle, column);
- if (value != null) {
- value.getChars(0, value.length(), outStringValue, 0);
- outStringValue[value.length()] = 0;
- return MtpConstants.RESPONSE_OK;
+ Cursor c = null;
+ try {
+ if (column != null) {
+ c = mMediaProvider.query(mObjectsUri,
+ new String [] { Files.FileColumns._ID, column },
+ // depth 0: single record, depth 1: immediate children
+ (depth == 0 ? ID_WHERE : PARENT_WHERE),
+ new String[] { Integer.toString(handle) }, null);
+ if (c == null) {
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
+ } else if (depth == 1) {
+ c = mMediaProvider.query(mObjectsUri,
+ new String [] { Files.FileColumns._ID },
+ PARENT_WHERE, new String[] { Integer.toString(handle) }, null);
+ if (c == null) {
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
}
- } else {
- if (queryInt(handle, column, outIntValue)) {
- return MtpConstants.RESPONSE_OK;
+
+ int count = (c == null ? 1 : c.getCount());
+ MtpPropertyList result = new MtpPropertyList(count, MtpConstants.RESPONSE_OK);
+
+ for (int index = 0; index < count; index++) {
+ if (c != null) {
+ c.moveToNext();
+ }
+ if (depth == 1) {
+ handle = (int)c.getLong(0);
+ }
+
+ switch (property) {
+ // handle special cases here
+ case MtpConstants.PROPERTY_STORAGE_ID:
+ result.setProperty(index, handle, property, MtpConstants.TYPE_UINT32,
+ mStorageID);
+ break;
+ case MtpConstants.PROPERTY_PROTECTION_STATUS:
+ // protection status is always 0
+ result.setProperty(index, handle, property, MtpConstants.TYPE_UINT16, 0);
+ break;
+ case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
+ // special case - need to extract file name from full path
+ String value = c.getString(1);
+ if (value != null) {
+ result.setProperty(index, handle, property, nameFromPath(value));
+ } else {
+ result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
+ break;
+ case MtpConstants.PROPERTY_NAME:
+ // first try title
+ String name = c.getString(1);
+ // then try name
+ if (name == null) {
+ name = queryString(handle, Audio.PlaylistsColumns.NAME);
+ }
+ // if title and name fail, extract name from full path
+ if (name == null) {
+ name = queryString(handle, Files.FileColumns.DATA);
+ if (name != null) {
+ name = nameFromPath(name);
+ }
+ }
+ if (name != null) {
+ result.setProperty(index, handle, property, name);
+ } else {
+ result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
+ break;
+ case MtpConstants.PROPERTY_DATE_MODIFIED:
+ case MtpConstants.PROPERTY_DATE_ADDED:
+ // convert from seconds to DateTime
+ result.setProperty(index, handle, property, formatDateTime(c.getInt(1)));
+ break;
+ case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
+ // release date is stored internally as just the year
+ int year = c.getInt(1);
+ String dateTime = Integer.toString(year) + "0101T000000";
+ result.setProperty(index, handle, property, dateTime);
+ break;
+ case MtpConstants.PROPERTY_PERSISTENT_UID:
+ // PUID is concatenation of storageID and object handle
+ long puid = mStorageID;
+ puid <<= 32;
+ puid += handle;
+ result.setProperty(index, handle, property, MtpConstants.TYPE_UINT128, puid);
+ break;
+ case MtpConstants.PROPERTY_TRACK:
+ result.setProperty(index, handle, property, MtpConstants.TYPE_UINT16,
+ c.getInt(1) % 1000);
+ break;
+ case MtpConstants.PROPERTY_ARTIST:
+ result.setProperty(index, handle, property, queryAudio(handle, Audio.AudioColumns.ARTIST));
+ break;
+ case MtpConstants.PROPERTY_ALBUM_NAME:
+ result.setProperty(index, handle, property, queryAudio(handle, Audio.AudioColumns.ALBUM));
+ break;
+ case MtpConstants.PROPERTY_GENRE:
+ String genre = queryGenre(handle);
+ if (genre != null) {
+ result.setProperty(index, handle, property, genre);
+ } else {
+ result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
+ break;
+ default:
+ if (type == MtpConstants.TYPE_STR) {
+ result.setProperty(index, handle, property, c.getString(1));
+ } else {
+ result.setProperty(index, handle, property, type, c.getLong(1));
+ }
+ }
+ }
+
+ return result;
+ } catch (RemoteException e) {
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_GENERAL_ERROR);
+ } finally {
+ if (c != null) {
+ c.close();
}
}
- // query failed if we get here
- return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
+ // impossible to get here, so no return statement
+ }
+
+ private int renameFile(int handle, String newName) {
+ Cursor c = null;
+
+ // first compute current path
+ String path = null;
+ String[] whereArgs = new String[] { Integer.toString(handle) };
+ try {
+ c = mMediaProvider.query(mObjectsUri, PATH_PROJECTION, ID_WHERE, whereArgs, null);
+ if (c != null && c.moveToNext()) {
+ path = externalToMediaPath(c.getString(1));
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getObjectFilePath", e);
+ return MtpConstants.RESPONSE_GENERAL_ERROR;
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ if (path == null) {
+ return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
+ }
+
+ // now rename the file. make sure this succeeds before updating database
+ File oldFile = new File(path);
+ int lastSlash = path.lastIndexOf('/');
+ if (lastSlash <= 1) {
+ return MtpConstants.RESPONSE_GENERAL_ERROR;
+ }
+ String newPath = path.substring(0, lastSlash + 1) + newName;
+ File newFile = new File(newPath);
+ boolean success = oldFile.renameTo(newFile);
+ Log.d(TAG, "renaming "+ path + " to " + newPath + (success ? " succeeded" : " failed"));
+ if (!success) {
+ return MtpConstants.RESPONSE_GENERAL_ERROR;
+ }
+
+ // finally update database
+ ContentValues values = new ContentValues();
+ values.put(Files.FileColumns.DATA, newPath);
+ int updated = 0;
+ try {
+ // note - we are relying on a special case in MediaProvider.update() to update
+ // the paths for all children in the case where this is a directory.
+ updated = mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in mMediaProvider.update", e);
+ }
+ if (updated == 0) {
+ Log.e(TAG, "Unable to update path for " + path + " to " + newPath);
+ // this shouldn't happen, but if it does we need to rename the file to its original name
+ newFile.renameTo(oldFile);
+ return MtpConstants.RESPONSE_GENERAL_ERROR;
+ }
+
+ return MtpConstants.RESPONSE_OK;
}
private int setObjectProperty(int handle, int property,
diff --git a/media/java/android/media/MtpPropertyList.java b/media/java/android/media/MtpPropertyList.java
new file mode 100644
index 0000000..f598981
--- /dev/null
+++ b/media/java/android/media/MtpPropertyList.java
@@ -0,0 +1,76 @@
+/*
+ * 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.media;
+
+/**
+ * Encapsulates the ObjectPropList dataset used by the GetObjectPropList command.
+ * The fields of this class are read by JNI code in android_media_MtpDatabase.cpp
+ *
+ * {@hide}
+ */
+
+public class MtpPropertyList {
+
+ // number of results returned
+ public final int mCount;
+ // result code for GetObjectPropList
+ public int mResult;
+ // list of object handles (first field in quadruplet)
+ public final int[] mObjectHandles;
+ // list of object propery codes (second field in quadruplet)
+ public final int[] mPropertyCodes;
+ // list of data type codes (third field in quadruplet)
+ public final int[] mDataTypes;
+ // list of long int property values (fourth field in quadruplet, when value is integer type)
+ public long[] mLongValues;
+ // list of long int property values (fourth field in quadruplet, when value is string type)
+ public String[] mStringValues;
+
+ // constructor only called from MtpDatabase
+ public MtpPropertyList(int count, int result) {
+ mCount = count;
+ mResult = result;
+ mObjectHandles = new int[count];
+ mPropertyCodes = new int[count];
+ mDataTypes = new int[count];
+ // mLongValues and mStringValues are created lazily since both might not be necessary
+ }
+
+ public void setProperty(int index, int handle, int property, int type, long value) {
+ if (mLongValues == null) {
+ mLongValues = new long[mCount];
+ }
+ mObjectHandles[index] = handle;
+ mPropertyCodes[index] = property;
+ mDataTypes[index] = type;
+ mLongValues[index] = value;
+ }
+
+ public void setProperty(int index, int handle, int property, String value) {
+ if (mStringValues == null) {
+ mStringValues = new String[mCount];
+ }
+ mObjectHandles[index] = handle;
+ mPropertyCodes[index] = property;
+ mDataTypes[index] = MtpConstants.TYPE_STR;
+ mStringValues[index] = value;
+ }
+
+ public void setResult(int result) {
+ mResult = result;
+ }
+}