StorageManager.java revision 38cf8867a8d3e8d5159abd0bd0e6a3b0b8348b94
1b104340496e3a531e26c8f428c808eca0e039f50San Mehat/* 2b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Copyright (C) 2008 The Android Open Source Project 3b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 4b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5b104340496e3a531e26c8f428c808eca0e039f50San Mehat * you may not use this file except in compliance with the License. 6b104340496e3a531e26c8f428c808eca0e039f50San Mehat * You may obtain a copy of the License at 7b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 8b104340496e3a531e26c8f428c808eca0e039f50San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 10b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Unless required by applicable law or agreed to in writing, software 11b104340496e3a531e26c8f428c808eca0e039f50San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12b104340496e3a531e26c8f428c808eca0e039f50San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b104340496e3a531e26c8f428c808eca0e039f50San Mehat * See the License for the specific language governing permissions and 14b104340496e3a531e26c8f428c808eca0e039f50San Mehat * limitations under the License. 15b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 16b104340496e3a531e26c8f428c808eca0e039f50San Mehat 17b104340496e3a531e26c8f428c808eca0e039f50San Mehatpackage android.os.storage; 18b104340496e3a531e26c8f428c808eca0e039f50San Mehat 19b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.Handler; 20a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Rootimport android.os.Looper; 21b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.Message; 22a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Rootimport android.os.RemoteException; 23b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.ServiceManager; 24b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.util.Log; 25b104340496e3a531e26c8f428c808eca0e039f50San Mehat 2605105f7abe02b2dff91d6260b3628c8b97816babKenny Rootimport java.lang.ref.WeakReference; 27b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport java.util.ArrayList; 2805105f7abe02b2dff91d6260b3628c8b97816babKenny Rootimport java.util.Iterator; 2905105f7abe02b2dff91d6260b3628c8b97816babKenny Rootimport java.util.LinkedList; 3005105f7abe02b2dff91d6260b3628c8b97816babKenny Rootimport java.util.List; 31b104340496e3a531e26c8f428c808eca0e039f50San Mehat 32b104340496e3a531e26c8f428c808eca0e039f50San Mehat/** 3305105f7abe02b2dff91d6260b3628c8b97816babKenny Root * StorageManager is the interface to the systems storage service. The storage 3405105f7abe02b2dff91d6260b3628c8b97816babKenny Root * manager handles storage-related items such as Opaque Binary Blobs (OBBs). 3505105f7abe02b2dff91d6260b3628c8b97816babKenny Root * <p> 3605105f7abe02b2dff91d6260b3628c8b97816babKenny Root * OBBs contain a filesystem that maybe be encrypted on disk and mounted 3705105f7abe02b2dff91d6260b3628c8b97816babKenny Root * on-demand from an application. OBBs are a good way of providing large amounts 3805105f7abe02b2dff91d6260b3628c8b97816babKenny Root * of binary assets without packaging them into APKs as they may be multiple 3905105f7abe02b2dff91d6260b3628c8b97816babKenny Root * gigabytes in size. However, due to their size, they're most likely stored in 4005105f7abe02b2dff91d6260b3628c8b97816babKenny Root * a shared storage pool accessible from all programs. The system does not 4105105f7abe02b2dff91d6260b3628c8b97816babKenny Root * guarantee the security of the OBB file itself: if any program modifies the 4205105f7abe02b2dff91d6260b3628c8b97816babKenny Root * OBB, there is no guarantee that a read from that OBB will produce the 4305105f7abe02b2dff91d6260b3628c8b97816babKenny Root * expected output. 4405105f7abe02b2dff91d6260b3628c8b97816babKenny Root * <p> 45b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Get an instance of this class by calling 4605105f7abe02b2dff91d6260b3628c8b97816babKenny Root * {@link android.content.Context#getSystemService(java.lang.String)} with an 4705105f7abe02b2dff91d6260b3628c8b97816babKenny Root * argument of {@link android.content.Context#STORAGE_SERVICE}. 48b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 49b104340496e3a531e26c8f428c808eca0e039f50San Mehat 50b104340496e3a531e26c8f428c808eca0e039f50San Mehatpublic class StorageManager 51b104340496e3a531e26c8f428c808eca0e039f50San Mehat{ 52b104340496e3a531e26c8f428c808eca0e039f50San Mehat private static final String TAG = "StorageManager"; 53b104340496e3a531e26c8f428c808eca0e039f50San Mehat 54b104340496e3a531e26c8f428c808eca0e039f50San Mehat /* 55b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Our internal MountService binder reference 56b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 57b104340496e3a531e26c8f428c808eca0e039f50San Mehat private IMountService mMountService; 58b104340496e3a531e26c8f428c808eca0e039f50San Mehat 59b104340496e3a531e26c8f428c808eca0e039f50San Mehat /* 60b104340496e3a531e26c8f428c808eca0e039f50San Mehat * The looper target for callbacks 61b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 62b104340496e3a531e26c8f428c808eca0e039f50San Mehat Looper mTgtLooper; 63b104340496e3a531e26c8f428c808eca0e039f50San Mehat 64b104340496e3a531e26c8f428c808eca0e039f50San Mehat /* 65b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Target listener for binder callbacks 66b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 67b104340496e3a531e26c8f428c808eca0e039f50San Mehat private MountServiceBinderListener mBinderListener; 68b104340496e3a531e26c8f428c808eca0e039f50San Mehat 69b104340496e3a531e26c8f428c808eca0e039f50San Mehat /* 70b104340496e3a531e26c8f428c808eca0e039f50San Mehat * List of our listeners 71b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 72b104340496e3a531e26c8f428c808eca0e039f50San Mehat private ArrayList<ListenerDelegate> mListeners = new ArrayList<ListenerDelegate>(); 73b104340496e3a531e26c8f428c808eca0e039f50San Mehat 74b104340496e3a531e26c8f428c808eca0e039f50San Mehat private class MountServiceBinderListener extends IMountServiceListener.Stub { 75b104340496e3a531e26c8f428c808eca0e039f50San Mehat public void onUsbMassStorageConnectionChanged(boolean available) { 76b104340496e3a531e26c8f428c808eca0e039f50San Mehat final int size = mListeners.size(); 77b104340496e3a531e26c8f428c808eca0e039f50San Mehat for (int i = 0; i < size; i++) { 78b104340496e3a531e26c8f428c808eca0e039f50San Mehat mListeners.get(i).sendShareAvailabilityChanged(available); 79b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 80b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 81b104340496e3a531e26c8f428c808eca0e039f50San Mehat 82b104340496e3a531e26c8f428c808eca0e039f50San Mehat public void onStorageStateChanged(String path, String oldState, String newState) { 83b104340496e3a531e26c8f428c808eca0e039f50San Mehat final int size = mListeners.size(); 84b104340496e3a531e26c8f428c808eca0e039f50San Mehat for (int i = 0; i < size; i++) { 85b104340496e3a531e26c8f428c808eca0e039f50San Mehat mListeners.get(i).sendStorageStateChanged(path, oldState, newState); 86b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 87b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 88b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 89b104340496e3a531e26c8f428c808eca0e039f50San Mehat 90b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 91a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * Binder listener for OBB action results. 92a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root */ 9305105f7abe02b2dff91d6260b3628c8b97816babKenny Root private final ObbActionListener mObbActionListener = new ObbActionListener(); 9405105f7abe02b2dff91d6260b3628c8b97816babKenny Root 9505105f7abe02b2dff91d6260b3628c8b97816babKenny Root private class ObbActionListener extends IObbActionListener.Stub { 9605105f7abe02b2dff91d6260b3628c8b97816babKenny Root private List<WeakReference<ObbListenerDelegate>> mListeners = new LinkedList<WeakReference<ObbListenerDelegate>>(); 9705105f7abe02b2dff91d6260b3628c8b97816babKenny Root 98a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root @Override 99a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root public void onObbResult(String filename, String status) throws RemoteException { 10005105f7abe02b2dff91d6260b3628c8b97816babKenny Root synchronized (mListeners) { 10105105f7abe02b2dff91d6260b3628c8b97816babKenny Root final Iterator<WeakReference<ObbListenerDelegate>> iter = mListeners.iterator(); 10205105f7abe02b2dff91d6260b3628c8b97816babKenny Root while (iter.hasNext()) { 10305105f7abe02b2dff91d6260b3628c8b97816babKenny Root final WeakReference<ObbListenerDelegate> ref = iter.next(); 10405105f7abe02b2dff91d6260b3628c8b97816babKenny Root 10505105f7abe02b2dff91d6260b3628c8b97816babKenny Root final ObbListenerDelegate delegate = (ref == null) ? null : ref.get(); 10605105f7abe02b2dff91d6260b3628c8b97816babKenny Root if (delegate == null) { 10705105f7abe02b2dff91d6260b3628c8b97816babKenny Root iter.remove(); 10805105f7abe02b2dff91d6260b3628c8b97816babKenny Root continue; 10905105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 11005105f7abe02b2dff91d6260b3628c8b97816babKenny Root 11105105f7abe02b2dff91d6260b3628c8b97816babKenny Root delegate.sendObbStateChanged(filename, status); 11205105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 11305105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 11405105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 11505105f7abe02b2dff91d6260b3628c8b97816babKenny Root 11605105f7abe02b2dff91d6260b3628c8b97816babKenny Root public void addListener(OnObbStateChangeListener listener) { 11705105f7abe02b2dff91d6260b3628c8b97816babKenny Root if (listener == null) { 11805105f7abe02b2dff91d6260b3628c8b97816babKenny Root return; 11905105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 12005105f7abe02b2dff91d6260b3628c8b97816babKenny Root 12105105f7abe02b2dff91d6260b3628c8b97816babKenny Root synchronized (mListeners) { 12205105f7abe02b2dff91d6260b3628c8b97816babKenny Root final Iterator<WeakReference<ObbListenerDelegate>> iter = mListeners.iterator(); 12305105f7abe02b2dff91d6260b3628c8b97816babKenny Root while (iter.hasNext()) { 12405105f7abe02b2dff91d6260b3628c8b97816babKenny Root final WeakReference<ObbListenerDelegate> ref = iter.next(); 12505105f7abe02b2dff91d6260b3628c8b97816babKenny Root 12605105f7abe02b2dff91d6260b3628c8b97816babKenny Root final ObbListenerDelegate delegate = (ref == null) ? null : ref.get(); 12705105f7abe02b2dff91d6260b3628c8b97816babKenny Root if (delegate == null) { 12805105f7abe02b2dff91d6260b3628c8b97816babKenny Root iter.remove(); 12905105f7abe02b2dff91d6260b3628c8b97816babKenny Root continue; 13005105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 13105105f7abe02b2dff91d6260b3628c8b97816babKenny Root 13205105f7abe02b2dff91d6260b3628c8b97816babKenny Root /* 13305105f7abe02b2dff91d6260b3628c8b97816babKenny Root * If we're already in the listeners, we don't need to be in 13405105f7abe02b2dff91d6260b3628c8b97816babKenny Root * there again. 13505105f7abe02b2dff91d6260b3628c8b97816babKenny Root */ 13605105f7abe02b2dff91d6260b3628c8b97816babKenny Root if (listener.equals(delegate.getListener())) { 13705105f7abe02b2dff91d6260b3628c8b97816babKenny Root return; 13805105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 13905105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 14005105f7abe02b2dff91d6260b3628c8b97816babKenny Root 14105105f7abe02b2dff91d6260b3628c8b97816babKenny Root final ObbListenerDelegate delegate = new ObbListenerDelegate(listener); 14205105f7abe02b2dff91d6260b3628c8b97816babKenny Root mListeners.add(new WeakReference<ObbListenerDelegate>(delegate)); 14305105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 14405105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 14505105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 14605105f7abe02b2dff91d6260b3628c8b97816babKenny Root 14705105f7abe02b2dff91d6260b3628c8b97816babKenny Root /** 14805105f7abe02b2dff91d6260b3628c8b97816babKenny Root * Private class containing sender and receiver code for StorageEvents. 14905105f7abe02b2dff91d6260b3628c8b97816babKenny Root */ 15005105f7abe02b2dff91d6260b3628c8b97816babKenny Root private class ObbListenerDelegate { 15105105f7abe02b2dff91d6260b3628c8b97816babKenny Root private final WeakReference<OnObbStateChangeListener> mObbEventListenerRef; 15205105f7abe02b2dff91d6260b3628c8b97816babKenny Root private final Handler mHandler; 15305105f7abe02b2dff91d6260b3628c8b97816babKenny Root 15405105f7abe02b2dff91d6260b3628c8b97816babKenny Root ObbListenerDelegate(OnObbStateChangeListener listener) { 15505105f7abe02b2dff91d6260b3628c8b97816babKenny Root mObbEventListenerRef = new WeakReference<OnObbStateChangeListener>(listener); 15605105f7abe02b2dff91d6260b3628c8b97816babKenny Root mHandler = new Handler(mTgtLooper) { 15705105f7abe02b2dff91d6260b3628c8b97816babKenny Root @Override 15805105f7abe02b2dff91d6260b3628c8b97816babKenny Root public void handleMessage(Message msg) { 15905105f7abe02b2dff91d6260b3628c8b97816babKenny Root final OnObbStateChangeListener listener = getListener(); 16005105f7abe02b2dff91d6260b3628c8b97816babKenny Root if (listener == null) { 16105105f7abe02b2dff91d6260b3628c8b97816babKenny Root return; 16205105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 16305105f7abe02b2dff91d6260b3628c8b97816babKenny Root 16405105f7abe02b2dff91d6260b3628c8b97816babKenny Root StorageEvent e = (StorageEvent) msg.obj; 16505105f7abe02b2dff91d6260b3628c8b97816babKenny Root 16605105f7abe02b2dff91d6260b3628c8b97816babKenny Root if (msg.what == StorageEvent.EVENT_OBB_STATE_CHANGED) { 16705105f7abe02b2dff91d6260b3628c8b97816babKenny Root ObbStateChangedStorageEvent ev = (ObbStateChangedStorageEvent) e; 16805105f7abe02b2dff91d6260b3628c8b97816babKenny Root listener.onObbStateChange(ev.path, ev.state); 16905105f7abe02b2dff91d6260b3628c8b97816babKenny Root } else { 17005105f7abe02b2dff91d6260b3628c8b97816babKenny Root Log.e(TAG, "Unsupported event " + msg.what); 17105105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 17205105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 17305105f7abe02b2dff91d6260b3628c8b97816babKenny Root }; 17405105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 17505105f7abe02b2dff91d6260b3628c8b97816babKenny Root 17605105f7abe02b2dff91d6260b3628c8b97816babKenny Root OnObbStateChangeListener getListener() { 17705105f7abe02b2dff91d6260b3628c8b97816babKenny Root if (mObbEventListenerRef == null) { 17805105f7abe02b2dff91d6260b3628c8b97816babKenny Root return null; 17905105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 18005105f7abe02b2dff91d6260b3628c8b97816babKenny Root return mObbEventListenerRef.get(); 18105105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 18205105f7abe02b2dff91d6260b3628c8b97816babKenny Root 18305105f7abe02b2dff91d6260b3628c8b97816babKenny Root void sendObbStateChanged(String path, String state) { 18405105f7abe02b2dff91d6260b3628c8b97816babKenny Root ObbStateChangedStorageEvent e = new ObbStateChangedStorageEvent(path, state); 18505105f7abe02b2dff91d6260b3628c8b97816babKenny Root mHandler.sendMessage(e.getMessage()); 18605105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 18705105f7abe02b2dff91d6260b3628c8b97816babKenny Root } 18805105f7abe02b2dff91d6260b3628c8b97816babKenny Root 18905105f7abe02b2dff91d6260b3628c8b97816babKenny Root /** 19005105f7abe02b2dff91d6260b3628c8b97816babKenny Root * Message sent during an OBB status change event. 19105105f7abe02b2dff91d6260b3628c8b97816babKenny Root */ 19205105f7abe02b2dff91d6260b3628c8b97816babKenny Root private class ObbStateChangedStorageEvent extends StorageEvent { 19305105f7abe02b2dff91d6260b3628c8b97816babKenny Root public final String path; 19405105f7abe02b2dff91d6260b3628c8b97816babKenny Root public final String state; 19505105f7abe02b2dff91d6260b3628c8b97816babKenny Root 19605105f7abe02b2dff91d6260b3628c8b97816babKenny Root public ObbStateChangedStorageEvent(String path, String state) { 19705105f7abe02b2dff91d6260b3628c8b97816babKenny Root super(EVENT_OBB_STATE_CHANGED); 19805105f7abe02b2dff91d6260b3628c8b97816babKenny Root this.path = path; 19905105f7abe02b2dff91d6260b3628c8b97816babKenny Root this.state = state; 200a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root } 201a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root } 202a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root 203a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root /** 204b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Private base class for messages sent between the callback thread 205b104340496e3a531e26c8f428c808eca0e039f50San Mehat * and the target looper handler. 206b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 207b104340496e3a531e26c8f428c808eca0e039f50San Mehat private class StorageEvent { 20805105f7abe02b2dff91d6260b3628c8b97816babKenny Root static final int EVENT_UMS_CONNECTION_CHANGED = 1; 20905105f7abe02b2dff91d6260b3628c8b97816babKenny Root static final int EVENT_STORAGE_STATE_CHANGED = 2; 21005105f7abe02b2dff91d6260b3628c8b97816babKenny Root static final int EVENT_OBB_STATE_CHANGED = 3; 211b104340496e3a531e26c8f428c808eca0e039f50San Mehat 212b104340496e3a531e26c8f428c808eca0e039f50San Mehat private Message mMessage; 213b104340496e3a531e26c8f428c808eca0e039f50San Mehat 214b104340496e3a531e26c8f428c808eca0e039f50San Mehat public StorageEvent(int what) { 215b104340496e3a531e26c8f428c808eca0e039f50San Mehat mMessage = Message.obtain(); 216b104340496e3a531e26c8f428c808eca0e039f50San Mehat mMessage.what = what; 217b104340496e3a531e26c8f428c808eca0e039f50San Mehat mMessage.obj = this; 218b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 219b104340496e3a531e26c8f428c808eca0e039f50San Mehat 220b104340496e3a531e26c8f428c808eca0e039f50San Mehat public Message getMessage() { 221b104340496e3a531e26c8f428c808eca0e039f50San Mehat return mMessage; 222b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 223b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 224b104340496e3a531e26c8f428c808eca0e039f50San Mehat 225b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 226b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Message sent on a USB mass storage connection change. 227b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 228b104340496e3a531e26c8f428c808eca0e039f50San Mehat private class UmsConnectionChangedStorageEvent extends StorageEvent { 229b104340496e3a531e26c8f428c808eca0e039f50San Mehat public boolean available; 230b104340496e3a531e26c8f428c808eca0e039f50San Mehat 231b104340496e3a531e26c8f428c808eca0e039f50San Mehat public UmsConnectionChangedStorageEvent(boolean a) { 232b104340496e3a531e26c8f428c808eca0e039f50San Mehat super(EVENT_UMS_CONNECTION_CHANGED); 233b104340496e3a531e26c8f428c808eca0e039f50San Mehat available = a; 234b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 235b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 236b104340496e3a531e26c8f428c808eca0e039f50San Mehat 237b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 238b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Message sent on volume state change. 239b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 240b104340496e3a531e26c8f428c808eca0e039f50San Mehat private class StorageStateChangedStorageEvent extends StorageEvent { 241b104340496e3a531e26c8f428c808eca0e039f50San Mehat public String path; 242b104340496e3a531e26c8f428c808eca0e039f50San Mehat public String oldState; 243b104340496e3a531e26c8f428c808eca0e039f50San Mehat public String newState; 244b104340496e3a531e26c8f428c808eca0e039f50San Mehat 245b104340496e3a531e26c8f428c808eca0e039f50San Mehat public StorageStateChangedStorageEvent(String p, String oldS, String newS) { 246b104340496e3a531e26c8f428c808eca0e039f50San Mehat super(EVENT_STORAGE_STATE_CHANGED); 247b104340496e3a531e26c8f428c808eca0e039f50San Mehat path = p; 248b104340496e3a531e26c8f428c808eca0e039f50San Mehat oldState = oldS; 249b104340496e3a531e26c8f428c808eca0e039f50San Mehat newState = newS; 250b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 251b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 252b104340496e3a531e26c8f428c808eca0e039f50San Mehat 253b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 254b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Private class containing sender and receiver code for StorageEvents. 255b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 256b104340496e3a531e26c8f428c808eca0e039f50San Mehat private class ListenerDelegate { 257b104340496e3a531e26c8f428c808eca0e039f50San Mehat final StorageEventListener mStorageEventListener; 258b104340496e3a531e26c8f428c808eca0e039f50San Mehat private final Handler mHandler; 259b104340496e3a531e26c8f428c808eca0e039f50San Mehat 260b104340496e3a531e26c8f428c808eca0e039f50San Mehat ListenerDelegate(StorageEventListener listener) { 261b104340496e3a531e26c8f428c808eca0e039f50San Mehat mStorageEventListener = listener; 262b104340496e3a531e26c8f428c808eca0e039f50San Mehat mHandler = new Handler(mTgtLooper) { 263b104340496e3a531e26c8f428c808eca0e039f50San Mehat @Override 264b104340496e3a531e26c8f428c808eca0e039f50San Mehat public void handleMessage(Message msg) { 265b104340496e3a531e26c8f428c808eca0e039f50San Mehat StorageEvent e = (StorageEvent) msg.obj; 266b104340496e3a531e26c8f428c808eca0e039f50San Mehat 267b104340496e3a531e26c8f428c808eca0e039f50San Mehat if (msg.what == StorageEvent.EVENT_UMS_CONNECTION_CHANGED) { 268b104340496e3a531e26c8f428c808eca0e039f50San Mehat UmsConnectionChangedStorageEvent ev = (UmsConnectionChangedStorageEvent) e; 269b104340496e3a531e26c8f428c808eca0e039f50San Mehat mStorageEventListener.onUsbMassStorageConnectionChanged(ev.available); 270b104340496e3a531e26c8f428c808eca0e039f50San Mehat } else if (msg.what == StorageEvent.EVENT_STORAGE_STATE_CHANGED) { 271b104340496e3a531e26c8f428c808eca0e039f50San Mehat StorageStateChangedStorageEvent ev = (StorageStateChangedStorageEvent) e; 272b104340496e3a531e26c8f428c808eca0e039f50San Mehat mStorageEventListener.onStorageStateChanged(ev.path, ev.oldState, ev.newState); 273b104340496e3a531e26c8f428c808eca0e039f50San Mehat } else { 274b104340496e3a531e26c8f428c808eca0e039f50San Mehat Log.e(TAG, "Unsupported event " + msg.what); 275b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 276b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 277b104340496e3a531e26c8f428c808eca0e039f50San Mehat }; 278b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 279b104340496e3a531e26c8f428c808eca0e039f50San Mehat 280b104340496e3a531e26c8f428c808eca0e039f50San Mehat StorageEventListener getListener() { 281b104340496e3a531e26c8f428c808eca0e039f50San Mehat return mStorageEventListener; 282b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 283b104340496e3a531e26c8f428c808eca0e039f50San Mehat 284b104340496e3a531e26c8f428c808eca0e039f50San Mehat void sendShareAvailabilityChanged(boolean available) { 285b104340496e3a531e26c8f428c808eca0e039f50San Mehat UmsConnectionChangedStorageEvent e = new UmsConnectionChangedStorageEvent(available); 286b104340496e3a531e26c8f428c808eca0e039f50San Mehat mHandler.sendMessage(e.getMessage()); 287b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 288b104340496e3a531e26c8f428c808eca0e039f50San Mehat 289b104340496e3a531e26c8f428c808eca0e039f50San Mehat void sendStorageStateChanged(String path, String oldState, String newState) { 290b104340496e3a531e26c8f428c808eca0e039f50San Mehat StorageStateChangedStorageEvent e = new StorageStateChangedStorageEvent(path, oldState, newState); 291b104340496e3a531e26c8f428c808eca0e039f50San Mehat mHandler.sendMessage(e.getMessage()); 292b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 293b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 294b104340496e3a531e26c8f428c808eca0e039f50San Mehat 295b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 296b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Constructs a StorageManager object through which an application can 297b104340496e3a531e26c8f428c808eca0e039f50San Mehat * can communicate with the systems mount service. 298b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 299b104340496e3a531e26c8f428c808eca0e039f50San Mehat * @param tgtLooper The {@android.os.Looper} which events will be received on. 300b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 301b104340496e3a531e26c8f428c808eca0e039f50San Mehat * <p>Applications can get instance of this class by calling 302b104340496e3a531e26c8f428c808eca0e039f50San Mehat * {@link android.content.Context#getSystemService(java.lang.String)} with an argument 303b104340496e3a531e26c8f428c808eca0e039f50San Mehat * of {@link android.content.Context#STORAGE_SERVICE}. 304b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 305b104340496e3a531e26c8f428c808eca0e039f50San Mehat * @hide 306b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 307b104340496e3a531e26c8f428c808eca0e039f50San Mehat public StorageManager(Looper tgtLooper) throws RemoteException { 308b104340496e3a531e26c8f428c808eca0e039f50San Mehat mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount")); 309b104340496e3a531e26c8f428c808eca0e039f50San Mehat if (mMountService == null) { 310b104340496e3a531e26c8f428c808eca0e039f50San Mehat Log.e(TAG, "Unable to connect to mount service! - is it running yet?"); 311b104340496e3a531e26c8f428c808eca0e039f50San Mehat return; 312b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 313b104340496e3a531e26c8f428c808eca0e039f50San Mehat mTgtLooper = tgtLooper; 314b104340496e3a531e26c8f428c808eca0e039f50San Mehat mBinderListener = new MountServiceBinderListener(); 315b104340496e3a531e26c8f428c808eca0e039f50San Mehat mMountService.registerListener(mBinderListener); 316b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 317b104340496e3a531e26c8f428c808eca0e039f50San Mehat 318b104340496e3a531e26c8f428c808eca0e039f50San Mehat 319b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 320b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Registers a {@link android.os.storage.StorageEventListener StorageEventListener}. 321b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 322b104340496e3a531e26c8f428c808eca0e039f50San Mehat * @param listener A {@link android.os.storage.StorageEventListener StorageEventListener} object. 323b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 32402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * @hide 325b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 326b104340496e3a531e26c8f428c808eca0e039f50San Mehat public void registerListener(StorageEventListener listener) { 327b104340496e3a531e26c8f428c808eca0e039f50San Mehat if (listener == null) { 328b104340496e3a531e26c8f428c808eca0e039f50San Mehat return; 329b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 330b104340496e3a531e26c8f428c808eca0e039f50San Mehat 331b104340496e3a531e26c8f428c808eca0e039f50San Mehat synchronized (mListeners) { 332b104340496e3a531e26c8f428c808eca0e039f50San Mehat mListeners.add(new ListenerDelegate(listener)); 333b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 334b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 335b104340496e3a531e26c8f428c808eca0e039f50San Mehat 336b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 337b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Unregisters a {@link android.os.storage.StorageEventListener StorageEventListener}. 338b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 339b104340496e3a531e26c8f428c808eca0e039f50San Mehat * @param listener A {@link android.os.storage.StorageEventListener StorageEventListener} object. 340b104340496e3a531e26c8f428c808eca0e039f50San Mehat * 34102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * @hide 342b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 343b104340496e3a531e26c8f428c808eca0e039f50San Mehat public void unregisterListener(StorageEventListener listener) { 344b104340496e3a531e26c8f428c808eca0e039f50San Mehat if (listener == null) { 345b104340496e3a531e26c8f428c808eca0e039f50San Mehat return; 346b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 347b104340496e3a531e26c8f428c808eca0e039f50San Mehat 348b104340496e3a531e26c8f428c808eca0e039f50San Mehat synchronized (mListeners) { 349b104340496e3a531e26c8f428c808eca0e039f50San Mehat final int size = mListeners.size(); 350b104340496e3a531e26c8f428c808eca0e039f50San Mehat for (int i=0 ; i<size ; i++) { 351b104340496e3a531e26c8f428c808eca0e039f50San Mehat ListenerDelegate l = mListeners.get(i); 352b104340496e3a531e26c8f428c808eca0e039f50San Mehat if (l.getListener() == listener) { 353b104340496e3a531e26c8f428c808eca0e039f50San Mehat mListeners.remove(i); 354b104340496e3a531e26c8f428c808eca0e039f50San Mehat break; 355b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 356b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 357b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 358b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 359b104340496e3a531e26c8f428c808eca0e039f50San Mehat 360b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 361b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Enables USB Mass Storage (UMS) on the device. 36202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * 36302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * @hide 364b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 3650eec21d97d9dc4eb4fdbad0e4c0fc53703452d02Suchi Amalapurapu public void enableUsbMassStorage() { 366b104340496e3a531e26c8f428c808eca0e039f50San Mehat try { 3670eec21d97d9dc4eb4fdbad0e4c0fc53703452d02Suchi Amalapurapu mMountService.setUsbMassStorageEnabled(true); 368b104340496e3a531e26c8f428c808eca0e039f50San Mehat } catch (Exception ex) { 369b104340496e3a531e26c8f428c808eca0e039f50San Mehat Log.e(TAG, "Failed to enable UMS", ex); 370b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 371b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 372b104340496e3a531e26c8f428c808eca0e039f50San Mehat 373b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 374b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Disables USB Mass Storage (UMS) on the device. 37502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * 37602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * @hide 377b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 3780eec21d97d9dc4eb4fdbad0e4c0fc53703452d02Suchi Amalapurapu public void disableUsbMassStorage() { 379b104340496e3a531e26c8f428c808eca0e039f50San Mehat try { 3800eec21d97d9dc4eb4fdbad0e4c0fc53703452d02Suchi Amalapurapu mMountService.setUsbMassStorageEnabled(false); 381b104340496e3a531e26c8f428c808eca0e039f50San Mehat } catch (Exception ex) { 382b104340496e3a531e26c8f428c808eca0e039f50San Mehat Log.e(TAG, "Failed to disable UMS", ex); 383b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 384b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 385b104340496e3a531e26c8f428c808eca0e039f50San Mehat 386b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 387b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Query if a USB Mass Storage (UMS) host is connected. 388b104340496e3a531e26c8f428c808eca0e039f50San Mehat * @return true if UMS host is connected. 38902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * 39002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * @hide 391b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 392b104340496e3a531e26c8f428c808eca0e039f50San Mehat public boolean isUsbMassStorageConnected() { 393b104340496e3a531e26c8f428c808eca0e039f50San Mehat try { 394b104340496e3a531e26c8f428c808eca0e039f50San Mehat return mMountService.isUsbMassStorageConnected(); 395b104340496e3a531e26c8f428c808eca0e039f50San Mehat } catch (Exception ex) { 396b104340496e3a531e26c8f428c808eca0e039f50San Mehat Log.e(TAG, "Failed to get UMS connection state", ex); 397b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 398b104340496e3a531e26c8f428c808eca0e039f50San Mehat return false; 399b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 400b104340496e3a531e26c8f428c808eca0e039f50San Mehat 401b104340496e3a531e26c8f428c808eca0e039f50San Mehat /** 402b104340496e3a531e26c8f428c808eca0e039f50San Mehat * Query if a USB Mass Storage (UMS) is enabled on the device. 403b104340496e3a531e26c8f428c808eca0e039f50San Mehat * @return true if UMS host is enabled. 40402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * 40502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root * @hide 406b104340496e3a531e26c8f428c808eca0e039f50San Mehat */ 407b104340496e3a531e26c8f428c808eca0e039f50San Mehat public boolean isUsbMassStorageEnabled() { 408b104340496e3a531e26c8f428c808eca0e039f50San Mehat try { 409b104340496e3a531e26c8f428c808eca0e039f50San Mehat return mMountService.isUsbMassStorageEnabled(); 410b104340496e3a531e26c8f428c808eca0e039f50San Mehat } catch (RemoteException rex) { 411b104340496e3a531e26c8f428c808eca0e039f50San Mehat Log.e(TAG, "Failed to get UMS enable state", rex); 412b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 413b104340496e3a531e26c8f428c808eca0e039f50San Mehat return false; 414b104340496e3a531e26c8f428c808eca0e039f50San Mehat } 41502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root 41602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root /** 417a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * Mount an Opaque Binary Blob (OBB) file. If a <code>key</code> is 418a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * specified, it is supplied to the mounting process to be used in any 419a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * encryption used in the OBB. 420a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * <p> 42105105f7abe02b2dff91d6260b3628c8b97816babKenny Root * The OBB will remain mounted for as long as the StorageManager reference 42205105f7abe02b2dff91d6260b3628c8b97816babKenny Root * is held by the application. As soon as this reference is lost, the OBBs 42305105f7abe02b2dff91d6260b3628c8b97816babKenny Root * in use will be unmounted. The {@link OnObbStateChangeListener} registered with 42405105f7abe02b2dff91d6260b3628c8b97816babKenny Root * this call will receive all further OBB-related events until it goes out 42505105f7abe02b2dff91d6260b3628c8b97816babKenny Root * of scope. If the caller is not interested in whether the call succeeds, 42605105f7abe02b2dff91d6260b3628c8b97816babKenny Root * the <code>listener</code> may be specified as <code>null</code>. 42705105f7abe02b2dff91d6260b3628c8b97816babKenny Root * <p> 428a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * <em>Note:</em> you can only mount OBB files for which the OBB tag on the 429a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * file matches a package ID that is owned by the calling program's UID. 43005105f7abe02b2dff91d6260b3628c8b97816babKenny Root * That is, shared UID applications can attempt to mount any other 431a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * application's OBB that shares its UID. 432a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * 433a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @param filename the path to the OBB file 43405105f7abe02b2dff91d6260b3628c8b97816babKenny Root * @param key secret used to encrypt the OBB; may be <code>null</code> if no 43505105f7abe02b2dff91d6260b3628c8b97816babKenny Root * encryption was used on the OBB. 436a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @return whether the mount call was successfully queued or not 43702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root */ 43805105f7abe02b2dff91d6260b3628c8b97816babKenny Root public boolean mountObb(String filename, String key, OnObbStateChangeListener listener) { 43902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root try { 44005105f7abe02b2dff91d6260b3628c8b97816babKenny Root mObbActionListener.addListener(listener); 441a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root mMountService.mountObb(filename, key, mObbActionListener); 442a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root return true; 44302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } catch (RemoteException e) { 44402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root Log.e(TAG, "Failed to mount OBB", e); 44502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } 44602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root 44702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root return false; 44802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } 44902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root 45002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root /** 45105105f7abe02b2dff91d6260b3628c8b97816babKenny Root * Unmount an Opaque Binary Blob (OBB) file asynchronously. If the 45205105f7abe02b2dff91d6260b3628c8b97816babKenny Root * <code>force</code> flag is true, it will kill any application needed to 45305105f7abe02b2dff91d6260b3628c8b97816babKenny Root * unmount the given OBB (even the calling application). 45405105f7abe02b2dff91d6260b3628c8b97816babKenny Root * <p> 45505105f7abe02b2dff91d6260b3628c8b97816babKenny Root * The {@link OnObbStateChangeListener} registered with this call will receive all 45605105f7abe02b2dff91d6260b3628c8b97816babKenny Root * further OBB-related events until it goes out of scope. If the caller is 45705105f7abe02b2dff91d6260b3628c8b97816babKenny Root * not interested in whether the call succeeded, the listener may be 45805105f7abe02b2dff91d6260b3628c8b97816babKenny Root * specified as <code>null</code>. 459a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * <p> 460a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * <em>Note:</em> you can only mount OBB files for which the OBB tag on the 461a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * file matches a package ID that is owned by the calling program's UID. 462a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * That is, shared UID applications can obtain access to any other 463a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * application's OBB that shares its UID. 46402ca31fbae9f35dd30f79de6927fae11b549391aKenny Root * <p> 465a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * 466a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @param filename path to the OBB file 467a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @param force whether to kill any programs using this in order to unmount 468a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * it 469a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @return whether the unmount call was successfully queued or not 47002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root */ 47138cf8867a8d3e8d5159abd0bd0e6a3b0b8348b94Kenny Root public boolean unmountObb(String filename, boolean force, OnObbStateChangeListener listener) { 47202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root try { 47305105f7abe02b2dff91d6260b3628c8b97816babKenny Root mObbActionListener.addListener(listener); 474a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root mMountService.unmountObb(filename, force, mObbActionListener); 475a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root return true; 47602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } catch (RemoteException e) { 47702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root Log.e(TAG, "Failed to mount OBB", e); 47802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } 47902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root 48002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root return false; 48102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } 48202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root 483a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root /** 484a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * Check whether an Opaque Binary Blob (OBB) is mounted or not. 485a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * 486a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @param filename path to OBB image 487a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @return true if OBB is mounted; false if not mounted or on error 488a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root */ 489a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root public boolean isObbMounted(String filename) throws IllegalArgumentException { 49002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root try { 49102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root return mMountService.isObbMounted(filename); 49202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } catch (RemoteException e) { 49302c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root Log.e(TAG, "Failed to check if OBB is mounted", e); 49402c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } 49502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root 49602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root return false; 49702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } 49802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root 49902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root /** 500a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * Check the mounted path of an Opaque Binary Blob (OBB) file. This will 501a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * give you the path to where you can obtain access to the internals of the 502a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * OBB. 503a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * 504a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @param filename path to OBB image 505a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * @return absolute path to mounted OBB image data or <code>null</code> if 506a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root * not mounted or exception encountered trying to read status 50702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root */ 50802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root public String getMountedObbPath(String filename) { 50902c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root try { 51002c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root return mMountService.getMountedObbPath(filename); 51102c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } catch (RemoteException e) { 51202c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root Log.e(TAG, "Failed to find mounted path for OBB", e); 513a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root } catch (IllegalArgumentException e) { 514a02b8b05dd1e8b8cf169e1f89542ef835b11fc13Kenny Root Log.d(TAG, "Couldn't read OBB file", e); 51502c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } 51602c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root 51702c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root return null; 51802c8730c1bf19daf48bec8c6995df676a00a73b1Kenny Root } 519b104340496e3a531e26c8f428c808eca0e039f50San Mehat} 520