Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(491)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/BlockingFileProvider.java

Issue 2143133002: Do screenshot capture async for share intents. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix packagename Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/BlockingFileProvider.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BlockingFileProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/BlockingFileProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..39dcad0dff03af2ea40a5e5cb8734bd7eebad14f
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/BlockingFileProvider.java
@@ -0,0 +1,130 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser;
+
+import android.app.Activity;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.support.v4.content.FileProvider;
+
+import java.io.FileNotFoundException;
+
+/**
+ * A file provider class that shares a potentially non-existent file and blocks the client from
+ * accessing till the file is written.
+ *
+ * This class gives an unique identifier for the file to be shared and the user must write the file
nyquist 2016/07/14 17:36:32 Could you clean up the usage of pronouns in this p
ssid 2016/07/19 18:32:57 Thanks, used these names.
+ * and notify that the file is ready. The client is blocked from accessing the file till the file is
+ * ready. This lets us create the share intent immediately after the user clicks on share and the
+ * actual file will be usually ready when it is requested by the client application. Only one file
+ * can be shared at a given time.
nyquist 2016/07/14 17:36:31 What happens if multiple files are shared? Is this
ssid 2016/07/19 18:32:57 It is the constraint of this implementation and cu
+ */
+public class BlockingFileProvider extends FileProvider {
nyquist 2016/07/14 17:36:32 Could you add a test for this class?
ssid 2016/07/19 18:32:57 Done.
+ private static final String AUTHORITY_SUFFIX = ".BlockingFileProvider";
+
+ /**
+ * Returns an unique uri to identify the file to be shared.
+ *
+ * @param activity Activity that is used to access package manager.
+ * @param fileName An unique file name that represents the file to be created.
+ */
+ public static Uri getContentUriForFile(final Activity activity, String fileName) {
+ Uri uri = null;
nyquist 2016/07/14 17:36:32 Nit: Could you just initialize this while building
ssid 2016/07/19 18:32:57 Done.
+ ensureUriMatcherInitialized(activity.getPackageName());
+ uri = new Uri.Builder().scheme("content").authority(sAuthority).path(fileName).build();
+ synchronized (sLock) {
+ sCurrentFileName = fileName;
+ sFileUri = null;
+ sIsFileReady = false;
+ // In case the previous file never got ready.
+ sLock.notify();
+ }
+ return uri;
+ }
+
+ /**
+ * Notify that the file is ready to be accessed by the resolver.
+ *
+ * @param fileName The unique file name that was passed to getContentUriForFile.
+ * @param fileUri The Uri for actual file given by FileProvider.
+ */
+ public static void notifyFileReady(String fileName, Uri fileUri) {
+ synchronized (sLock) {
+ sFileUri = fileUri;
+ // Ready is set only if the current file is ready.
+ sIsFileReady = sCurrentFileName.equals(fileName);
+ sLock.notify();
+ }
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ Uri fileUri = getFileUriWhenReady(uri);
+ return fileUri != null ? super.openFile(fileUri, mode) : null;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ Uri fileUri = getFileUriWhenReady(uri);
+ return fileUri != null
+ ? super.query(fileUri, projection, selection, selectionArgs, sortOrder)
+ : null;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ synchronized (sLock) {
+ sFileUri = null;
+ sIsFileReady = false;
+ sCurrentFileName = null;
+ }
+ return super.delete(uri, selection, selectionArgs);
+ }
+
+ // Matcher to tell the content resolver the uri patterns that can be handled.
+ private static UriMatcher sUriMatcher = null;
nyquist 2016/07/14 17:36:31 Where is this used?
ssid 2016/07/19 18:32:57 I am not really sure. I I thought this was used by
+ private static String sAuthority = null;
+ private static Object sLock = new Object();
+
+ // All these static objects must be accesseed in a synchronized block:
+ private static boolean sIsFileReady = false;
+ private static String sCurrentFileName = null;
+ private static Uri sFileUri = null;
+
+ /**
+ * Initializes the matcher for content resolver.
+ */
+ private static void ensureUriMatcherInitialized(String packageName) {
+ if (sUriMatcher != null) return;
nyquist 2016/07/14 17:36:32 I don't think this is threadsafe, and it can be ca
ssid 2016/07/19 18:32:57 Acknowledged.
+
+ sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ sAuthority = packageName + AUTHORITY_SUFFIX;
+ sUriMatcher.addURI(sAuthority, "*", 0);
+ }
+
+ /**
+ * Waits and returns file uri iff the file is ready to be accessed, or returns null if file is
+ * replaced.
+ */
+ private Uri getFileUriWhenReady(Uri uri) {
+ String fileName = uri.getPath();
+ synchronized (sLock) {
+ // Wait only if the file is not ready and the current file has not changed.
+ while (!sIsFileReady && fileName.contains(sCurrentFileName)) {
nyquist 2016/07/14 17:36:32 Should this be "endsWith" instead of "contains"?
ssid 2016/07/19 18:32:57 Done.
+ try {
+ sLock.wait();
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ // If the current file has changed while waiting, return null.
+ if (fileName.contains(sCurrentFileName)) return sFileUri;
+ }
+ return null;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698