Bug 1368971 - Restrict the scope for monitoring Screenshot folder to avoid infinite loop when saving as PDF r?sebastian
MozReview-Commit-ID: 6jSwmSW63Iq
--- a/mobile/android/base/java/org/mozilla/gecko/ScreenshotObserver.java
+++ b/mobile/android/base/java/org/mozilla/gecko/ScreenshotObserver.java
@@ -10,21 +10,29 @@ import org.mozilla.gecko.permissions.Per
import org.mozilla.gecko.util.ThreadUtils;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Environment;
+import android.os.FileObserver;
import android.provider.MediaStore;
import android.util.Log;
+import java.io.File;
+
public class ScreenshotObserver {
private static final String LOGTAG = "GeckoScreenshotObserver";
+ private static final String SCREENSHOT_FOLDER = Environment.getExternalStorageDirectory()
+ + File.separator + Environment.DIRECTORY_PICTURES
+ + File.separator + "Screenshots" + File.separator;
+
public Context context;
/**
* Listener for screenshot changes.
*/
public interface OnScreenshotListener {
/**
* This callback is executed on the UI thread.
@@ -38,23 +46,16 @@ public class ScreenshotObserver {
}
public void setListener(Context context, OnScreenshotListener listener) {
this.context = context;
this.listener = listener;
}
private MediaObserver mediaObserver;
- private String[] mediaProjections = new String[] {
- MediaStore.Images.ImageColumns.DATA,
- MediaStore.Images.ImageColumns.DISPLAY_NAME,
- MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
- MediaStore.Images.ImageColumns.DATE_TAKEN,
- MediaStore.Images.ImageColumns.TITLE
- };
/**
* Start ScreenshotObserver if this device is supported and all required runtime permissions
* have been granted by the user. Calling this method will not prompt for permissions.
*/
public void start() {
Permissions.from(context)
.withPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
@@ -64,83 +65,56 @@ public class ScreenshotObserver {
private Runnable startObserverRunnable() {
return new Runnable() {
@Override
public void run() {
try {
if (mediaObserver == null) {
mediaObserver = new MediaObserver();
- context.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, mediaObserver);
+ mediaObserver.startWatching();
}
} catch (Exception e) {
Log.e(LOGTAG, "Failure to start watching media: ", e);
}
}
};
}
public void stop() {
if (mediaObserver == null) {
return;
}
try {
- context.getContentResolver().unregisterContentObserver(mediaObserver);
+ mediaObserver.stopWatching();
mediaObserver = null;
} catch (Exception e) {
Log.e(LOGTAG, "Failure to stop watching media: ", e);
}
}
- public void onMediaChange(final Uri uri) {
- // Make sure we are on not on the main thread.
- final ContentResolver cr = context.getContentResolver();
- ThreadUtils.postToBackgroundThread(new Runnable() {
- @Override
- public void run() {
- // Find the most recent image added to the MediaStore and see if it's a screenshot.
- final Cursor cursor = cr.query(uri, mediaProjections, null, null, MediaStore.Images.ImageColumns.DATE_ADDED + " DESC LIMIT 1");
- try {
- if (cursor == null) {
- return;
- }
+ private void onMediaChange(final String path) {
+ final File file = new File(path);
+ final String data = Uri.fromFile(file).toString();
+ Log.i(LOGTAG, "data: " + data);
+ final String title = file.getName();
+ Log.i(LOGTAG, "title: " + title);
- while (cursor.moveToNext()) {
- String data = cursor.getString(0);
- Log.i(LOGTAG, "data: " + data);
- String display = cursor.getString(1);
- Log.i(LOGTAG, "display: " + display);
- String album = cursor.getString(2);
- Log.i(LOGTAG, "album: " + album);
- long date = cursor.getLong(3);
- String title = cursor.getString(4);
- Log.i(LOGTAG, "title: " + title);
- if (album != null && album.toLowerCase().contains("screenshot")) {
- if (listener != null) {
- listener.onScreenshotTaken(data, title);
- break;
- }
- }
- }
- } catch (Exception e) {
- Log.e(LOGTAG, "Failure to process media change: ", e);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
- });
+ if (listener != null) {
+ listener.onScreenshotTaken(data, title);
+ }
}
- private class MediaObserver extends ContentObserver {
- public MediaObserver() {
- super(null);
+ private class MediaObserver extends FileObserver {
+
+ MediaObserver() {
+ super(SCREENSHOT_FOLDER, FileObserver.CREATE);
}
- @Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
- onMediaChange(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ @Override public void onEvent(int event, String path) {
+ Log.i(LOGTAG, "SCREENSHOT_FOLDER changed with file : " + path);
+ if (path != null) {
+ onMediaChange(SCREENSHOT_FOLDER + path);
+ }
}
}
}