OSDN Git Service

Plumb through physical device UUID and label.
authorJeff Sharkey <jsharkey@android.com>
Wed, 16 Oct 2013 23:21:54 +0000 (16:21 -0700)
committerJeff Sharkey <jsharkey@android.com>
Wed, 16 Oct 2013 23:34:21 +0000 (16:34 -0700)
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
core/java/android/os/storage/StorageVolume.java
core/jni/Android.mk
core/jni/AndroidRuntime.cpp
core/jni/android_os_FileUtils.cpp [deleted file]
services/java/com/android/server/MountService.java

index 4d48fd4..ff3e277 100644 (file)
@@ -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.
index 177a955..1668f59 100644 (file)
@@ -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<StorageVolume> CREATOR = new Creator<StorageVolume>() {
@@ -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);
     }
 }
index e09fcff..5983120 100644 (file)
@@ -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 \
index 8518101..09577da 100644 (file)
@@ -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 (file)
index d1245da..0000000
+++ /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 <utils/Log.h>
-
-#include <android_runtime/AndroidRuntime.h>
-
-#include "JNIHelp.h"
-
-#include <sys/errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <linux/msdos_fs.h>
-
-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));
-}
-
-}
index c7ca1ea..7308b7d 100644 (file)
@@ -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 <label> <path> <uuid>
+            final String path = cooked[2];
+            final String uuid = (cooked.length > 3) ? cooked[3] : null;
+
+            final StorageVolume vol = mVolumesByPath.get(path);
+            if (vol != null) {
+                vol.setUuid(uuid);
+            }
+
+        } else if (code == VoldResponseCode.VolumeUserLabelChange) {
+            // Format: nnn <label> <path> <label>
+            final String path = cooked[2];
+            final String userLabel = (cooked.length > 3) ? cooked[3] : null;
+
+            final StorageVolume vol = mVolumesByPath.get(path);
+            if (vol != null) {
+                vol.setUserLabel(userLabel);
+            }
+
         } else if ((code == VoldResponseCode.VolumeDiskInserted) ||
                    (code == VoldResponseCode.VolumeDiskRemoved) ||
                    (code == VoldResponseCode.VolumeBadRemoval)) {
@@ -2743,54 +2768,59 @@ class MountService extends IMountService.Stub
     }
 
     @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump ActivityManager from from pid="
-                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
-                    + " without permission " + android.Manifest.permission.DUMP);
-            return;
-        }
+    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
 
-        synchronized (mObbMounts) {
-            pw.println("  mObbMounts:");
+        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ", 160);
 
-            final Iterator<Entry<IBinder, List<ObbState>>> binders = mObbMounts.entrySet().iterator();
+        synchronized (mObbMounts) {
+            pw.println("mObbMounts:");
+            pw.increaseIndent();
+            final Iterator<Entry<IBinder, List<ObbState>>> binders = mObbMounts.entrySet()
+                    .iterator();
             while (binders.hasNext()) {
                 Entry<IBinder, List<ObbState>> e = binders.next();
-                pw.print("    Key="); pw.println(e.getKey().toString());
+                pw.println(e.getKey() + ":");
+                pw.increaseIndent();
                 final List<ObbState> obbStates = e.getValue();
                 for (final ObbState obbState : obbStates) {
-                    pw.print("      "); pw.println(obbState.toString());
+                    pw.println(obbState);
                 }
+                pw.decreaseIndent();
             }
+            pw.decreaseIndent();
 
-            pw.println("");
-            pw.println("  mObbPathToStateMap:");
+            pw.println();
+            pw.println("mObbPathToStateMap:");
+            pw.increaseIndent();
             final Iterator<Entry<String, ObbState>> maps = mObbPathToStateMap.entrySet().iterator();
             while (maps.hasNext()) {
                 final Entry<String, ObbState> e = maps.next();
-                pw.print("    "); pw.print(e.getKey());
-                pw.print(" -> "); pw.println(e.getValue().toString());
+                pw.print(e.getKey());
+                pw.print(" -> ");
+                pw.println(e.getValue());
             }
+            pw.decreaseIndent();
         }
 
-        pw.println("");
-
         synchronized (mVolumesLock) {
-            pw.println("  mVolumes:");
-
-            final int N = mVolumes.size();
-            for (int i = 0; i < N; i++) {
-                final StorageVolume v = mVolumes.get(i);
-                pw.print("    ");
-                pw.println(v.toString());
-                pw.println("      state=" + mVolumeStates.get(v.getPath()));
+            pw.println();
+            pw.println("mVolumes:");
+            pw.increaseIndent();
+            for (StorageVolume volume : mVolumes) {
+                pw.println(volume);
+                pw.increaseIndent();
+                pw.println("Current state: " + mVolumeStates.get(volume.getPath()));
+                pw.decreaseIndent();
             }
+            pw.decreaseIndent();
         }
 
         pw.println();
-        pw.println("  mConnection:");
+        pw.println("mConnection:");
+        pw.increaseIndent();
         mConnector.dump(fd, pw, args);
+        pw.decreaseIndent();
     }
 
     /** {@inheritDoc} */