Pull clipping related classes to a separate package.
Change-Id: I125d1c34e475f9465e82014cb869f88c9c7cebc4
This commit is contained in:
committed by
Garfield Tan
parent
3b457c74d9
commit
415cd8b846
@@ -28,6 +28,9 @@ import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.text.format.DateUtils;
|
||||
|
||||
import com.android.documentsui.clipping.ClipStorage;
|
||||
import com.android.documentsui.clipping.DocumentClipper;
|
||||
|
||||
public class DocumentsApplication extends Application {
|
||||
private static final long PROVIDER_ANR_TIMEOUT = 20 * DateUtils.SECOND_IN_MILLIS;
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.view.MenuItem;
|
||||
import com.android.documentsui.MenuManager.DirectoryDetails;
|
||||
import com.android.documentsui.OperationDialogFragment.DialogType;
|
||||
import com.android.documentsui.RecentsProvider.ResumeColumns;
|
||||
import com.android.documentsui.clipping.DocumentClipper;
|
||||
import com.android.documentsui.dirlist.AnimationView;
|
||||
import com.android.documentsui.dirlist.DirectoryFragment;
|
||||
import com.android.documentsui.dirlist.FragmentTuner;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.documentsui;
|
||||
package com.android.documentsui.clipping;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
@@ -24,15 +24,13 @@ import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.documentsui.Files;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -45,7 +43,7 @@ public final class ClipStorage {
|
||||
|
||||
public static final int NO_SELECTION_TAG = -1;
|
||||
|
||||
static final String PREF_NAME = "ClipStoragePref";
|
||||
public static final String PREF_NAME = "ClipStoragePref";
|
||||
|
||||
@VisibleForTesting
|
||||
static final int NUM_OF_SLOTS = 20;
|
||||
@@ -90,7 +88,7 @@ public final class ClipStorage {
|
||||
* file may be overwritten.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public synchronized int claimStorageSlot() {
|
||||
synchronized int claimStorageSlot() {
|
||||
int curPos = mNextPos;
|
||||
for (int i = 0; i < NUM_OF_SLOTS; ++i, curPos = (curPos + 1) % NUM_OF_SLOTS) {
|
||||
createSlotFile(curPos);
|
||||
@@ -167,9 +165,9 @@ public final class ClipStorage {
|
||||
/**
|
||||
* Returns a Reader. Callers must close the reader when finished.
|
||||
*/
|
||||
public Reader createReader(File file) throws IOException {
|
||||
ClipStorageReader createReader(File file) throws IOException {
|
||||
assert(file.getParentFile().getParentFile().equals(mOutDir));
|
||||
return new Reader(file);
|
||||
return new ClipStorageReader(file);
|
||||
}
|
||||
|
||||
private File toSlotDataFile(int pos) {
|
||||
@@ -186,7 +184,7 @@ public final class ClipStorage {
|
||||
/**
|
||||
* Provides initialization of the clip data storage directory.
|
||||
*/
|
||||
static File prepareStorage(File cacheDir) {
|
||||
public static File prepareStorage(File cacheDir) {
|
||||
File clipDir = getClipDir(cacheDir);
|
||||
clipDir.mkdir();
|
||||
|
||||
@@ -198,96 +196,6 @@ public final class ClipStorage {
|
||||
return new File(cacheDir, "clippings");
|
||||
}
|
||||
|
||||
static final class Reader implements Iterable<Uri>, Closeable {
|
||||
|
||||
/**
|
||||
* FileLock can't be held multiple times in a single JVM, but it's possible to have multiple
|
||||
* readers reading the same clip file. Share the FileLock here so that it can be released
|
||||
* when it's not needed.
|
||||
*/
|
||||
private static final Map<String, FileLockEntry> sLocks = new HashMap<>();
|
||||
|
||||
private final String mCanonicalPath;
|
||||
private final Scanner mScanner;
|
||||
|
||||
private Reader(File file) throws IOException {
|
||||
FileInputStream inStream = new FileInputStream(file);
|
||||
mScanner = new Scanner(inStream);
|
||||
|
||||
mCanonicalPath = file.getCanonicalPath(); // Resolve symlink
|
||||
synchronized (sLocks) {
|
||||
if (sLocks.containsKey(mCanonicalPath)) {
|
||||
// Read lock is already held by someone in this JVM, just increment the ref
|
||||
// count.
|
||||
sLocks.get(mCanonicalPath).mCount++;
|
||||
} else {
|
||||
// No map entry, need to lock the file so it won't pass this line until the
|
||||
// corresponding writer is done writing.
|
||||
FileLock lock = inStream.getChannel().lock(0L, Long.MAX_VALUE, true);
|
||||
sLocks.put(mCanonicalPath, new FileLockEntry(1, lock, mScanner));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator iterator() {
|
||||
return new Iterator(mScanner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
synchronized (sLocks) {
|
||||
FileLockEntry ref = sLocks.get(mCanonicalPath);
|
||||
|
||||
assert(ref.mCount > 0);
|
||||
if (--ref.mCount == 0) {
|
||||
// If ref count is 0 now, then there is no one who needs to hold the read lock.
|
||||
// Release the lock, and remove the entry.
|
||||
ref.mLock.release();
|
||||
ref.mScanner.close();
|
||||
sLocks.remove(mCanonicalPath);
|
||||
}
|
||||
|
||||
if (mScanner != ref.mScanner) {
|
||||
mScanner.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Iterator implements java.util.Iterator {
|
||||
private final Scanner mScanner;
|
||||
|
||||
private Iterator(Scanner scanner) {
|
||||
mScanner = scanner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return mScanner.hasNextLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri next() {
|
||||
String line = mScanner.nextLine();
|
||||
return Uri.parse(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FileLockEntry {
|
||||
private int mCount;
|
||||
private FileLock mLock;
|
||||
// We need to keep this scanner here because if the scanner is closed, the file lock is
|
||||
// closed too.
|
||||
private Scanner mScanner;
|
||||
|
||||
private FileLockEntry(int count, FileLock lock, Scanner scanner) {
|
||||
mCount = count;
|
||||
mLock = lock;
|
||||
mScanner = scanner;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Writer implements Closeable {
|
||||
|
||||
private final FileOutputStream mOut;
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.documentsui.clipping;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* Reader class used to read uris from clip files stored in {@link ClipStorage}. It provides
|
||||
* synchronization within a single process as an addition to {@link FileLock} which is for
|
||||
* cross-process synchronization.
|
||||
*/
|
||||
class ClipStorageReader implements Iterable<Uri>, Closeable {
|
||||
|
||||
/**
|
||||
* FileLock can't be held multiple times in a single JVM, but it's possible to have multiple
|
||||
* readers reading the same clip file. Share the FileLock here so that it can be released
|
||||
* when it's not needed.
|
||||
*/
|
||||
private static final Map<String, FileLockEntry> sLocks = new HashMap<>();
|
||||
|
||||
private final String mCanonicalPath;
|
||||
private final Scanner mScanner;
|
||||
|
||||
ClipStorageReader(File file) throws IOException {
|
||||
FileInputStream inStream = new FileInputStream(file);
|
||||
mScanner = new Scanner(inStream);
|
||||
|
||||
mCanonicalPath = file.getCanonicalPath(); // Resolve symlink
|
||||
synchronized (sLocks) {
|
||||
if (sLocks.containsKey(mCanonicalPath)) {
|
||||
// Read lock is already held by someone in this JVM, just increment the ref
|
||||
// count.
|
||||
sLocks.get(mCanonicalPath).mCount++;
|
||||
} else {
|
||||
// No map entry, need to lock the file so it won't pass this line until the
|
||||
// corresponding writer is done writing.
|
||||
FileLock lock = inStream.getChannel().lock(0L, Long.MAX_VALUE, true);
|
||||
sLocks.put(mCanonicalPath, new FileLockEntry(1, lock, mScanner));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator iterator() {
|
||||
return new Iterator(mScanner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
FileLockEntry ref;
|
||||
synchronized (sLocks) {
|
||||
ref = sLocks.get(mCanonicalPath);
|
||||
|
||||
assert(ref.mCount > 0);
|
||||
if (--ref.mCount == 0) {
|
||||
// If ref count is 0 now, then there is no one who needs to hold the read lock.
|
||||
// Release the lock, and remove the entry.
|
||||
ref.mLock.release();
|
||||
ref.mScanner.close();
|
||||
sLocks.remove(mCanonicalPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (mScanner != ref.mScanner) {
|
||||
mScanner.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Iterator implements java.util.Iterator {
|
||||
private final Scanner mScanner;
|
||||
|
||||
private Iterator(Scanner scanner) {
|
||||
mScanner = scanner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return mScanner.hasNextLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri next() {
|
||||
String line = mScanner.nextLine();
|
||||
return Uri.parse(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FileLockEntry {
|
||||
private final FileLock mLock;
|
||||
// We need to keep this scanner here because if the scanner is closed, the file lock is
|
||||
// closed too.
|
||||
private final Scanner mScanner;
|
||||
|
||||
private int mCount;
|
||||
|
||||
private FileLockEntry(int count, FileLock lock, Scanner scanner) {
|
||||
mCount = count;
|
||||
mLock = lock;
|
||||
mScanner = scanner;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.documentsui;
|
||||
package com.android.documentsui.clipping;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipDescription;
|
||||
@@ -27,6 +27,7 @@ import android.provider.DocumentsContract;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.documentsui.Shared;
|
||||
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
|
||||
import com.android.documentsui.model.DocumentInfo;
|
||||
import com.android.documentsui.model.DocumentStack;
|
||||
@@ -59,7 +60,7 @@ public final class DocumentClipper {
|
||||
private final ClipStorage mClipStorage;
|
||||
private final ClipboardManager mClipboard;
|
||||
|
||||
DocumentClipper(Context context, ClipStorage storage) {
|
||||
public DocumentClipper(Context context, ClipStorage storage) {
|
||||
mContext = context;
|
||||
mClipStorage = storage;
|
||||
mClipboard = context.getSystemService(ClipboardManager.class);
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.documentsui;
|
||||
package com.android.documentsui.clipping;
|
||||
|
||||
import static com.android.documentsui.DocumentClipper.OP_JUMBO_SELECTION_SIZE;
|
||||
import static com.android.documentsui.DocumentClipper.OP_JUMBO_SELECTION_TAG;
|
||||
import static com.android.documentsui.clipping.DocumentClipper.OP_JUMBO_SELECTION_SIZE;
|
||||
import static com.android.documentsui.clipping.DocumentClipper.OP_JUMBO_SELECTION_TAG;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.Context;
|
||||
@@ -28,6 +28,8 @@ import android.os.PersistableBundle;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.documentsui.DocumentsApplication;
|
||||
import com.android.documentsui.Shared;
|
||||
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
|
||||
import com.android.documentsui.services.FileOperation;
|
||||
|
||||
@@ -110,7 +112,7 @@ public abstract class UrisSupplier implements Parcelable {
|
||||
private final File mFile;
|
||||
private final int mSelectionSize;
|
||||
|
||||
private final transient AtomicReference<ClipStorage.Reader> mReader =
|
||||
private final transient AtomicReference<ClipStorageReader> mReader =
|
||||
new AtomicReference<>();
|
||||
|
||||
private JumboUrisSupplier(ClipData clipData, Context context) throws IOException {
|
||||
@@ -143,7 +145,7 @@ public abstract class UrisSupplier implements Parcelable {
|
||||
|
||||
@Override
|
||||
Iterable<Uri> getUris(ClipStorage storage) throws IOException {
|
||||
ClipStorage.Reader reader = mReader.getAndSet(storage.createReader(mFile));
|
||||
ClipStorageReader reader = mReader.getAndSet(storage.createReader(mFile));
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
mReader.get().close();
|
||||
@@ -156,7 +158,7 @@ public abstract class UrisSupplier implements Parcelable {
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
ClipStorage.Reader reader = mReader.get();
|
||||
ClipStorageReader reader = mReader.get();
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
@@ -73,7 +73,7 @@ import android.widget.Toolbar;
|
||||
import com.android.documentsui.BaseActivity;
|
||||
import com.android.documentsui.DirectoryLoader;
|
||||
import com.android.documentsui.DirectoryResult;
|
||||
import com.android.documentsui.DocumentClipper;
|
||||
import com.android.documentsui.clipping.DocumentClipper;
|
||||
import com.android.documentsui.DocumentsActivity;
|
||||
import com.android.documentsui.DocumentsApplication;
|
||||
import com.android.documentsui.Events.InputEvent;
|
||||
@@ -92,7 +92,7 @@ import com.android.documentsui.Shared;
|
||||
import com.android.documentsui.Snackbars;
|
||||
import com.android.documentsui.State;
|
||||
import com.android.documentsui.State.ViewMode;
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
|
||||
import com.android.documentsui.dirlist.UserInputHandler.DocumentDetails;
|
||||
import com.android.documentsui.model.DocumentInfo;
|
||||
|
||||
@@ -55,7 +55,7 @@ import com.android.documentsui.DocumentsApplication;
|
||||
import com.android.documentsui.Metrics;
|
||||
import com.android.documentsui.R;
|
||||
import com.android.documentsui.RootsCache;
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.model.DocumentInfo;
|
||||
import com.android.documentsui.model.DocumentStack;
|
||||
import com.android.documentsui.model.RootInfo;
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.Metrics;
|
||||
import com.android.documentsui.R;
|
||||
import com.android.documentsui.model.DocumentInfo;
|
||||
|
||||
@@ -27,7 +27,7 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.model.DocumentStack;
|
||||
import com.android.documentsui.services.FileOperationService.OpType;
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ import android.os.RemoteException;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.FilesActivity;
|
||||
import com.android.documentsui.Metrics;
|
||||
import com.android.documentsui.OperationDialogFragment;
|
||||
|
||||
@@ -30,7 +30,7 @@ import android.provider.DocumentsContract.Document;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.documentsui.R;
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.model.DocumentInfo;
|
||||
import com.android.documentsui.model.DocumentStack;
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.documentsui;
|
||||
package com.android.documentsui.clipping;
|
||||
|
||||
import static com.android.documentsui.ClipStorage.NUM_OF_SLOTS;
|
||||
import static com.android.documentsui.clipping.ClipStorage.NUM_OF_SLOTS;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -29,7 +29,6 @@ import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.documentsui.ClipStorage.Reader;
|
||||
import com.android.documentsui.testing.TestScheduledExecutorService;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
@@ -89,7 +88,7 @@ public class ClipStorageTest {
|
||||
List<Uri> uris = new ArrayList<>();
|
||||
|
||||
File copy = mStorage.getFile(mTag);
|
||||
try(Reader provider = mStorage.createReader(copy)) {
|
||||
try(ClipStorageReader provider = mStorage.createReader(copy)) {
|
||||
for (Uri uri : provider) {
|
||||
uris.add(uri);
|
||||
}
|
||||
@@ -98,7 +97,7 @@ public class ClipStorageTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTag_NoAvailableSlot() throws Exception {
|
||||
public void testClaimStorageSlot_NoAvailableSlot() throws Exception {
|
||||
int firstTag = mStorage.claimStorageSlot();
|
||||
writeAll(firstTag, TEST_URIS);
|
||||
mStorage.getFile(firstTag);
|
||||
@@ -119,8 +118,8 @@ public class ClipStorageTest {
|
||||
|
||||
File copy = mStorage.getFile(mTag);
|
||||
File copy2 = mStorage.getFile(mTag);
|
||||
try(Reader reader = mStorage.createReader(copy)) {
|
||||
try(Reader reader2 = mStorage.createReader(copy2)){
|
||||
try(ClipStorageReader reader = mStorage.createReader(copy)) {
|
||||
try(ClipStorageReader reader2 = mStorage.createReader(copy2)){
|
||||
Iterator<Uri> iter = reader.iterator();
|
||||
Iterator<Uri> iter2 = reader2.iterator();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.documentsui;
|
||||
package com.android.documentsui.clipping;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -27,6 +27,7 @@ import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.documentsui.Shared;
|
||||
import com.android.documentsui.testing.TestScheduledExecutorService;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
@@ -27,7 +27,7 @@ import android.os.RemoteException;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.DocumentsProviderHelper;
|
||||
import com.android.documentsui.StubProvider;
|
||||
import com.android.documentsui.model.DocumentInfo;
|
||||
|
||||
@@ -32,7 +32,7 @@ import android.os.Parcelable;
|
||||
import android.test.ServiceTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.model.DocumentInfo;
|
||||
import com.android.documentsui.model.DocumentStack;
|
||||
import com.android.documentsui.testing.DocsProviders;
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.app.Notification;
|
||||
import android.app.Notification.Builder;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
import com.android.documentsui.R;
|
||||
import com.android.documentsui.model.DocumentInfo;
|
||||
import com.android.documentsui.model.DocumentStack;
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.android.documentsui.testing;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.android.documentsui.UrisSupplier;
|
||||
import com.android.documentsui.clipping.UrisSupplier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user