diff options
4 files changed, 173 insertions, 414 deletions
diff --git a/core/java/android/os/IMountService.aidl b/core/java/android/os/IMountService.aidl index 1e79030e46f8..e73569adc97e 100644 --- a/core/java/android/os/IMountService.aidl +++ b/core/java/android/os/IMountService.aidl @@ -42,17 +42,17 @@ interface IMountService /** * Mount external storage at given mount point. */ - void mountMedia(String mountPoint); + void mountVolume(String mountPoint); /** * Safely unmount external storage at given mount point. */ - void unmountMedia(String mountPoint); + void unmountVolume(String mountPoint); /** * Format external storage given a mount point. */ - void formatMedia(String mountPoint); + void formatVolume(String mountPoint); /** * Returns true if media notification sounds are enabled. diff --git a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java index 000f6c49ab49..2b07ae67c566 100644 --- a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java +++ b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java @@ -102,7 +102,7 @@ public class ExternalMediaFormatActivity extends AlertActivity implements Dialog .getService("mount")); if (mountService != null) { try { - mountService.formatMedia(Environment.getExternalStorageDirectory().toString()); + mountService.formatVolume(Environment.getExternalStorageDirectory().toString()); } catch (RemoteException e) { } } diff --git a/services/java/com/android/server/MountListener.java b/services/java/com/android/server/MountListener.java deleted file mode 100644 index 9443ff84921f..000000000000 --- a/services/java/com/android/server/MountListener.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2007 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 com.android.server; - -import android.net.LocalSocketAddress; -import android.net.LocalSocket; -import android.os.Environment; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.util.Config; -import android.util.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.lang.IllegalStateException; - -import java.util.List; -import java.util.ArrayList; -import java.util.ListIterator; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -/** - * Vold Connection class - */ -final class MountListener implements Runnable { - private static final String TAG = "MountListener"; - private static final String VOLD_SOCKET = "vold"; - private static final int RESPONSE_QUEUE_SIZE = 10; - - private MountService mService; - private BlockingQueue<String> mResponseQueue; - private OutputStream mOutputStream; - - class ResponseCode { - public static final int ActionInitiated = 100; - public static final int VolumeListResult = 110; - public static final int AsecListResult = 111; - - public static final int CommandOkay = 200; - public static final int ShareAvailabilityResult = 210; - public static final int AsecPathResult = 211; - - public static final int UnsolicitedInformational = 600; - public static final int VolumeStateChange = 605; - public static final int VolumeMountFailedBlank = 610; - public static final int VolumeMountFailedDamaged = 611; - public static final int VolumeMountFailedNoMedia = 612; - public static final int ShareAvailabilityChange = 620; - public static final int VolumeDiskInserted = 630; - public static final int VolumeDiskRemoved = 631; - public static final int VolumeBadRemoval = 632; - } - - MountListener(MountService service) { - mService = service; - mResponseQueue = new LinkedBlockingQueue<String>(RESPONSE_QUEUE_SIZE); - } - - public void run() { - // Vold does not run in the simulator, so fake out a mounted event to trigger the Media Scanner - if ("simulator".equals(SystemProperties.get("ro.product.device"))) { - mService.notifyMediaMounted(Environment.getExternalStorageDirectory().getPath(), false); - return; - } - - try { - while (true) { - listenToSocket(); - } - } catch (Throwable t) { - Log.e(TAG, "Fatal error " + t + " in MountListener thread!"); - } - } - - private void listenToSocket() { - LocalSocket socket = null; - - try { - socket = new LocalSocket(); - LocalSocketAddress address = new LocalSocketAddress(VOLD_SOCKET, - LocalSocketAddress.Namespace.RESERVED); - - socket.connect(address); - mService.onVoldConnected(); - - InputStream inputStream = socket.getInputStream(); - mOutputStream = socket.getOutputStream(); - - byte[] buffer = new byte[4096]; - - while (true) { - int count = inputStream.read(buffer); - if (count < 0) break; - - int start = 0; - for (int i = 0; i < count; i++) { - if (buffer[i] == 0) { - String event = new String(buffer, start, i - start); -// Log.d(TAG, "Got packet {" + event + "}"); - - String[] tokens = event.split(" "); - try { - int code = Integer.parseInt(tokens[0]); - - if (code >= ResponseCode.UnsolicitedInformational) { - try { - handleUnsolicitedEvent(code, event, tokens); - } catch (Exception ex) { - Log.e(TAG, String.format( - "Error handling '%s'", event), ex); - } - } else { - try { - mResponseQueue.put(event); - } catch (InterruptedException ex) { - Log.e(TAG, "InterruptedException"); - } - } - } catch (NumberFormatException nfe) { - Log.w(TAG, - "Unknown msg from Vold '" + event + "'"); - } - start = i + 1; - } - } - } - } catch (IOException ex) { - Log.e(TAG, "IOException in listenToSocket"); - } - - synchronized (this) { - if (mOutputStream != null) { - try { - mOutputStream.close(); - } catch (IOException e) { - Log.w(TAG, "IOException closing output stream"); - } - - mOutputStream = null; - } - } - - try { - if (socket != null) { - socket.close(); - } - } catch (IOException ex) { - Log.w(TAG, "IOException closing socket"); - } - - Log.e(TAG, "Failed to connect to Vold", new IllegalStateException()); - SystemClock.sleep(5000); - } - - private void handleUnsolicitedEvent(int code, String raw, - String[] cooked) throws IllegalStateException { -// Log.d(TAG, "unsolicited {" + raw + "}"); - if (code == ResponseCode.VolumeStateChange) { - // FMT: NNN Volume <label> <mountpoint> state changed from <old_#> (<old_str>) to <new_#> (<new_str>) - mService.notifyVolumeStateChange(cooked[2], cooked[3], - Integer.parseInt(cooked[7]), - Integer.parseInt(cooked[10])); - } else if (code == ResponseCode.VolumeMountFailedBlank) { - // FMT: NNN Volume <label> <mountpoint> mount failed - no supported file-systems - mService.notifyMediaNoFs(cooked[3]); - // FMT: NNN Volume <label> <mountpoint> mount failed - no media - } else if (code == ResponseCode.VolumeMountFailedNoMedia) { - mService.notifyMediaRemoved(cooked[3]); - } else if (code == ResponseCode.VolumeMountFailedDamaged) { - // FMT: NNN Volume <label> <mountpoint> mount failed - filesystem check failed - mService.notifyMediaUnmountable(cooked[3]); - } else if (code == ResponseCode.ShareAvailabilityChange) { - // FMT: NNN Share method <method> now <available|unavailable> - boolean avail = false; - if (cooked[5].equals("available")) { - avail = true; - } - mService.notifyShareAvailabilityChange(cooked[3], avail); - } else if (code == ResponseCode.VolumeDiskInserted) { - // FMT: NNN Volume <label> <mountpoint> disk inserted (<major>:<minor>) - mService.notifyMediaInserted(cooked[3]); - } else if (code == ResponseCode.VolumeDiskRemoved) { - // FMT: NNN Volume <label> <mountpoint> disk removed (<major>:<minor>) - mService.notifyMediaRemoved(cooked[3]); - } else if (code == ResponseCode.VolumeBadRemoval) { - // FMT: NNN Volume <label> <mountpoint> bad removal (<major>:<minor>) - mService.notifyMediaBadRemoval(cooked[3]); - } else { - Log.w(TAG, "Unhandled event {" + raw + "}"); - } - } - - - private void sendCommand(String command) { - sendCommand(command, null); - } - - /** - * Sends a command to Vold with a single argument - * - * @param command The command to send to the mount service daemon - * @param argument The argument to send with the command (or null) - */ - private void sendCommand(String command, String argument) { - synchronized (this) { - // Log.d(TAG, "sendCommand {" + command + "} {" + argument + "}"); - if (mOutputStream == null) { - Log.e(TAG, "No connection to Vold", new IllegalStateException()); - } else { - StringBuilder builder = new StringBuilder(command); - if (argument != null) { - builder.append(argument); - } - builder.append('\0'); - - try { - mOutputStream.write(builder.toString().getBytes()); - } catch (IOException ex) { - Log.e(TAG, "IOException in sendCommand", ex); - } - } - } - } - - private synchronized ArrayList<String> doCommand(String cmd) throws IllegalStateException { - sendCommand(cmd); - - ArrayList<String> response = new ArrayList<String>(); - boolean complete = false; - int code = -1; - - while (!complete) { - try { - String line = mResponseQueue.take(); -// Log.d(TAG, "Removed off queue -> " + line); - String[] tokens = line.split(" "); - code = Integer.parseInt(tokens[0]); - - if ((code >= 200) && (code < 600)) - complete = true; - response.add(line); - } catch (InterruptedException ex) { - Log.e(TAG, "InterruptedException"); - } - } - - if (code >= 400 && code < 600) { - throw new IllegalStateException(String.format( - "Command %s failed with code %d", - cmd, code)); - } - return response; - } - - boolean getShareAvailable(String method) throws IllegalStateException { - ArrayList<String> rsp = doCommand("share_available " + method); - - for (String line : rsp) { - String []tok = line.split(" "); - int code = Integer.parseInt(tok[0]); - if (code == ResponseCode.ShareAvailabilityResult) { - if (tok[2].equals("available")) - return true; - return false; - } else { - throw new IllegalStateException(String.format("Unexpected response code %d", code)); - } - } - throw new IllegalStateException("Got an empty response"); - } - - /** - * Enables or disables USB mass storage support. - * - * @param enable true to enable USB mass storage support - */ - void setShareMethodEnabled(String mountPoint, String method, - boolean enable) throws IllegalStateException { - doCommand((enable ? "" : "un") + "share " + mountPoint + " " + method); - } - - /** - * Mount media at given mount point. - */ - public void mountVolume(String label) throws IllegalStateException { - doCommand("mount " + label); - } - - /** - * Unmount media at given mount point. - */ - public void unmountVolume(String label) throws IllegalStateException { - doCommand("unmount " + label); - } - - /** - * Format media at given mount point. - */ - public void formatVolume(String label) throws IllegalStateException { - doCommand("format " + label); - } - - public String createAsec(String id, int sizeMb, String fstype, String key, - int ownerUid) throws IllegalStateException { - String cmd = String.format("create_asec %s %d %s %s %d", - id, sizeMb, fstype, key, ownerUid); - doCommand(cmd); - return getAsecPath(id); - } - - public void finalizeAsec(String id) throws IllegalStateException { - doCommand("finalize_asec " + id); - } - - public void destroyAsec(String id) throws IllegalStateException { - doCommand("destroy_asec " + id); - } - - public String mountAsec(String id, String key, int ownerUid) throws IllegalStateException { - String cmd = String.format("mount_asec %s %s %d", - id, key, ownerUid); - doCommand(cmd); - return getAsecPath(id); - } - - public String getAsecPath(String id) throws IllegalStateException { - ArrayList<String> rsp = doCommand("asec_path " + id); - - for (String line : rsp) { - String []tok = line.split(" "); - int code = Integer.parseInt(tok[0]); - if (code == ResponseCode.AsecPathResult) { - return tok[1]; - } else { - throw new IllegalStateException(String.format("Unexpected response code %d", code)); - } - } - throw new IllegalStateException("Got an empty response"); - } - - public String[] listAsec() throws IllegalStateException { - ArrayList<String> rsp = doCommand("list_asec"); - - String[] rdata = new String[rsp.size()]; - int idx = 0; - - for (String line : rsp) { - String []tok = line.split(" "); - int code = Integer.parseInt(tok[0]); - if (code == ResponseCode.AsecListResult) { - rdata[idx++] = tok[1]; - } else if (code == ResponseCode.CommandOkay) { - return rdata; - } else { - throw new IllegalStateException(String.format("Unexpected response code %d", code)); - } - } - throw new IllegalStateException("Got an empty response"); - } -} diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 81ebe031938a..c8a691526058 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -33,6 +33,7 @@ import android.os.UEventObserver; import android.os.Handler; import android.text.TextUtils; import android.util.Log; +import java.util.ArrayList; import android.provider.Settings; import android.content.ContentResolver; @@ -46,7 +47,8 @@ import java.lang.IllegalStateException; * MountService implements an to the mount service daemon * @hide */ -class MountService extends IMountService.Stub { +class MountService extends IMountService.Stub + implements INativeDaemonConnectorCallbacks { private static final String TAG = "MountService"; @@ -63,15 +65,33 @@ class MountService extends IMountService.Stub { public static final int SharedMnt = 8; } + class VoldResponseCode { + public static final int VolumeListResult = 110; + public static final int AsecListResult = 111; + + public static final int ShareAvailabilityResult = 210; + public static final int AsecPathResult = 211; + + public static final int VolumeStateChange = 605; + public static final int VolumeMountFailedBlank = 610; + public static final int VolumeMountFailedDamaged = 611; + public static final int VolumeMountFailedNoMedia = 612; + public static final int ShareAvailabilityChange = 620; + public static final int VolumeDiskInserted = 630; + public static final int VolumeDiskRemoved = 631; + public static final int VolumeBadRemoval = 632; + } + + /** * Binder context for this service */ private Context mContext; /** - * listener object for communicating with the mount service daemon + * connectorr object for communicating with vold */ - private MountListener mListener; + private NativeDaemonConnector mConnector; /** * The notification that is shown when a USB mass storage host @@ -119,12 +139,12 @@ class MountService extends IMountService.Stub { mContext = context; // Register a BOOT_COMPLETED handler so that we can start - // MountListener. We defer the startup so that we don't + // our NativeDaemonConnector. We defer the startup so that we don't // start processing events before we ought-to mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null); - mListener = new MountListener(this); + mConnector = new NativeDaemonConnector(this, "vold", 10, "VoldConnector"); mShowSafeUnmountNotificationWhenUnmounted = false; mPlaySounds = SystemProperties.get("persist.service.mount.playsnd", "1").equals("1"); @@ -202,7 +222,18 @@ class MountService extends IMountService.Stub { String action = intent.getAction(); if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { - Thread thread = new Thread(mListener, MountListener.class.getName()); + /* + * Vold does not run in the simulator, so fake out a mounted + * event to trigger MediaScanner + */ + if ("simulator".equals(SystemProperties.get("ro.product.device"))) { + notifyMediaMounted( + Environment.getExternalStorageDirectory().getPath(), false); + return; + } + + Thread thread = new Thread( + mConnector, NativeDaemonConnector.class.getName()); thread.start(); } } @@ -258,7 +289,7 @@ class MountService extends IMountService.Stub { */ try { String m = Environment.getExternalStorageDirectory().toString(); - unmountMedia(m); + unmountVolume(m); int retries = 12; while (!state.equals(Environment.MEDIA_UNMOUNTED) && (retries-- >=0)) { @@ -302,17 +333,14 @@ class MountService extends IMountService.Stub { String vs = getVolumeState(vp); if (enable && vs.equals(Environment.MEDIA_MOUNTED)) { - mListener.unmountVolume(vp); + unmountVolume(vp); updateUsbMassStorageNotification(true, false); } - mListener.setShareMethodEnabled(Environment - .getExternalStorageDirectory() - .getPath(), - "ums", enable); + setShareMethodEnabled(vp, "ums", enable); mUmsEnabled = enable; if (!enable) { - mountMedia(vp); + mountVolume(vp); if (mPromptUms) { updateUsbMassStorageNotification(false, false); } else { @@ -352,19 +380,19 @@ class MountService extends IMountService.Stub { /** * Attempt to mount external media */ - public void mountMedia(String mountPath) throws IllegalStateException { + public void mountVolume(String mountPath) throws IllegalStateException { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires MOUNT_UNMOUNT_FILESYSTEMS permission"); } - mListener.mountVolume(mountPath); + mConnector.doCommand(String.format("mount %s", mountPath)); } /** * Attempt to unmount external media to prepare for eject */ - public void unmountMedia(String mountPath) throws IllegalStateException { + public void unmountVolume(String mountPath) throws IllegalStateException { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) != PackageManager.PERMISSION_GRANTED) { @@ -375,23 +403,51 @@ class MountService extends IMountService.Stub { // to display the notification mShowSafeUnmountNotificationWhenUnmounted = true; - // tell mountd to unmount the media - mListener.unmountVolume(mountPath); + mConnector.doCommand(String.format("unmount %s", mountPath)); } /** * Attempt to format external media */ - public void formatMedia(String formatPath) throws IllegalStateException { + public void formatVolume(String formatPath) throws IllegalStateException { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires MOUNT_FORMAT_FILESYSTEMS permission"); } - mListener.formatVolume(formatPath); + mConnector.doCommand(String.format("format %s", formatPath)); + } + + boolean getShareAvailable(String method) throws IllegalStateException { + ArrayList<String> rsp = mConnector.doCommand("share_available " + method); + + for (String line : rsp) { + String []tok = line.split(" "); + int code = Integer.parseInt(tok[0]); + if (code == VoldResponseCode.ShareAvailabilityResult) { + if (tok[2].equals("available")) + return true; + return false; + } else { + throw new IllegalStateException(String.format("Unexpected response code %d", code)); + } + } + throw new IllegalStateException("Got an empty response"); + } + + /** + * Enables or disables USB mass storage support. + * + * @param enable true to enable USB mass storage support + */ + void setShareMethodEnabled(String mountPoint, String method, + boolean enable) throws IllegalStateException { + mConnector.doCommand(String.format( + "%sshare %s %s", (enable ? "" : "un"), mountPoint, method)); } + /** * Returns true if we're playing media notification sounds. */ @@ -417,7 +473,7 @@ class MountService extends IMountService.Stub { Log.w(TAG, "Multiple volumes not currently supported"); return; } - Log.w(TAG, "State for {" + mountPoint + "} = {" + state + "}"); + Log.i(TAG, "State for {" + mountPoint + "} = {" + state + "}"); mLegacyState = state; } @@ -455,14 +511,18 @@ class MountService extends IMountService.Stub { } } - void onVoldConnected() { + /** + * + * Callback from NativeDaemonConnector + */ + public void onDaemonConnected() { new Thread() { public void run() { try { if (!getVolumeState(Environment.getExternalStorageDirectory().getPath()) .equals(Environment.MEDIA_MOUNTED)) { try { - mountMedia(Environment.getExternalStorageDirectory().getPath()); + mountVolume(Environment.getExternalStorageDirectory().getPath()); } catch (Exception ex) { Log.w(TAG, "Connection-mount failed"); } @@ -474,7 +534,7 @@ class MountService extends IMountService.Stub { } try { - boolean avail = mListener.getShareAvailable("ums"); + boolean avail = getShareAvailable("ums"); notifyShareAvailabilityChange("ums", avail); } catch (Exception ex) { Log.w(TAG, "Failed to get share availability"); @@ -483,6 +543,49 @@ class MountService extends IMountService.Stub { }.start(); } + /** + * + * Callback from NativeDaemonConnector + */ + public boolean onEvent(int code, String raw, String[] cooked) { + // Log.d(TAG, "event {" + raw + "}"); + if (code == VoldResponseCode.VolumeStateChange) { + // FMT: NNN Volume <label> <mountpoint> state changed + // from <old_#> (<old_str>) to <new_#> (<new_str>) + notifyVolumeStateChange( + cooked[2], cooked[3], Integer.parseInt(cooked[7]), + Integer.parseInt(cooked[10])); + } else if (code == VoldResponseCode.VolumeMountFailedBlank) { + // FMT: NNN Volume <label> <mountpoint> mount failed - no supported file-systems + notifyMediaNoFs(cooked[3]); + // FMT: NNN Volume <label> <mountpoint> mount failed - no media + } else if (code == VoldResponseCode.VolumeMountFailedNoMedia) { + notifyMediaRemoved(cooked[3]); + } else if (code == VoldResponseCode.VolumeMountFailedDamaged) { + // FMT: NNN Volume <label> <mountpoint> mount failed - filesystem check failed + notifyMediaUnmountable(cooked[3]); + } else if (code == VoldResponseCode.ShareAvailabilityChange) { + // FMT: NNN Share method <method> now <available|unavailable> + boolean avail = false; + if (cooked[5].equals("available")) { + avail = true; + } + notifyShareAvailabilityChange(cooked[3], avail); + } else if (code == VoldResponseCode.VolumeDiskInserted) { + // FMT: NNN Volume <label> <mountpoint> disk inserted (<major>:<minor>) + notifyMediaInserted(cooked[3]); + } else if (code == VoldResponseCode.VolumeDiskRemoved) { + // FMT: NNN Volume <label> <mountpoint> disk removed (<major>:<minor>) + notifyMediaRemoved(cooked[3]); + } else if (code == VoldResponseCode.VolumeBadRemoval) { + // FMT: NNN Volume <label> <mountpoint> bad removal (<major>:<minor>) + notifyMediaBadRemoval(cooked[3]); + } else { + return false; + } + return true; + } + void notifyVolumeStateChange(String label, String mountPoint, int oldState, int newState) throws IllegalStateException { String vs = getVolumeState(mountPoint); @@ -587,7 +690,7 @@ class MountService extends IMountService.Stub { new Thread() { public void run() { try { - mountMedia(path); + mountVolume(path); } catch (Exception ex) { Log.w(TAG, "Failed to mount media on insertion", ex); } @@ -903,29 +1006,62 @@ class MountService extends IMountService.Stub { } public String[] getSecureContainerList() throws IllegalStateException { - return mListener.listAsec(); + ArrayList<String> rsp = mConnector.doCommand("list_asec"); + + String[] rdata = new String[rsp.size()]; + int idx = 0; + + for (String line : rsp) { + String []tok = line.split(" "); + int code = Integer.parseInt(tok[0]); + if (code == VoldResponseCode.AsecListResult) { + rdata[idx++] = tok[1]; + } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) { + return rdata; + } else { + throw new IllegalStateException(String.format("Unexpected response code %d", code)); + } + } + throw new IllegalStateException("Got an empty response"); } public String createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid) throws IllegalStateException { - return mListener.createAsec(id, sizeMb, fstype, key, ownerUid); + String cmd = String.format("create_asec %s %d %s %s %d", + id, sizeMb, fstype, key, ownerUid); + mConnector.doCommand(cmd); + return getSecureContainerPath(id); } public void finalizeSecureContainer(String id) throws IllegalStateException { - mListener.finalizeAsec(id); + mConnector.doCommand(String.format("finalize_asec %s", id)); } public void destroySecureContainer(String id) throws IllegalStateException { - mListener.destroyAsec(id); + mConnector.doCommand(String.format("destroy_asec %s", id)); } - public String mountSecureContainer(String id, String key, int ownerUid) throws IllegalStateException { - return mListener.mountAsec(id, key, ownerUid); + public String mountSecureContainer(String id, String key, + int ownerUid) throws IllegalStateException { + String cmd = String.format("mount_asec %s %s %d", + id, key, ownerUid); + mConnector.doCommand(cmd); + return getSecureContainerPath(id); } public String getSecureContainerPath(String id) throws IllegalStateException { - return mListener.getAsecPath(id); - } + ArrayList<String> rsp = mConnector.doCommand("asec_path " + id); + for (String line : rsp) { + String []tok = line.split(" "); + int code = Integer.parseInt(tok[0]); + if (code == VoldResponseCode.AsecPathResult) { + return tok[1]; + } else { + throw new IllegalStateException(String.format("Unexpected response code %d", code)); + } + } + throw new IllegalStateException("Got an empty response"); + } } |