From 5aca2b8dc4f4ff2d466a64587d06666c7bbd9749 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 16 Oct 2013 16:21:54 -0700 Subject: [PATCH] Plumb through physical device UUID and label. vold now parse out UUID and label for inserted physical devices, and reports them to framework. Add these to hidden StorageVolume class for use by DocumentsUI and MediaProvider. Remove last JNI method in FileUtils! Bug: 11175082 Change-Id: I1cfcd1ade61767b103f693319ea2600008ee2e3c --- core/java/android/os/FileUtils.java | 7 -- core/java/android/os/storage/StorageVolume.java | 75 +++++++++++++++---- core/jni/Android.mk | 1 - core/jni/AndroidRuntime.cpp | 2 - core/jni/android_os_FileUtils.cpp | 70 ------------------ services/java/com/android/server/MountService.java | 84 +++++++++++++++------- 6 files changed, 119 insertions(+), 120 deletions(-) delete mode 100644 core/jni/android_os_FileUtils.cpp diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 4d48fd46dd29..ff3e27785b74 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -144,13 +144,6 @@ public class FileUtils { } } - /** returns the FAT file system volume ID for the volume mounted - * at the given mount point, or -1 for failure - * @param mountPoint point for FAT volume - * @return volume ID or -1 - */ - public static native int getFatVolumeId(String mountPoint); - /** * Perform an fsync on the given FileOutputStream. The stream at this * point must be flushed but not yet closed. diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index 177a9554191a..1668f59f549d 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -21,6 +21,9 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; +import com.android.internal.util.IndentingPrintWriter; + +import java.io.CharArrayWriter; import java.io.File; /** @@ -46,6 +49,9 @@ public class StorageVolume implements Parcelable { /** When set, indicates exclusive ownership of this volume */ private final UserHandle mOwner; + private String mUuid; + private String mUserLabel; + // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING, // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED, // ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts. @@ -76,6 +82,8 @@ public class StorageVolume implements Parcelable { mAllowMassStorage = in.readInt() != 0; mMaxFileSize = in.readLong(); mOwner = in.readParcelable(null); + mUuid = in.readString(); + mUserLabel = in.readString(); } public static StorageVolume fromTemplate(StorageVolume template, File path, UserHandle owner) { @@ -189,6 +197,37 @@ public class StorageVolume implements Parcelable { return mOwner; } + public void setUuid(String uuid) { + mUuid = uuid; + } + + public String getUuid() { + return mUuid; + } + + /** + * Parse and return volume UUID as FAT volume ID, or return -1 if unable to + * parse or UUID is unknown. + */ + public int getFatVolumeId() { + if (mUuid == null || mUuid.length() != 9) { + return -1; + } + try { + return Integer.parseInt(mUuid.replace("-", ""), 16); + } catch (NumberFormatException e) { + return -1; + } + } + + public void setUserLabel(String userLabel) { + mUserLabel = userLabel; + } + + public String getUserLabel() { + return mUserLabel; + } + @Override public boolean equals(Object obj) { if (obj instanceof StorageVolume && mPath != null) { @@ -205,19 +244,27 @@ public class StorageVolume implements Parcelable { @Override public String toString() { - final StringBuilder builder = new StringBuilder("StorageVolume ["); - builder.append("mStorageId=").append(mStorageId); - builder.append(" mPath=").append(mPath); - builder.append(" mDescriptionId=").append(mDescriptionId); - builder.append(" mPrimary=").append(mPrimary); - builder.append(" mRemovable=").append(mRemovable); - builder.append(" mEmulated=").append(mEmulated); - builder.append(" mMtpReserveSpace=").append(mMtpReserveSpace); - builder.append(" mAllowMassStorage=").append(mAllowMassStorage); - builder.append(" mMaxFileSize=").append(mMaxFileSize); - builder.append(" mOwner=").append(mOwner); - builder.append("]"); - return builder.toString(); + final CharArrayWriter writer = new CharArrayWriter(); + dump(new IndentingPrintWriter(writer, " ", 80)); + return writer.toString(); + } + + public void dump(IndentingPrintWriter pw) { + pw.println("StorageVolume:"); + pw.increaseIndent(); + pw.printPair("mStorageId", mStorageId); + pw.printPair("mPath", mPath); + pw.printPair("mDescriptionId", mDescriptionId); + pw.printPair("mPrimary", mPrimary); + pw.printPair("mRemovable", mRemovable); + pw.printPair("mEmulated", mEmulated); + pw.printPair("mMtpReserveSpace", mMtpReserveSpace); + pw.printPair("mAllowMassStorage", mAllowMassStorage); + pw.printPair("mMaxFileSize", mMaxFileSize); + pw.printPair("mOwner", mOwner); + pw.printPair("mUuid", mUuid); + pw.printPair("mUserLabel", mUserLabel); + pw.decreaseIndent(); } public static final Creator CREATOR = new Creator() { @@ -249,5 +296,7 @@ public class StorageVolume implements Parcelable { parcel.writeInt(mAllowMassStorage ? 1 : 0); parcel.writeLong(mMaxFileSize); parcel.writeParcelable(mOwner, flags); + parcel.writeString(mUuid); + parcel.writeString(mUserLabel); } } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index e09fcff2d4e8..598312068914 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -60,7 +60,6 @@ LOCAL_SRC_FILES:= \ android_text_AndroidCharacter.cpp \ android_text_AndroidBidi.cpp \ android_os_Debug.cpp \ - android_os_FileUtils.cpp \ android_os_MemoryFile.cpp \ android_os_MessageQueue.cpp \ android_os_Parcel.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 851810143280..09577da9121c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -142,7 +142,6 @@ extern int register_android_os_SystemProperties(JNIEnv *env); extern int register_android_os_SystemClock(JNIEnv* env); extern int register_android_os_Trace(JNIEnv* env); extern int register_android_os_FileObserver(JNIEnv *env); -extern int register_android_os_FileUtils(JNIEnv *env); extern int register_android_os_UEventObserver(JNIEnv* env); extern int register_android_os_MemoryFile(JNIEnv* env); extern int register_android_net_LocalSocketImpl(JNIEnv* env); @@ -1169,7 +1168,6 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_database_SQLiteDebug), REG_JNI(register_android_os_Debug), REG_JNI(register_android_os_FileObserver), - REG_JNI(register_android_os_FileUtils), REG_JNI(register_android_os_MessageQueue), REG_JNI(register_android_os_SELinux), REG_JNI(register_android_os_Trace), diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp deleted file mode 100644 index d1245da24777..000000000000 --- a/core/jni/android_os_FileUtils.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* //device/libs/android_runtime/android_util_Process.cpp -** -** Copyright 2006, 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 "FileUtils" - -#include - -#include - -#include "JNIHelp.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace android { - -jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path) -{ - if (path == NULL) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return -1; - } - const char *pathStr = env->GetStringUTFChars(path, NULL); - int result = -1; - // only if our system supports this ioctl - #ifdef VFAT_IOCTL_GET_VOLUME_ID - int fd = open(pathStr, O_RDONLY); - if (fd >= 0) { - result = ioctl(fd, VFAT_IOCTL_GET_VOLUME_ID); - close(fd); - } - #endif - - env->ReleaseStringUTFChars(path, pathStr); - return result; -} - -static const JNINativeMethod methods[] = { - {"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId}, -}; - -static const char* const kFileUtilsPathName = "android/os/FileUtils"; - -int register_android_os_FileUtils(JNIEnv* env) -{ - return AndroidRuntime::registerNativeMethods( - env, kFileUtilsPathName, - methods, NELEM(methods)); -} - -} diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index c7ca1ea9cb3f..7308b7d7bb3e 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -56,12 +56,14 @@ import android.os.storage.StorageResultCode; import android.os.storage.StorageVolume; import android.text.TextUtils; import android.util.AttributeSet; +import android.util.Log; import android.util.Slog; import android.util.Xml; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IMediaContainerService; +import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.server.NativeDaemonConnector.Command; @@ -83,6 +85,7 @@ import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -173,6 +176,8 @@ class MountService extends IMountService.Stub * 600 series - Unsolicited broadcasts. */ public static final int VolumeStateChange = 605; + public static final int VolumeUuidChange = 613; + public static final int VolumeUserLabelChange = 614; public static final int VolumeDiskInserted = 630; public static final int VolumeDiskRemoved = 631; public static final int VolumeBadRemoval = 632; @@ -801,6 +806,26 @@ class MountService extends IMountService.Stub notifyVolumeStateChange( cooked[2], cooked[3], Integer.parseInt(cooked[7]), Integer.parseInt(cooked[10])); + } else if (code == VoldResponseCode.VolumeUuidChange) { + // Format: nnn