Loading packages/MtpDocumentsProvider/res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,6 @@ <string name="accessing_notification_title">Accessing files from <xliff:g id="device_model" example="Nexus 9">%1$s</xliff:g></string> <!-- Description of notification showing Files app is accessing files in a MTP device. [CHAR LIMIT=60]--> <string name="accessing_notification_description">Don\'t disconnect the device</string> <!-- Error message shown in Files app when the connected MTP device is busy. [CHAR LIMIT=150]--> <string name="error_busy_device">The other device is busy. You can\'t transfer files until it\'s available.</string> </resources> packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +11 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,12 @@ import android.content.ContentResolver; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.database.Cursor; import android.database.MatrixCursor; import android.graphics.Point; import android.media.MediaFile; import android.mtp.MtpConstants; import android.mtp.MtpObjectInfo; import android.os.Bundle; import android.os.CancellationSignal; import android.os.ParcelFileDescriptor; import android.os.storage.StorageManager; Loading @@ -35,6 +37,7 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.mtp.exceptions.BusyDeviceException; import java.io.FileNotFoundException; import java.io.IOException; Loading Loading @@ -174,6 +177,14 @@ public class MtpDocumentsProvider extends DocumentsProvider { // Returns object list from document loader. return getDocumentLoader(parentIdentifier).queryChildDocuments( projection, parentIdentifier); } catch (BusyDeviceException exception) { final Bundle bundle = new Bundle(); bundle.putString( DocumentsContract.EXTRA_ERROR, mResources.getString(R.string.error_busy_device)); final Cursor cursor = new MatrixCursor(projection); cursor.setExtras(bundle); return cursor; } catch (IOException exception) { Log.e(MtpDocumentsProvider.TAG, "queryChildDocuments", exception); throw new FileNotFoundException(exception.getMessage()); Loading packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java +4 −2 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.mtp.exceptions.BusyDeviceException; import java.io.FileNotFoundException; import java.io.IOException; Loading Loading @@ -101,7 +102,8 @@ class MtpManager { } if (!device.open(connection)) { throw new IOException("Failed to open a MTP device."); // We cannot open connection when another application use the device. throw new BusyDeviceException(); } // Handle devices that fail to obtain storages just after opening a MTP session. Loading Loading @@ -134,7 +136,7 @@ class MtpManager { try { roots = getRoots(device.getDeviceId()); } catch (IOException exp) { Log.e(MtpDocumentsProvider.TAG, exp.getMessage()); Log.e(MtpDocumentsProvider.TAG, "Failed to open device", exp); // If we failed to fetch roots for the device, we still returns device model // with an empty set of roots so that the device is shown DocumentsUI as long as // the device is physically connected. Loading packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java 0 → 100644 +25 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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.mtp.exceptions; import java.io.IOException; /** * Exception thrown when the device is busy and the requested operation cannon be completed. */ public class BusyDeviceException extends IOException { } packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import android.provider.DocumentsContract; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.MediumTest; import com.android.mtp.exceptions.BusyDeviceException; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; Loading Loading @@ -526,6 +528,32 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { } } public void testBusyDevice() throws Exception { mMtpManager = new TestMtpManager(getContext()) { @Override void openDevice(int deviceId) throws IOException { throw new BusyDeviceException(); } }; setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); mMtpManager.addValidDevice(new MtpDeviceRecord( 0, "Device A", false /* unopened */, new MtpRoot[0], null, null)); mProvider.resumeRootScanner(); mResolver.waitForNotification(ROOTS_URI, 1); try (final Cursor cursor = mProvider.queryRoots(null)) { assertEquals(1, cursor.getCount()); } try (final Cursor cursor = mProvider.queryChildDocuments("1", null, null)) { assertEquals(0, cursor.getCount()); assertEquals( "error_busy_device", cursor.getExtras().getString(DocumentsContract.EXTRA_ERROR)); } } private void setupProvider(int flag) { mDatabase = new MtpDatabase(getContext(), flag); mProvider = new MtpDocumentsProvider(); Loading Loading
packages/MtpDocumentsProvider/res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,6 @@ <string name="accessing_notification_title">Accessing files from <xliff:g id="device_model" example="Nexus 9">%1$s</xliff:g></string> <!-- Description of notification showing Files app is accessing files in a MTP device. [CHAR LIMIT=60]--> <string name="accessing_notification_description">Don\'t disconnect the device</string> <!-- Error message shown in Files app when the connected MTP device is busy. [CHAR LIMIT=150]--> <string name="error_busy_device">The other device is busy. You can\'t transfer files until it\'s available.</string> </resources>
packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +11 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,12 @@ import android.content.ContentResolver; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.database.Cursor; import android.database.MatrixCursor; import android.graphics.Point; import android.media.MediaFile; import android.mtp.MtpConstants; import android.mtp.MtpObjectInfo; import android.os.Bundle; import android.os.CancellationSignal; import android.os.ParcelFileDescriptor; import android.os.storage.StorageManager; Loading @@ -35,6 +37,7 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.mtp.exceptions.BusyDeviceException; import java.io.FileNotFoundException; import java.io.IOException; Loading Loading @@ -174,6 +177,14 @@ public class MtpDocumentsProvider extends DocumentsProvider { // Returns object list from document loader. return getDocumentLoader(parentIdentifier).queryChildDocuments( projection, parentIdentifier); } catch (BusyDeviceException exception) { final Bundle bundle = new Bundle(); bundle.putString( DocumentsContract.EXTRA_ERROR, mResources.getString(R.string.error_busy_device)); final Cursor cursor = new MatrixCursor(projection); cursor.setExtras(bundle); return cursor; } catch (IOException exception) { Log.e(MtpDocumentsProvider.TAG, "queryChildDocuments", exception); throw new FileNotFoundException(exception.getMessage()); Loading
packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java +4 −2 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.mtp.exceptions.BusyDeviceException; import java.io.FileNotFoundException; import java.io.IOException; Loading Loading @@ -101,7 +102,8 @@ class MtpManager { } if (!device.open(connection)) { throw new IOException("Failed to open a MTP device."); // We cannot open connection when another application use the device. throw new BusyDeviceException(); } // Handle devices that fail to obtain storages just after opening a MTP session. Loading Loading @@ -134,7 +136,7 @@ class MtpManager { try { roots = getRoots(device.getDeviceId()); } catch (IOException exp) { Log.e(MtpDocumentsProvider.TAG, exp.getMessage()); Log.e(MtpDocumentsProvider.TAG, "Failed to open device", exp); // If we failed to fetch roots for the device, we still returns device model // with an empty set of roots so that the device is shown DocumentsUI as long as // the device is physically connected. Loading
packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java 0 → 100644 +25 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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.mtp.exceptions; import java.io.IOException; /** * Exception thrown when the device is busy and the requested operation cannon be completed. */ public class BusyDeviceException extends IOException { }
packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import android.provider.DocumentsContract; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.MediumTest; import com.android.mtp.exceptions.BusyDeviceException; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; Loading Loading @@ -526,6 +528,32 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { } } public void testBusyDevice() throws Exception { mMtpManager = new TestMtpManager(getContext()) { @Override void openDevice(int deviceId) throws IOException { throw new BusyDeviceException(); } }; setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); mMtpManager.addValidDevice(new MtpDeviceRecord( 0, "Device A", false /* unopened */, new MtpRoot[0], null, null)); mProvider.resumeRootScanner(); mResolver.waitForNotification(ROOTS_URI, 1); try (final Cursor cursor = mProvider.queryRoots(null)) { assertEquals(1, cursor.getCount()); } try (final Cursor cursor = mProvider.queryChildDocuments("1", null, null)) { assertEquals(0, cursor.getCount()); assertEquals( "error_busy_device", cursor.getExtras().getString(DocumentsContract.EXTRA_ERROR)); } } private void setupProvider(int flag) { mDatabase = new MtpDatabase(getContext(), flag); mProvider = new MtpDocumentsProvider(); Loading