Loading packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +1 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,7 @@ public class MtpDocumentsProvider extends DocumentsProvider { for (final int id : keySet) { closeDeviceInternal(id); } mRootScanner.pause(); } catch (InterruptedException|IOException e) { // It should fail unit tests by throwing runtime exception. throw new RuntimeException(e); Loading packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java +21 −11 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import java.io.FileNotFoundException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; final class RootScanner { Loading Loading @@ -56,7 +55,7 @@ final class RootScanner { final MtpDatabase mDatabase; ExecutorService mExecutor; FutureTask<Void> mCurrentTask; private UpdateRootsRunnable mCurrentTask; RootScanner( ContentResolver resolver, Loading Loading @@ -84,13 +83,12 @@ final class RootScanner { mExecutor = Executors.newSingleThreadExecutor(); } if (mCurrentTask != null) { // Cancel previous task. mCurrentTask.cancel(true); // Stop previous task. mCurrentTask.stop(); } final UpdateRootsRunnable runnable = new UpdateRootsRunnable(); mCurrentTask = new FutureTask<Void>(runnable, null); mExecutor.submit(mCurrentTask); return runnable.mFirstScanCompleted; mCurrentTask = new UpdateRootsRunnable(); mExecutor.execute(mCurrentTask); return mCurrentTask.mFirstScanCompleted; } /** Loading @@ -112,13 +110,21 @@ final class RootScanner { * Runnable to scan roots and update the database information. */ private final class UpdateRootsRunnable implements Runnable { /** * Count down latch that specifies the runnable is stopped. */ final CountDownLatch mStopped = new CountDownLatch(1); /** * Count down latch that specifies the first scan is completed. */ final CountDownLatch mFirstScanCompleted = new CountDownLatch(1); @Override public void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); int pollingCount = 0; while (true) { while (mStopped.getCount() > 0) { boolean changed = false; // Update devices. Loading Loading @@ -171,12 +177,16 @@ final class RootScanner { // Use SHORT_POLLING_PERIOD for the first SHORT_POLLING_TIMES because it is // more likely to add new root just after the device is added. // TODO: Use short interval only for a device that is just added. Thread.sleep(pollingCount > SHORT_POLLING_TIMES ? LONG_POLLING_INTERVAL : SHORT_POLLING_INTERVAL); mStopped.await(pollingCount > SHORT_POLLING_TIMES ? LONG_POLLING_INTERVAL : SHORT_POLLING_INTERVAL, TimeUnit.MILLISECONDS); } catch (InterruptedException exp) { break; } } } void stop() { mStopped.countDown(); } } } Loading
packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +1 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,7 @@ public class MtpDocumentsProvider extends DocumentsProvider { for (final int id : keySet) { closeDeviceInternal(id); } mRootScanner.pause(); } catch (InterruptedException|IOException e) { // It should fail unit tests by throwing runtime exception. throw new RuntimeException(e); Loading
packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java +21 −11 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import java.io.FileNotFoundException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; final class RootScanner { Loading Loading @@ -56,7 +55,7 @@ final class RootScanner { final MtpDatabase mDatabase; ExecutorService mExecutor; FutureTask<Void> mCurrentTask; private UpdateRootsRunnable mCurrentTask; RootScanner( ContentResolver resolver, Loading Loading @@ -84,13 +83,12 @@ final class RootScanner { mExecutor = Executors.newSingleThreadExecutor(); } if (mCurrentTask != null) { // Cancel previous task. mCurrentTask.cancel(true); // Stop previous task. mCurrentTask.stop(); } final UpdateRootsRunnable runnable = new UpdateRootsRunnable(); mCurrentTask = new FutureTask<Void>(runnable, null); mExecutor.submit(mCurrentTask); return runnable.mFirstScanCompleted; mCurrentTask = new UpdateRootsRunnable(); mExecutor.execute(mCurrentTask); return mCurrentTask.mFirstScanCompleted; } /** Loading @@ -112,13 +110,21 @@ final class RootScanner { * Runnable to scan roots and update the database information. */ private final class UpdateRootsRunnable implements Runnable { /** * Count down latch that specifies the runnable is stopped. */ final CountDownLatch mStopped = new CountDownLatch(1); /** * Count down latch that specifies the first scan is completed. */ final CountDownLatch mFirstScanCompleted = new CountDownLatch(1); @Override public void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); int pollingCount = 0; while (true) { while (mStopped.getCount() > 0) { boolean changed = false; // Update devices. Loading Loading @@ -171,12 +177,16 @@ final class RootScanner { // Use SHORT_POLLING_PERIOD for the first SHORT_POLLING_TIMES because it is // more likely to add new root just after the device is added. // TODO: Use short interval only for a device that is just added. Thread.sleep(pollingCount > SHORT_POLLING_TIMES ? LONG_POLLING_INTERVAL : SHORT_POLLING_INTERVAL); mStopped.await(pollingCount > SHORT_POLLING_TIMES ? LONG_POLLING_INTERVAL : SHORT_POLLING_INTERVAL, TimeUnit.MILLISECONDS); } catch (InterruptedException exp) { break; } } } void stop() { mStopped.countDown(); } } }