Bug 1078355 - Move reader mode code out of BrowserApp, r=margaret

This commit is contained in:
Mark Capella 2014-10-18 02:45:34 -04:00
parent 9d930d28e6
commit 8f7e30d7c5
3 changed files with 205 additions and 110 deletions

View File

@ -21,10 +21,10 @@ import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.DynamicToolbar.PinReason;
import org.mozilla.gecko.DynamicToolbar.VisibilityTransition;
import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
import org.mozilla.gecko.ReadingListHelper;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.animation.ViewHelper;
import org.mozilla.gecko.db.BrowserContract.Combined;
import org.mozilla.gecko.db.BrowserContract.ReadingListItems;
import org.mozilla.gecko.db.BrowserContract.SearchHistory;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.SuggestedSites;
@ -146,10 +146,6 @@ public class BrowserApp extends GeckoApp
private static final int TABS_ANIMATION_DURATION = 450;
private static final int READER_ADD_SUCCESS = 0;
private static final int READER_ADD_FAILED = 1;
private static final int READER_ADD_DUPLICATE = 2;
private static final String ADD_SHORTCUT_TOAST = "add_shortcut_toast";
public static final String GUEST_BROWSING_ARG = "--guest";
@ -229,6 +225,8 @@ public class BrowserApp extends GeckoApp
private BrowserHealthReporter mBrowserHealthReporter;
private ReadingListHelper mReadingListHelper;
private SystemBarTintManager mTintManager;
// The tab to be selected on editing mode exit.
@ -433,90 +431,6 @@ public class BrowserApp extends GeckoApp
return super.onKeyUp(keyCode, event);
}
void handleReaderListStatusRequest(final String url) {
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
final int inReadingList = BrowserDB.isReadingListItem(getContentResolver(), url) ? 1 : 0;
final JSONObject json = new JSONObject();
try {
json.put("url", url);
json.put("inReadingList", inReadingList);
} catch (JSONException e) {
Log.e(LOGTAG, "JSON error - failed to return inReadingList status", e);
return;
}
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Reader:ListStatusReturn", json.toString()));
}
});
}
private void handleReaderAdded(int result, final ContentValues values) {
if (result != READER_ADD_SUCCESS) {
if (result == READER_ADD_FAILED) {
showToast(R.string.reading_list_failed, Toast.LENGTH_SHORT);
} else if (result == READER_ADD_DUPLICATE) {
showToast(R.string.reading_list_duplicate, Toast.LENGTH_SHORT);
}
return;
}
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
BrowserDB.addReadingListItem(getContentResolver(), values);
showToast(R.string.reading_list_added, Toast.LENGTH_SHORT);
}
});
}
private ContentValues messageToReadingListContentValues(JSONObject message) {
final ContentValues values = new ContentValues();
values.put(ReadingListItems.URL, message.optString("url"));
values.put(ReadingListItems.TITLE, message.optString("title"));
values.put(ReadingListItems.LENGTH, message.optInt("length"));
values.put(ReadingListItems.EXCERPT, message.optString("excerpt"));
return values;
}
void handleReaderRemoved(final String url) {
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
BrowserDB.removeReadingListItemWithURL(getContentResolver(), url);
showToast(R.string.page_removed, Toast.LENGTH_SHORT);
}
});
}
private void handleReaderFaviconRequest(final String url) {
(new UIAsyncTask.WithoutParams<String>(ThreadUtils.getBackgroundHandler()) {
@Override
public String doInBackground() {
return Favicons.getFaviconURLForPageURL(getContext(), url);
}
@Override
public void onPostExecute(String faviconUrl) {
JSONObject args = new JSONObject();
if (faviconUrl != null) {
try {
args.put("url", url);
args.put("faviconUrl", faviconUrl);
} catch (JSONException e) {
Log.w(LOGTAG, "Error building JSON favicon arguments.", e);
}
}
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Reader:FaviconReturn", args.toString()));
}
}).execute();
}
@Override
public void onCreate(Bundle savedInstanceState) {
mAboutHomeStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_ABOUTHOME");
@ -600,8 +514,6 @@ public class BrowserApp extends GeckoApp
EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener)this,
"Menu:Update",
"Reader:Added",
"Reader:FaviconRequest",
"Search:Keyword",
"Prompt:ShowTop",
"Accounts:Exist");
@ -615,8 +527,6 @@ public class BrowserApp extends GeckoApp
"Feedback:OpenPlayStore",
"Menu:Add",
"Menu:Remove",
"Reader:ListStatusRequest",
"Reader:Removed",
"Reader:Share",
"Settings:Show",
"Telemetry:Gather",
@ -633,6 +543,7 @@ public class BrowserApp extends GeckoApp
mSharedPreferencesHelper = new SharedPreferencesHelper(appContext);
mOrderedBroadcastHelper = new OrderedBroadcastHelper(appContext);
mBrowserHealthReporter = new BrowserHealthReporter();
mReadingListHelper = new ReadingListHelper(appContext);
if (AppConstants.MOZ_ANDROID_BEAM) {
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
@ -1142,10 +1053,13 @@ public class BrowserApp extends GeckoApp
mBrowserHealthReporter = null;
}
if (mReadingListHelper != null) {
mReadingListHelper.uninit();
mReadingListHelper = null;
}
EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventListener)this,
"Menu:Update",
"Reader:Added",
"Reader:FaviconRequest",
"Search:Keyword",
"Prompt:ShowTop",
"Accounts:Exist");
@ -1159,8 +1073,6 @@ public class BrowserApp extends GeckoApp
"Feedback:OpenPlayStore",
"Menu:Add",
"Menu:Remove",
"Reader:ListStatusRequest",
"Reader:Removed",
"Reader:Share",
"Settings:Show",
"Telemetry:Gather",
@ -1519,13 +1431,6 @@ public class BrowserApp extends GeckoApp
}
});
} else if ("Reader:ListStatusRequest".equals(event)) {
handleReaderListStatusRequest(message.getString("url"));
} else if ("Reader:Removed".equals(event)) {
final String url = message.getString("url");
handleReaderRemoved(url);
} else if ("Reader:Share".equals(event)) {
final String title = message.getString("title");
final String url = message.getString("url");
@ -1640,12 +1545,6 @@ public class BrowserApp extends GeckoApp
DataReportingNotification.checkAndNotifyPolicy(GeckoAppShell.getContext());
}
} else if (event.equals("Reader:Added")) {
final int result = message.getInt("result");
handleReaderAdded(result, messageToReadingListContentValues(message));
} else if (event.equals("Reader:FaviconRequest")) {
final String url = message.getString("url");
handleReaderFaviconRequest(url);
} else if (event.equals("Search:Keyword")) {
storeSearchQuery(message.getString("query"));
} else if (event.equals("Prompt:ShowTop")) {

View File

@ -0,0 +1,195 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import org.mozilla.gecko.db.BrowserContract.ReadingListItems;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.favicons.Favicons;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.NativeEventListener;
import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UIAsyncTask;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.widget.Toast;
public final class ReadingListHelper implements GeckoEventListener, NativeEventListener {
private static final String LOGTAG = "ReadingListHelper";
private static final int READER_ADD_SUCCESS = 0;
private static final int READER_ADD_FAILED = 1;
private static final int READER_ADD_DUPLICATE = 2;
protected final Context context;
public ReadingListHelper(Context context) {
this.context = context;
EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener) this,
"Reader:Added", "Reader:FaviconRequest");
EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener) this,
"Reader:ListStatusRequest", "Reader:Removed");
}
public void uninit() {
EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventListener) this,
"Reader:Added", "Reader:FaviconRequest");
EventDispatcher.getInstance().unregisterGeckoThreadListener((NativeEventListener) this,
"Reader:ListStatusRequest", "Reader:Removed");
}
@Override
public void handleMessage(String event, JSONObject message) {
switch(event) {
case "Reader:Added": {
handleReadingListAdded(message);
break;
}
case "Reader:FaviconRequest": {
handleReaderModeFaviconRequest(message.optString("url"));
break;
}
}
}
@Override
public void handleMessage(final String event, final NativeJSObject message,
final EventCallback callback) {
switch(event) {
case "Reader:Removed": {
handleReadingListRemoved(message.getString("url"));
break;
}
case "Reader:ListStatusRequest": {
handleReadingListStatusRequest(message.getString("url"));
break;
}
}
}
/**
* A page can be added to the ReadingList by long-tap of the page-action
* icon, or by tapping the readinglist-add icon in the ReaderMode banner.
*/
private void handleReadingListAdded(JSONObject message) {
final int result = message.optInt("result", READER_ADD_FAILED);
if (result != READER_ADD_SUCCESS) {
if (result == READER_ADD_FAILED) {
showToast(R.string.reading_list_failed, Toast.LENGTH_SHORT);
} else if (result == READER_ADD_DUPLICATE) {
showToast(R.string.reading_list_duplicate, Toast.LENGTH_SHORT);
}
return;
}
final ContentValues values = new ContentValues();
values.put(ReadingListItems.URL, message.optString("url"));
values.put(ReadingListItems.TITLE, message.optString("title"));
values.put(ReadingListItems.LENGTH, message.optInt("length"));
values.put(ReadingListItems.EXCERPT, message.optString("excerpt"));
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
BrowserDB.addReadingListItem(context.getContentResolver(), values);
showToast(R.string.reading_list_added, Toast.LENGTH_SHORT);
}
});
}
/**
* Gecko (ReaderMode) requests the page favicon to append to the
* document head for display.
*/
private void handleReaderModeFaviconRequest(final String url) {
(new UIAsyncTask.WithoutParams<String>(ThreadUtils.getBackgroundHandler()) {
@Override
public String doInBackground() {
return Favicons.getFaviconURLForPageURL(context, url);
}
@Override
public void onPostExecute(String faviconUrl) {
JSONObject args = new JSONObject();
if (faviconUrl != null) {
try {
args.put("url", url);
args.put("faviconUrl", faviconUrl);
} catch (JSONException e) {
Log.w(LOGTAG, "Error building JSON favicon arguments.", e);
}
}
GeckoAppShell.sendEventToGecko(
GeckoEvent.createBroadcastEvent("Reader:FaviconReturn", args.toString()));
}
}).execute();
}
/**
* A page can be removed from the ReadingList by panel context menu,
* or by tapping the readinglist-remove icon in the ReaderMode banner.
*/
private void handleReadingListRemoved(final String url) {
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
BrowserDB.removeReadingListItemWithURL(context.getContentResolver(), url);
showToast(R.string.page_removed, Toast.LENGTH_SHORT);
}
});
}
/**
* Gecko (ReaderMode) requests the page ReadingList status, to display
* the proper ReaderMode banner icon (readinglist-add / readinglist-remove).
*/
private void handleReadingListStatusRequest(final String url) {
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
final int inReadingList =
BrowserDB.isReadingListItem(context.getContentResolver(), url) ? 1 : 0;
final JSONObject json = new JSONObject();
try {
json.put("url", url);
json.put("inReadingList", inReadingList);
} catch (JSONException e) {
Log.e(LOGTAG, "JSON error - failed to return inReadingList status", e);
return;
}
GeckoAppShell.sendEventToGecko(
GeckoEvent.createBroadcastEvent("Reader:ListStatusReturn", json.toString()));
}
});
}
/**
* Show various status toasts.
*/
private void showToast(final int resId, final int duration) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, resId, duration).show();
}
});
}
}

View File

@ -368,6 +368,7 @@ gbjar.sources += [
'prompts/PromptService.java',
'prompts/TabInput.java',
'ReaderModeUtils.java',
'ReadingListHelper.java',
'RemoteClientsDialogFragment.java',
'RemoteTabsExpandableListAdapter.java',
'Restarter.java',