summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/MtpDocumentsProvider/res/values/strings.xml2
-rw-r--r--packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java11
-rw-r--r--packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java6
-rw-r--r--packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java25
-rw-r--r--packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java28
-rw-r--r--packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java2
6 files changed, 72 insertions, 2 deletions
diff --git a/packages/MtpDocumentsProvider/res/values/strings.xml b/packages/MtpDocumentsProvider/res/values/strings.xml
index 43a420cf6d97..42bedf1c1cdc 100644
--- a/packages/MtpDocumentsProvider/res/values/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values/strings.xml
@@ -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>
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 033845401b4b..7eae71a8d8a4 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -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;
@@ -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;
@@ -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());
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 5519efd5a323..0527790470fb 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -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;
@@ -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.
@@ -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.
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java b/packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java
new file mode 100644
index 000000000000..55f55b0edbc3
--- /dev/null
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java
@@ -0,0 +1,25 @@
+/*
+ * 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 {
+}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index 5b0f55703a2b..4bc016247762 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -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;
@@ -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();
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java
index b23038b6c3f6..a576a04ac6bb 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java
@@ -24,6 +24,8 @@ class TestResources extends MockResources {
switch (id) {
case R.string.root_name:
return "%1$s %2$s";
+ case R.string.error_busy_device:
+ return "error_busy_device";
}
throw new NotFoundException();
}