summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Sharkey <jsharkey@android.com> 2018-12-07 15:16:08 -0700
committer Jeff Sharkey <jsharkey@android.com> 2018-12-08 11:35:52 -0700
commit844989ead3947133ec0854bd16e67b461bb122a0 (patch)
tree328d26072223f7b8d5f2c23b710273cb4f3c6a39
parentdc0d44176d23c7ed24e9cb38ce6886bf02a9bd6d (diff)
Make DocumentsContract methods more general.
Accepting only ContentResolver arguments was quite limiting, so use the newly created super-interface ContentInterface, which lets callers use a ContentResolver, and ContentProviderClient, or even a specific ContentProvider. This is a safe API change, since we're accepting a more-general argument, and existing API users can continue passing ContentResolver to these methods. Bug: 117635768 Test: atest DocumentsUITests Test: atest android.appsecurity.cts.DocumentsTest Change-Id: I109af667d9bdabe4bf78fb35fa61dee6c429ed47
-rw-r--r--src/com/android/documentsui/DocumentsAccess.java4
-rw-r--r--src/com/android/documentsui/Metrics.java3
-rw-r--r--src/com/android/documentsui/services/CopyJob.java6
-rw-r--r--src/com/android/documentsui/services/Job.java3
-rw-r--r--src/com/android/documentsui/services/MoveJob.java2
-rw-r--r--tests/common/com/android/documentsui/DocumentsProviderHelper.java3
-rw-r--r--tests/common/com/android/documentsui/bots/NotificationsBot.java70
-rw-r--r--tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java3
8 files changed, 28 insertions, 66 deletions
diff --git a/src/com/android/documentsui/DocumentsAccess.java b/src/com/android/documentsui/DocumentsAccess.java
index ea62d935a..a0f3b2ddd 100644
--- a/src/com/android/documentsui/DocumentsAccess.java
+++ b/src/com/android/documentsui/DocumentsAccess.java
@@ -47,7 +47,7 @@ public interface DocumentsAccess {
@Nullable DocumentInfo getArchiveDocument(Uri uri);
boolean isDocumentUri(Uri uri);
- @Nullable Path findDocumentPath(Uri uri) throws RemoteException;
+ @Nullable Path findDocumentPath(Uri uri) throws RemoteException, FileNotFoundException;
List<DocumentInfo> getDocuments(String authority, List<String> docIds) throws RemoteException;
@@ -120,7 +120,7 @@ public interface DocumentsAccess {
}
@Override
- public Path findDocumentPath(Uri docUri) throws RemoteException {
+ public Path findDocumentPath(Uri docUri) throws RemoteException, FileNotFoundException {
final ContentResolver resolver = mContext.getContentResolver();
try (final ContentProviderClient client = DocumentsApplication
.acquireUnstableProviderOrThrow(resolver, docUri.getAuthority())) {
diff --git a/src/com/android/documentsui/Metrics.java b/src/com/android/documentsui/Metrics.java
index 838ebf8b7..4ce3697a8 100644
--- a/src/com/android/documentsui/Metrics.java
+++ b/src/com/android/documentsui/Metrics.java
@@ -43,6 +43,7 @@ import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.services.FileOperationService.OpType;
import com.android.internal.logging.MetricsLogger;
+import java.io.FileNotFoundException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
@@ -709,7 +710,7 @@ public final class Metrics {
final RootInfo root = providers.getRootOneshot(
Providers.AUTHORITY_STORAGE, path.getRootId());
isInternal = !root.supportsEject();
- } catch (RemoteException | RuntimeException e) {
+ } catch (FileNotFoundException | RemoteException | RuntimeException e) {
Log.e(TAG, "Failed to obtain its root info. Log the metrics as internal.", e);
// It's not very likely to have an external storage so log it as internal.
isInternal = true;
diff --git a/src/com/android/documentsui/services/CopyJob.java b/src/com/android/documentsui/services/CopyJob.java
index 013a73d70..5761fed83 100644
--- a/src/com/android/documentsui/services/CopyJob.java
+++ b/src/com/android/documentsui/services/CopyJob.java
@@ -327,7 +327,7 @@ class CopyJob extends ResolvedResourcesJob {
appContext, operationType, Metrics.OPMODE_PROVIDER);
return;
}
- } catch (RemoteException | RuntimeException e) {
+ } catch (FileNotFoundException | RemoteException | RuntimeException e) {
Log.e(TAG, "Provider side copy failed for: " + src.derivedUri
+ " due to an exception.", e);
Metrics.logFileOperationFailure(
@@ -390,7 +390,7 @@ class CopyJob extends ResolvedResourcesJob {
try {
dstUri = DocumentsContract.createDocument(
getClient(dest), dest.derivedUri, dstMimeType, dstDisplayName);
- } catch (RemoteException | RuntimeException e) {
+ } catch (FileNotFoundException | RemoteException | RuntimeException e) {
Metrics.logFileOperationFailure(
appContext, Metrics.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
throw new ResourceException(
@@ -783,7 +783,7 @@ class CopyJob extends ResolvedResourcesJob {
if (parent.isDirectory() && doc.authority.equals(parent.authority)) {
try {
return isChildDocument(getClient(doc), doc.derivedUri, parent.derivedUri);
- } catch (RemoteException | RuntimeException e) {
+ } catch (FileNotFoundException | RemoteException | RuntimeException e) {
throw new ResourceException(
"Failed to check if %s is a child of %s due to an exception.",
doc.derivedUri, parent.derivedUri, e);
diff --git a/src/com/android/documentsui/services/Job.java b/src/com/android/documentsui/services/Job.java
index e50d50b0a..cc5208ec7 100644
--- a/src/com/android/documentsui/services/Job.java
+++ b/src/com/android/documentsui/services/Job.java
@@ -53,6 +53,7 @@ import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.files.FilesActivity;
import com.android.documentsui.services.FileOperationService.OpType;
+import java.io.FileNotFoundException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -264,7 +265,7 @@ abstract public class Job implements Runnable {
throw new ResourceException("Unable to delete source document. "
+ "File is not deletable or removable: %s.", doc.derivedUri);
}
- } catch (RemoteException | RuntimeException e) {
+ } catch (FileNotFoundException | RemoteException | RuntimeException e) {
throw new ResourceException("Failed to delete file %s due to an exception.",
doc.derivedUri, e);
}
diff --git a/src/com/android/documentsui/services/MoveJob.java b/src/com/android/documentsui/services/MoveJob.java
index c46f39bc4..10185e23a 100644
--- a/src/com/android/documentsui/services/MoveJob.java
+++ b/src/com/android/documentsui/services/MoveJob.java
@@ -153,7 +153,7 @@ final class MoveJob extends CopyJob {
appContext, operationType, Metrics.OPMODE_PROVIDER);
return;
}
- } catch (RemoteException | RuntimeException e) {
+ } catch (FileNotFoundException | RemoteException | RuntimeException e) {
Metrics.logFileOperationFailure(
appContext, Metrics.SUBFILEOP_QUICK_MOVE, src.derivedUri);
Log.e(TAG, "Provider side move failed for: " + src.derivedUri
diff --git a/tests/common/com/android/documentsui/DocumentsProviderHelper.java b/tests/common/com/android/documentsui/DocumentsProviderHelper.java
index 123f4fb15..fdc71888c 100644
--- a/tests/common/com/android/documentsui/DocumentsProviderHelper.java
+++ b/tests/common/com/android/documentsui/DocumentsProviderHelper.java
@@ -49,6 +49,7 @@ import libcore.io.Streams;
import com.google.common.collect.Lists;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -93,7 +94,7 @@ public class DocumentsProviderHelper {
try {
Uri uri = DocumentsContract.createDocument(mClient, parentUri, mimeType, name);
return uri;
- } catch (RemoteException e) {
+ } catch (FileNotFoundException e) {
throw new RuntimeException("Couldn't create document: " + name + " with mimetype "
+ mimeType, e);
}
diff --git a/tests/common/com/android/documentsui/bots/NotificationsBot.java b/tests/common/com/android/documentsui/bots/NotificationsBot.java
index 500b6304e..7a4c5496b 100644
--- a/tests/common/com/android/documentsui/bots/NotificationsBot.java
+++ b/tests/common/com/android/documentsui/bots/NotificationsBot.java
@@ -17,74 +17,32 @@
package com.android.documentsui.bots;
import android.app.Activity;
-import android.content.ContentResolver;
+import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.UiSelector;
-import android.text.TextUtils;
-import android.view.KeyEvent;
+
+import com.android.documentsui.services.TestNotificationService;
+
+import java.io.IOException;
/**
* A test helper class for controlling notification items.
*/
public class NotificationsBot extends Bots.BaseBot {
- private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
- private static final String allow_res_name = "allow";
- private static final String turn_off_res_name = "notification_listener_disable_warning_confirm";
+ private final ComponentName mComponent;
public NotificationsBot(UiDevice device, Context context, int timeout) {
super(device, context, timeout);
+ mComponent = new ComponentName(context, TestNotificationService.class);
}
- public void setNotificationAccess(Activity activity, boolean enabled)
- throws UiObjectNotFoundException, NameNotFoundException {
- Context testContext = InstrumentationRegistry.getContext();
-
- if(isNotificationAccessEnabled(
- mContext.getContentResolver(), testContext.getPackageName()) == enabled) {
- return;
- }
-
- Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
- activity.startActivity(intent);
- mDevice.waitForIdle();
-
- String appName = testContext.getPackageManager().getApplicationLabel(
- testContext.getApplicationInfo()).toString();
- clickLabel(appName);
-
- Context settings_context = mContext.createPackageContext(SETTINGS_PACKAGE_NAME,
- Context.CONTEXT_RESTRICTED);
- String label_res_name = enabled ? allow_res_name : turn_off_res_name;
- int res_id = settings_context.getResources().getIdentifier(label_res_name,
- "string", SETTINGS_PACKAGE_NAME);
-
- clickLabel(settings_context.getResources().getString(res_id));
- mDevice.pressKeyCode(KeyEvent.KEYCODE_BACK);
- mDevice.waitForIdle();
- }
-
- private boolean isNotificationAccessEnabled(ContentResolver resolver, String pkgName) {
- String listeners = Settings.Secure.getString(resolver, "enabled_notification_listeners");
- if (!TextUtils.isEmpty(listeners)) {
- String[] list = listeners.split(":");
- for(String item : list) {
- if(item.startsWith(pkgName)) {
- return true;
- }
- }
+ public void setNotificationAccess(Activity activity, boolean enabled) throws IOException {
+ if (enabled) {
+ mDevice.executeShellCommand(
+ "cmd notification allow_listener " + mComponent.flattenToString());
+ } else {
+ mDevice.executeShellCommand(
+ "cmd notification disallow_listener " + mComponent.flattenToString());
}
- return false;
- }
-
- private void clickLabel(String label) throws UiObjectNotFoundException {
- UiSelector selector = new UiSelector().textMatches("(?i)" + label);
- mDevice.findObject(selector).click();
- mDevice.waitForIdle();
}
}
diff --git a/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java b/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
index cc40e56e8..cd7bda299 100644
--- a/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
+++ b/tests/unit/com/android/documentsui/archives/ArchivesProviderTest.java
@@ -44,6 +44,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.FileNotFoundException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -266,7 +267,7 @@ public class ArchivesProviderTest {
}
@Test
- public void testGetDocumentMetadata() throws InterruptedException, RemoteException {
+ public void testGetDocumentMetadata() throws Exception {
final Uri sourceUri = DocumentsContract.buildDocumentUri(
ResourcesProvider.AUTHORITY, "images.zip");
final Uri archiveUri = ArchivesProvider.buildUriForArchive(sourceUri,