1abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood/* 2abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * Copyright (C) 2010 The Android Open Source Project 3abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * 4abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 5abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * you may not use this file except in compliance with the License. 6abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * You may obtain a copy of the License at 7abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * 8abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 9abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * 10abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * Unless required by applicable law or agreed to in writing, software 11abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 12abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * See the License for the specific language governing permissions and 14abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood * limitations under the License. 15abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood */ 16abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood 17abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwoodpackage com.android.providers.media; 18abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood 198efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkeyimport android.app.ActivityManager; 20abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwoodimport android.app.Service; 21abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwoodimport android.content.Intent; 226fcef4f5098c35a94cf0f17b6dd2b99149d2296cMike Lockwoodimport android.hardware.usb.UsbManager; 2390345783ad297da6059398cab174687de6f36a5bMike Lockwoodimport android.mtp.MtpDatabase; 2490345783ad297da6059398cab174687de6f36a5bMike Lockwoodimport android.mtp.MtpServer; 25d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwoodimport android.mtp.MtpStorage; 26abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwoodimport android.os.Environment; 27abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwoodimport android.os.IBinder; 288efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkeyimport android.os.UserHandle; 29d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwoodimport android.os.storage.StorageEventListener; 30d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwoodimport android.os.storage.StorageManager; 31c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwoodimport android.os.storage.StorageVolume; 32abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwoodimport android.util.Log; 33abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood 341e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwoodimport java.io.File; 35d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwoodimport java.util.HashMap; 36d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood 37d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwoodpublic class MtpService extends Service { 38abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood private static final String TAG = "MtpService"; 391469c78b58e40d0400487e61078b1297899d8956Nick Kralevich private static final boolean LOGD = false; 40abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood 411e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood // We restrict PTP to these subdirectories 421e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood private static final String[] PTP_DIRECTORIES = new String[] { 431e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood Environment.DIRECTORY_DCIM, 441e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood Environment.DIRECTORY_PICTURES, 451e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood }; 461e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood 471e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood private void addStorageDevicesLocked() { 481e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood if (mPtpMode) { 491e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood // In PTP mode we support only primary storage 50395ad2597601ccf285cfe679c7263a1b1feee231Jeff Sharkey final StorageVolume primary = StorageManager.getPrimaryVolume(mVolumes); 5157b65f10aaafc4bf42a0fa59eb2bbe6c8371c2e6Jeff Sharkey final String path = primary.getPath(); 528d13ca8552efd8292099a7bf5a30c0e0d18a60e7Chuanxiao Dong if (path != null) { 538d13ca8552efd8292099a7bf5a30c0e0d18a60e7Chuanxiao Dong String state = mStorageManager.getVolumeState(path); 548d13ca8552efd8292099a7bf5a30c0e0d18a60e7Chuanxiao Dong if (Environment.MEDIA_MOUNTED.equals(state)) { 5557b65f10aaafc4bf42a0fa59eb2bbe6c8371c2e6Jeff Sharkey addStorageLocked(mVolumeMap.get(path)); 568d13ca8552efd8292099a7bf5a30c0e0d18a60e7Chuanxiao Dong } 578d13ca8552efd8292099a7bf5a30c0e0d18a60e7Chuanxiao Dong } 581e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood } else { 5955bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood for (StorageVolume volume : mVolumeMap.values()) { 6055bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood addStorageLocked(volume); 611e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood } 621e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood } 631e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood } 641e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood 65d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood private final StorageEventListener mStorageEventListener = new StorageEventListener() { 668efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey @Override 67d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood public void onStorageStateChanged(String path, String oldState, String newState) { 68d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood synchronized (mBinder) { 69d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood Log.d(TAG, "onStorageStateChanged " + path + " " + oldState + " -> " + newState); 70d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood if (Environment.MEDIA_MOUNTED.equals(newState)) { 71d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood volumeMountedLocked(path); 72d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } else if (Environment.MEDIA_MOUNTED.equals(oldState)) { 7355bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood StorageVolume volume = mVolumeMap.remove(path); 7455bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood if (volume != null) { 7555bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood removeStorageLocked(volume); 76868c8a91b9fe8aba9e3c1f17514c3aa1022307d5Mike Lockwood } 77868c8a91b9fe8aba9e3c1f17514c3aa1022307d5Mike Lockwood } 78868c8a91b9fe8aba9e3c1f17514c3aa1022307d5Mike Lockwood } 79868c8a91b9fe8aba9e3c1f17514c3aa1022307d5Mike Lockwood } 80868c8a91b9fe8aba9e3c1f17514c3aa1022307d5Mike Lockwood }; 81868c8a91b9fe8aba9e3c1f17514c3aa1022307d5Mike Lockwood 82d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood private MtpDatabase mDatabase; 83abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood private MtpServer mServer; 84d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood private StorageManager mStorageManager; 858efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey /** Flag indicating if MTP is disabled due to keyguard */ 868efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey private boolean mMtpDisabled; 871469c78b58e40d0400487e61078b1297899d8956Nick Kralevich private boolean mUnlocked; 881e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood private boolean mPtpMode; 8955bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood private final HashMap<String, StorageVolume> mVolumeMap = new HashMap<String, StorageVolume>(); 90d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood private final HashMap<String, MtpStorage> mStorageMap = new HashMap<String, MtpStorage>(); 91c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood private StorageVolume[] mVolumes; 92685aac2d437ef229f81b167ffa1dae95fe2d1a97Mike Lockwood 93685aac2d437ef229f81b167ffa1dae95fe2d1a97Mike Lockwood @Override 94685aac2d437ef229f81b167ffa1dae95fe2d1a97Mike Lockwood public void onCreate() { 958efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey mStorageManager = StorageManager.from(this); 96d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood synchronized (mBinder) { 978efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey updateDisabledStateLocked(); 98d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood mStorageManager.registerListener(mStorageEventListener); 99c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood StorageVolume[] volumes = mStorageManager.getVolumeList(); 100c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood mVolumes = volumes; 101d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood for (int i = 0; i < volumes.length; i++) { 102c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood String path = volumes[i].getPath(); 103d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood String state = mStorageManager.getVolumeState(path); 104d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood if (Environment.MEDIA_MOUNTED.equals(state)) { 1058efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey volumeMountedLocked(path); 106d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 107d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 108d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 109685aac2d437ef229f81b167ffa1dae95fe2d1a97Mike Lockwood } 110abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood 111abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood @Override 112819cafdb3d4c3ce8a74d3b572b8ca0a0b639e8b2Mike Lockwood public int onStartCommand(Intent intent, int flags, int startId) { 1131469c78b58e40d0400487e61078b1297899d8956Nick Kralevich mUnlocked = intent.getBooleanExtra(UsbManager.USB_DATA_UNLOCKED, false); 1141469c78b58e40d0400487e61078b1297899d8956Nick Kralevich if (LOGD) { Log.d(TAG, "onStartCommand intent=" + intent + " mUnlocked=" + mUnlocked); } 115abf5daf6a8c2f9441af98b489398a476e7c6564cMike Lockwood synchronized (mBinder) { 1168efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey updateDisabledStateLocked(); 1178efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey mPtpMode = (intent == null ? false 1188efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey : intent.getBooleanExtra(UsbManager.USB_FUNCTION_PTP, false)); 1198efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey String[] subdirs = null; 1208efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey if (mPtpMode) { 1218efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey int count = PTP_DIRECTORIES.length; 1228efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey subdirs = new String[count]; 1238efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey for (int i = 0; i < count; i++) { 1248efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey File file = 1258efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey Environment.getExternalStoragePublicDirectory(PTP_DIRECTORIES[i]); 1268efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey // make sure this directory exists 1278efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey file.mkdirs(); 1288efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey subdirs[i] = file.getPath(); 1291e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood } 130abf5daf6a8c2f9441af98b489398a476e7c6564cMike Lockwood } 1318efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey final StorageVolume primary = StorageManager.getPrimaryVolume(mVolumes); 1321e45d525d1e521a0b1d425d53f1cda773fd203d3Marco Nelissen if (mDatabase != null) { 1331e45d525d1e521a0b1d425d53f1cda773fd203d3Marco Nelissen mDatabase.setServer(null); 1341e45d525d1e521a0b1d425d53f1cda773fd203d3Marco Nelissen } 1359aecbd92265fe74a29d47866abbb233c1454effcDaichi Hirono manageServiceLocked(primary, subdirs); 136abf5daf6a8c2f9441af98b489398a476e7c6564cMike Lockwood } 137819cafdb3d4c3ce8a74d3b572b8ca0a0b639e8b2Mike Lockwood 138bc640a0889da34c67b1eb298fe9de04609fd78b6Jeff Sharkey return START_REDELIVER_INTENT; 139abf5daf6a8c2f9441af98b489398a476e7c6564cMike Lockwood } 140abf5daf6a8c2f9441af98b489398a476e7c6564cMike Lockwood 1418efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey private void updateDisabledStateLocked() { 1428efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey final boolean isCurrentUser = UserHandle.myUserId() == ActivityManager.getCurrentUser(); 1431469c78b58e40d0400487e61078b1297899d8956Nick Kralevich mMtpDisabled = !mUnlocked || !isCurrentUser; 1448efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey if (LOGD) { 1458efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey Log.d(TAG, "updating state; isCurrentUser=" + isCurrentUser + ", mMtpLocked=" 1468efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey + mMtpDisabled); 1478efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey } 1488efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey } 1498efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey 1508efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey /** 1518efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey * Manage {@link #mServer}, creating only when running as the current user. 1528efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey */ 1539aecbd92265fe74a29d47866abbb233c1454effcDaichi Hirono private void manageServiceLocked(StorageVolume primary, String[] subdirs) { 1548efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey final boolean isCurrentUser = UserHandle.myUserId() == ActivityManager.getCurrentUser(); 1558efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey if (mServer == null && isCurrentUser) { 1568efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey Log.d(TAG, "starting MTP server in " + (mPtpMode ? "PTP mode" : "MTP mode")); 1579aecbd92265fe74a29d47866abbb233c1454effcDaichi Hirono mDatabase = new MtpDatabase(this, MediaProvider.EXTERNAL_VOLUME, 1589aecbd92265fe74a29d47866abbb233c1454effcDaichi Hirono primary.getPath(), subdirs); 1598efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey mServer = new MtpServer(mDatabase, mPtpMode); 160bcbcb91c4cac69658faebd6e45ca6490d944778aMike Lockwood mDatabase.setServer(mServer); 1618efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey if (!mMtpDisabled) { 1628efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey addStorageDevicesLocked(); 1638efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey } 1648efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey mServer.start(); 1658efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey } else if (mServer != null && !isCurrentUser) { 1668efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey Log.d(TAG, "no longer current user; shutting down MTP server"); 1678efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey // Internally, kernel will close our FD, and server thread will 1688efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey // handle cleanup. 1698efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey mServer = null; 170bcbcb91c4cac69658faebd6e45ca6490d944778aMike Lockwood mDatabase.setServer(null); 1718efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey } 1728efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey } 1738efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey 174819cafdb3d4c3ce8a74d3b572b8ca0a0b639e8b2Mike Lockwood @Override 1758efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey public void onDestroy() { 176d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood mStorageManager.unregisterListener(mStorageEventListener); 1771e45d525d1e521a0b1d425d53f1cda773fd203d3Marco Nelissen if (mDatabase != null) { 1781e45d525d1e521a0b1d425d53f1cda773fd203d3Marco Nelissen mDatabase.setServer(null); 1791e45d525d1e521a0b1d425d53f1cda773fd203d3Marco Nelissen } 180abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood } 181abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood 182d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood private final IMtpService.Stub mBinder = 183d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood new IMtpService.Stub() { 184d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood public void sendObjectAdded(int objectHandle) { 1853d8bf05677c11764474df82ec5dc912c9e746b0aMike Lockwood synchronized (mBinder) { 186d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood if (mServer != null) { 187d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood mServer.sendObjectAdded(objectHandle); 188d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood } 189d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood } 190d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood } 191d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood 192d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood public void sendObjectRemoved(int objectHandle) { 1933d8bf05677c11764474df82ec5dc912c9e746b0aMike Lockwood synchronized (mBinder) { 194d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood if (mServer != null) { 195d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood mServer.sendObjectRemoved(objectHandle); 196d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood } 197d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood } 198d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood } 199d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood }; 200d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood 201abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood @Override 2028efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey public IBinder onBind(Intent intent) { 203d186c64cdd590e6491ee46dd8fcd52600d2edc5cMike Lockwood return mBinder; 204abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood } 205d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood 206d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood private void volumeMountedLocked(String path) { 207c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood for (int i = 0; i < mVolumes.length; i++) { 208c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood StorageVolume volume = mVolumes[i]; 209c47e4f2921312098eddc5fe49b080e0f2df60e81Mike Lockwood if (volume.getPath().equals(path)) { 21055bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood mVolumeMap.put(path, volume); 211d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood if (!mMtpDisabled) { 2121e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood // In PTP mode we support only primary storage 213395ad2597601ccf285cfe679c7263a1b1feee231Jeff Sharkey if (volume.isPrimary() || !mPtpMode) { 21455bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood addStorageLocked(volume); 2151e950b8090d90bbf92e528a974ecb8c5c48dff84Mike Lockwood } 216d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 217d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood break; 218d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 219d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 220d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 221d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood 22255bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood private void addStorageLocked(StorageVolume volume) { 2239681e238cd39c3cfbbd63d47d26a1d9bff9f09e5Fabrice Di Meglio MtpStorage storage = new MtpStorage(volume, getApplicationContext()); 22440fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey mStorageMap.put(storage.getPath(), storage); 22540fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey 22640fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey if (storage.getStorageId() == StorageVolume.STORAGE_ID_INVALID) { 22740fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey Log.w(TAG, "Ignoring volume with invalid MTP storage ID: " + storage); 22840fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey return; 22940fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey } else { 23040fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey Log.d(TAG, "Adding MTP storage 0x" + Integer.toHexString(storage.getStorageId()) 23140fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey + " at " + storage.getPath()); 23240fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey } 2338efd65fe64c7978534bb549b2329068a2f8c5075Jeff Sharkey 234d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood if (mDatabase != null) { 235d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood mDatabase.addStorage(storage); 236d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 237d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood if (mServer != null) { 238d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood mServer.addStorage(storage); 239d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 240d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 241d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood 24255bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood private void removeStorageLocked(StorageVolume volume) { 24355bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood MtpStorage storage = mStorageMap.remove(volume.getPath()); 24455bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood if (storage == null) { 24540fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey Log.e(TAG, "Missing MtpStorage for " + volume.getPath()); 24655bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood return; 24755bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood } 24855bf981b5231b0831a146ba67dc16d9f55c67154Mike Lockwood 24940fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey Log.d(TAG, "Removing MTP storage " + Integer.toHexString(storage.getStorageId()) + " at " 25040fef25a59cc7a36b99857b756befc36e6996845Jeff Sharkey + storage.getPath()); 251d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood if (mDatabase != null) { 252d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood mDatabase.removeStorage(storage); 253d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 254d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood if (mServer != null) { 255d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood mServer.removeStorage(storage); 256d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 257d3709e80446eb8abc3bb9c60db0d5c9473930611Mike Lockwood } 258abf8d09064cdc380d4996f5022d3a20eb4448ed1Mike Lockwood} 259