fragments;
- public FolioPageFragmentAdapter(FragmentManager fm, List spineReferences, String epubFileName, String bookId) {
- super(fm);
+ public FolioPageFragmentAdapter(FragmentManager fragmentManager, List spineReferences,
+ String epubFileName, String bookId) {
+ super(fragmentManager);
this.mSpineReferences = spineReferences;
this.mEpubFileName = epubFileName;
this.mBookId = bookId;
+ fragments = new ArrayList<>(Arrays.asList(new Fragment[mSpineReferences.size()]));
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ super.destroyItem(container, position, object);
+ fragments.set(position, null);
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+
+ Fragment fragment = (Fragment) super.instantiateItem(container, position);
+ fragments.set(position, fragment);
+ return fragment;
}
@Override
public Fragment getItem(int position) {
- FolioPageFragment mFolioPageFragment = FolioPageFragment.newInstance(position, mEpubFileName, mSpineReferences.get(position),mBookId);
- mFolioPageFragment.setFragmentPos(position);
- return mFolioPageFragment;
+
+ if (mSpineReferences.size() == 0 || position < 0 || position >= mSpineReferences.size())
+ return null;
+
+ Fragment fragment = fragments.get(position);
+ if (fragment == null) {
+ fragment = FolioPageFragment.newInstance(position,
+ mEpubFileName, mSpineReferences.get(position), mBookId);
+ fragments.set(position, fragment);
+ }
+ return fragment;
}
@Override
diff --git a/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java b/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java
index a02fe77ae..2024e2e7c 100644
--- a/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java
+++ b/folioreader/src/main/java/com/folioreader/ui/folio/fragment/FolioPageFragment.java
@@ -3,7 +3,6 @@
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
-import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
@@ -27,42 +26,43 @@
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
+import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bossturban.webviewmarker.TextSelectionSupport;
import com.folioreader.Config;
import com.folioreader.Constants;
+import com.folioreader.FolioReader;
import com.folioreader.R;
import com.folioreader.model.HighLight;
import com.folioreader.model.HighlightImpl;
import com.folioreader.model.ReadPosition;
import com.folioreader.model.ReadPositionImpl;
-import com.folioreader.model.event.AnchorIdEvent;
import com.folioreader.model.event.MediaOverlayHighlightStyleEvent;
import com.folioreader.model.event.MediaOverlayPlayPauseEvent;
import com.folioreader.model.event.MediaOverlaySpeedEvent;
import com.folioreader.model.event.ReloadDataEvent;
import com.folioreader.model.event.RewindIndexEvent;
import com.folioreader.model.event.UpdateHighlightEvent;
-import com.folioreader.model.event.WebViewPosition;
import com.folioreader.model.quickaction.ActionItem;
import com.folioreader.model.quickaction.QuickAction;
import com.folioreader.model.sqlite.HighLightTable;
import com.folioreader.ui.base.HtmlTask;
import com.folioreader.ui.base.HtmlTaskCallback;
import com.folioreader.ui.base.HtmlUtil;
-import com.folioreader.ui.folio.activity.FolioActivity;
+import com.folioreader.ui.folio.activity.FolioActivityCallback;
import com.folioreader.ui.folio.mediaoverlay.MediaController;
import com.folioreader.ui.folio.mediaoverlay.MediaControllerCallbacks;
import com.folioreader.util.AppUtil;
-import com.folioreader.FolioReader;
import com.folioreader.util.HighlightUtil;
import com.folioreader.util.SMILParser;
import com.folioreader.util.UiUtil;
+import com.folioreader.view.FolioWebView;
+import com.folioreader.view.LoadingView;
import com.folioreader.view.MediaControllerView;
-import com.folioreader.view.ObservableWebView;
import com.folioreader.view.VerticalSeekbar;
+import com.folioreader.view.WebViewPager;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -79,13 +79,16 @@
* Created by mahavir on 4/2/16.
*/
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
-public class FolioPageFragment extends Fragment implements HtmlTaskCallback, MediaControllerCallbacks, ObservableWebView.SeekBarListener {
+public class FolioPageFragment
+ extends Fragment
+ implements HtmlTaskCallback, MediaControllerCallbacks, FolioWebView.SeekBarListener {
+ public static final String LOG_TAG = FolioPageFragment.class.getSimpleName();
public static final String KEY_FRAGMENT_FOLIO_POSITION = "com.folioreader.ui.folio.fragment.FolioPageFragment.POSITION";
public static final String KEY_FRAGMENT_FOLIO_BOOK_TITLE = "com.folioreader.ui.folio.fragment.FolioPageFragment.BOOK_TITLE";
public static final String KEY_FRAGMENT_EPUB_FILE_NAME = "com.folioreader.ui.folio.fragment.FolioPageFragment.EPUB_FILE_NAME";
private static final String KEY_IS_SMIL_AVAILABLE = "com.folioreader.ui.folio.fragment.FolioPageFragment.IS_SMIL_AVAILABLE";
- public static final String TAG = FolioPageFragment.class.getSimpleName();
+ private static final String BUNDLE_READ_POSITION_CONFIG_CHANGE = "BUNDLE_READ_POSITION_CONFIG_CHANGE";
private static final int ACTION_ID_COPY = 1001;
private static final int ACTION_ID_SHARE = 1002;
@@ -109,26 +112,20 @@ public class FolioPageFragment extends Fragment implements HtmlTaskCallback, Med
private String rangy = "";
private String highlightId;
- public interface FolioPageFragmentCallback {
-
- int getChapterPosition();
-
- void setPagerToPosition(String href);
-
- ReadPosition getEntryReadPosition();
-
- void goToChapter(String href);
- }
+ private ReadPosition lastReadPosition;
+ private Bundle outState;
+ private Bundle savedInstanceState;
private View mRootView;
+ private LoadingView loadingView;
private VerticalSeekbar mScrollSeekbar;
- private ObservableWebView mWebview;
+ private FolioWebView mWebview;
+ private WebViewPager webViewPager;
private TextSelectionSupport mTextSelectionSupport;
private TextView mPagesLeftTextView, mMinutesLeftTextView;
- private FolioPageFragmentCallback mActivityCallback;
+ private FolioActivityCallback mActivityCallback;
- private int mScrollY;
private int mTotalMinutes;
private String mSelectedText;
private Animation mFadeInAnimation, mFadeOutAnimation;
@@ -137,9 +134,7 @@ public interface FolioPageFragmentCallback {
private int mPosition = -1;
private String mBookTitle;
private String mEpubFileName = null;
- private int mPos;
private boolean mIsPageReloaded;
- private int mLastWebviewScrollpos;
private String highlightStyle;
@@ -162,8 +157,10 @@ public static FolioPageFragment newInstance(int position, String bookTitle, Link
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
- if (getActivity() instanceof FolioPageFragmentCallback)
- mActivityCallback = (FolioPageFragmentCallback) getActivity();
+ this.savedInstanceState = savedInstanceState;
+
+ if (getActivity() instanceof FolioActivityCallback)
+ mActivityCallback = (FolioActivityCallback) getActivity();
EventBus.getDefault().register(this);
if ((savedInstanceState != null)
@@ -181,6 +178,7 @@ public View onCreateView(LayoutInflater inflater,
spineItem = (Link) getArguments().getSerializable(SPINE_ITEM);
mBookId = getArguments().getString(FolioReader.INTENT_BOOK_ID);
}
+
if (spineItem != null) {
if (spineItem.properties.contains("media-overlay")) {
mediaController = new MediaController(getActivity(), MediaController.MediaType.SMIL, this);
@@ -191,14 +189,13 @@ public View onCreateView(LayoutInflater inflater,
}
}
highlightStyle = HighlightImpl.HighlightStyle.classForStyle(HighlightImpl.HighlightStyle.Normal);
- mRootView = View.inflate(getActivity(), R.layout.folio_page_fragment, null);
+ mRootView = inflater.inflate(R.layout.folio_page_fragment, container, false);
mPagesLeftTextView = (TextView) mRootView.findViewById(R.id.pagesLeft);
mMinutesLeftTextView = (TextView) mRootView.findViewById(R.id.minutesLeft);
- Activity activity = getActivity();
-
- mConfig = AppUtil.getSavedConfig(activity);
+ mConfig = AppUtil.getSavedConfig(getContext());
+ loadingView = mRootView.findViewById(R.id.loadingView);
initSeekbar();
initAnimations();
initWebView();
@@ -207,27 +204,13 @@ public View onCreateView(LayoutInflater inflater,
return mRootView;
}
-
private String getWebviewUrl() {
return Constants.LOCALHOST + mBookTitle + "/" + spineItem.href;
}
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- float positionTopView = mWebview.getTop();
- float contentHeight = mWebview.getContentHeight();
- float currentScrollPosition = mScrollY;
- float percentWebview = (currentScrollPosition - positionTopView) / contentHeight;
- float webviewsize = mWebview.getContentHeight() - mWebview.getTop();
- float positionInWV = webviewsize * percentWebview;
- int positionY = Math.round(mWebview.getTop() + positionInWV);
- mScrollY = positionY;
- }
-
/**
* [EVENT BUS FUNCTION]
- * Function triggered from {@link FolioActivity#initAudioView()} when pause/play
+ * Function triggered from {@link MediaControllerView#initListeners()} when pause/play
* button is clicked
*
* @param event of type {@link MediaOverlayPlayPauseEvent} contains if paused/played
@@ -294,8 +277,13 @@ public void styleChanged(MediaOverlayHighlightStyleEvent event) {
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void reload(ReloadDataEvent reloadDataEvent) {
+
+ if (isCurrentFragment())
+ getLastReadPosition();
+
if (isAdded()) {
- mLastWebviewScrollpos = mWebview.getScrollY();
+ loadingView.updateTheme();
+ loadingView.show();
mIsPageReloaded = true;
setHtml(true);
updatePagesLeftTextBg();
@@ -304,7 +292,7 @@ public void reload(ReloadDataEvent reloadDataEvent) {
/**
* [EVENT BUS FUNCTION]
- *
+ *
* Function triggered when highlight is deleted and page is needed to
* be updated.
*
@@ -312,28 +300,21 @@ public void reload(ReloadDataEvent reloadDataEvent) {
*/
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
- public void updateHighlight(UpdateHighlightEvent event){
- if(isAdded()) {
+ public void updateHighlight(UpdateHighlightEvent event) {
+ if (isAdded()) {
this.rangy = HighlightUtil.generateRangyString(getPageName());
loadRangy(mWebview, this.rangy);
}
}
- /**
- * [EVENT BUS FUNCTION]
- * Function triggered from {@link FolioActivity#onActivityResult(int, int, Intent)} when any item in toc clicked.
- *
- * @param event of type {@link AnchorIdEvent} contains selected chapter href.
- */
- @Subscribe(threadMode = ThreadMode.MAIN)
- public void jumpToAnchorPoint(AnchorIdEvent event) {
- if (isAdded() && event != null && event.getHref() != null) {
- String href = event.getHref();
- if (href != null && href.indexOf('#') != -1 && spineItem.href.equals(href.substring(0, href.lastIndexOf('#')))) {
- mAnchorId = href.substring(href.lastIndexOf('#') + 1);
- if (mWebview.getContentHeight() > 0 && mAnchorId != null) {
- mWebview.loadUrl("javascript:document.getElementById(\"" + mAnchorId + "\").scrollIntoView()");
- }
+ public void scrollToAnchorId(String href) {
+
+ if (!TextUtils.isEmpty(href) && href.indexOf('#') != -1) {
+ mAnchorId = href.substring(href.lastIndexOf('#') + 1);
+ if (loadingView != null && loadingView.getVisibility() != View.VISIBLE) {
+ loadingView.show();
+ mWebview.loadUrl(String.format(getString(R.string.go_to_anchor), mAnchorId));
+ mAnchorId = null;
}
}
}
@@ -361,32 +342,71 @@ private void setHtml(boolean reloaded) {
mediaController.setSMILItems(SMILParser.parseSMIL(mHtmlString));
mediaController.setUpMediaPlayer(spineItem.mediaOverlay, spineItem.mediaOverlay.getAudioPath(spineItem.href), mBookTitle);
}
- mConfig = AppUtil.getSavedConfig(getActivity());
+ mConfig = AppUtil.getSavedConfig(getContext());
String path = "";
int forwardSlashLastIndex = ref.lastIndexOf('/');
if (forwardSlashLastIndex != -1)
path = ref.substring(0, forwardSlashLastIndex + 1);
+ String mimeType;
+ if (spineItem.typeLink.equalsIgnoreCase(getString(R.string.xhtml_mime_type))) {
+ mimeType = getString(R.string.xhtml_mime_type);
+ } else {
+ mimeType = getString(R.string.html_mime_type);
+ }
+
mWebview.loadDataWithBaseURL(
Constants.LOCALHOST + mBookTitle + "/" + path,
- HtmlUtil.getHtmlContent(getActivity(), mHtmlString, mConfig),
- "text/html",
+ HtmlUtil.getHtmlContent(getContext(), mHtmlString, mConfig),
+ mimeType,
"UTF-8",
null);
}
}
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public String getDirection() {
+ return mActivityCallback.getDirection().toString();
+ }
+
+ public void scrollToLast() {
+
+ boolean isPageLoading = loadingView == null || loadingView.getVisibility() == View.VISIBLE;
+ Log.v(LOG_TAG, "-> scrollToLast -> isPageLoading = " + isPageLoading);
+
+ if (!isPageLoading) {
+ loadingView.show();
+ mWebview.loadUrl("javascript:scrollToLast()");
+ }
+ }
+
+ public void scrollToFirst() {
+
+ boolean isPageLoading = loadingView == null || loadingView.getVisibility() == View.VISIBLE;
+ Log.v(LOG_TAG, "-> scrollToFirst -> isPageLoading = " + isPageLoading);
+
+ if (!isPageLoading) {
+ loadingView.show();
+ mWebview.loadUrl("javascript:scrollToFirst()");
+ }
+ }
+
private void initWebView() {
- mWebview = (ObservableWebView) mRootView.findViewById(R.id.contentWebView);
- mWebview.setSeekBarListener(FolioPageFragment.this);
- if (getActivity() instanceof ObservableWebView.ToolBarListener)
- mWebview.setToolBarListener((ObservableWebView.ToolBarListener) getActivity());
+ FrameLayout webViewLayout = mRootView.findViewById(R.id.webViewLayout);
+ mWebview = webViewLayout.findViewById(R.id.folioWebView);
+ webViewPager = webViewLayout.findViewById(R.id.webViewPager);
+
+ if (getActivity() instanceof FolioActivityCallback)
+ mWebview.setFolioActivityCallback((FolioActivityCallback) getActivity());
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if (getActivity() instanceof FolioWebView.ToolBarListener)
+ mWebview.setToolBarListener((FolioWebView.ToolBarListener) getActivity());
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
WebView.setWebContentsDebuggingEnabled(true);
- }
setupScrollBar();
mWebview.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@@ -408,174 +428,145 @@ public void onLayoutChange(View view, int left, int top, int right, int bottom,
mWebview.addJavascriptInterface(this, "Highlight");
mWebview.addJavascriptInterface(this, "FolioPageFragment");
+ mWebview.addJavascriptInterface(webViewPager, "WebViewPager");
+ mWebview.addJavascriptInterface(loadingView, "LoadingView");
+ mWebview.addJavascriptInterface(mWebview, "FolioWebView");
- mWebview.setScrollListener(new ObservableWebView.ScrollListener() {
+ mWebview.setScrollListener(new FolioWebView.ScrollListener() {
@Override
public void onScrollChange(int percent) {
- if (mWebview.getScrollY() != 0)
- mScrollY = mWebview.getScrollY();
-
mScrollSeekbar.setProgressAndThumb(percent);
updatePagesLeftText(percent);
}
});
- mWebview.setWebViewClient(new WebViewClient() {
+ mWebview.setWebViewClient(webViewClient);
+ mWebview.setWebChromeClient(webChromeClient);
+
+ mTextSelectionSupport = TextSelectionSupport.support(getActivity(), mWebview);
+ mTextSelectionSupport.setSelectionListener(new TextSelectionSupport.SelectionListener() {
+ @Override
+ public void startSelection() {
+ }
+
@Override
- public void onPageFinished(WebView view, String url) {
+ public void selectionChanged(String text) {
+ mSelectedText = text;
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebview.loadUrl("javascript:alert(getRectForSelectedText())");
+ }
+ });
+ }
- if (isAdded()) {
+ @Override
+ public void endSelection() {
- view.loadUrl("javascript:alert(getReadingTime())");
+ }
+ });
- if (!hasMediaOverlay)
- view.loadUrl("javascript:wrappingSentencesWithinPTags()");
+ mWebview.getSettings().setDefaultTextEncodingName("utf-8");
+ new HtmlTask(this).execute(getWebviewUrl());
+ }
- view.loadUrl(String.format(getString(R.string.setmediaoverlaystyle),
- HighlightImpl.HighlightStyle.classForStyle(
- HighlightImpl.HighlightStyle.Normal)));
+ private WebViewClient webViewClient = new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {
- String rangy = HighlightUtil.generateRangyString(getPageName());
- FolioPageFragment.this.rangy = rangy;
- if (!rangy.isEmpty())
- loadRangy(view, rangy);
+ if (isAdded()) {
- if (mIsPageReloaded) {
- setWebViewPosition(mLastWebviewScrollpos);
- mIsPageReloaded = false;
- } else if (!TextUtils.isEmpty(mAnchorId)) {
- view.loadUrl("javascript:document.getElementById(\"" + mAnchorId + "\").scrollIntoView()");
- } else if (!TextUtils.isEmpty(highlightId)) {
- scrollToHighlightId();
- } else if (isCurrentFragment()) {
-
- ReadPosition entryReadPosition = mActivityCallback.getEntryReadPosition();
- if (entryReadPosition != null) {
- mWebview.loadUrl(String.format("javascript:scrollToSpan(%b, %s)",
- entryReadPosition.isUsingId(), entryReadPosition.getValue()));
- }
- }
- }
- }
+ mWebview.loadUrl("javascript:getCompatMode()");
+ mWebview.loadUrl("javascript:alert(getReadingTime())");
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- if (!url.isEmpty() && url.length() > 0) {
- if (Uri.parse(url).getScheme().startsWith("highlight")) {
- final Pattern pattern = Pattern.compile(getString(R.string.pattern));
- try {
- String htmlDecode = URLDecoder.decode(url, "UTF-8");
- Matcher matcher = pattern.matcher(htmlDecode.substring(12));
- if (matcher.matches()) {
- double left = Double.parseDouble(matcher.group(1));
- double top = Double.parseDouble(matcher.group(2));
- double width = Double.parseDouble(matcher.group(3));
- double height = Double.parseDouble(matcher.group(4));
- onHighlight((int) (UiUtil.convertDpToPixel((float) left,
- getActivity())),
- (int) (UiUtil.convertDpToPixel((float) top,
- getActivity())),
- (int) (UiUtil.convertDpToPixel((float) width,
- getActivity())),
- (int) (UiUtil.convertDpToPixel((float) height,
- getActivity())));
- }
- } catch (UnsupportedEncodingException e) {
- Log.d(TAG, e.getMessage());
- }
+ if (!hasMediaOverlay)
+ mWebview.loadUrl("javascript:wrappingSentencesWithinPTags()");
+
+ if (mActivityCallback.getDirection() == Config.Direction.HORIZONTAL)
+ mWebview.loadUrl("javascript:initHorizontalDirection()");
+
+ view.loadUrl(String.format(getString(R.string.setmediaoverlaystyle),
+ HighlightImpl.HighlightStyle.classForStyle(
+ HighlightImpl.HighlightStyle.Normal)));
+
+ String rangy = HighlightUtil.generateRangyString(getPageName());
+ FolioPageFragment.this.rangy = rangy;
+ if (!rangy.isEmpty())
+ loadRangy(mWebview, rangy);
+
+ if (mIsPageReloaded) {
+
+ if (isCurrentFragment()) {
+ mWebview.loadUrl(String.format("javascript:scrollToSpan(%b, %s)",
+ lastReadPosition.isUsingId(), lastReadPosition.getValue()));
} else {
- if (url.contains("storage")) {
- mActivityCallback.setPagerToPosition(url);
- } else if (url.endsWith(".xhtml") || url.endsWith(".html")) {
- mActivityCallback.goToChapter(url);
+ if (mPosition == mActivityCallback.getChapterPosition() - 1) {
+ // Scroll to last, the page before current page
+ mWebview.loadUrl("javascript:scrollToLast()");
} else {
- // Otherwise, give the default behavior (open in browser)
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- startActivity(intent);
+ // Make loading view invisible for all other fragments
+ loadingView.hide();
}
}
- }
- return true;
- }
- // prevent favicon.ico to be loaded automatically
- @Override
- public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
- if(url.toLowerCase().contains("/favicon.ico")) {
- try {
- return new WebResourceResponse("image/png", null, null);
- } catch (Exception e) {
- Log.e(TAG, "shouldInterceptRequest failed", e);
+ mIsPageReloaded = false;
+
+ } else if (!TextUtils.isEmpty(mAnchorId)) {
+ mWebview.loadUrl(String.format(getString(R.string.go_to_anchor), mAnchorId));
+ mAnchorId = null;
+
+ } else if (!TextUtils.isEmpty(highlightId)) {
+ mWebview.loadUrl(String.format(getString(R.string.go_to_highlight), highlightId));
+ highlightId = null;
+
+ } else if (isCurrentFragment()) {
+
+ ReadPosition readPosition;
+ if (savedInstanceState == null) {
+ Log.v(LOG_TAG, "-> onPageFinished -> took from getEntryReadPosition");
+ readPosition = mActivityCallback.getEntryReadPosition();
+ } else {
+ Log.v(LOG_TAG, "-> onPageFinished -> took from bundle");
+ readPosition = savedInstanceState.getParcelable(BUNDLE_READ_POSITION_CONFIG_CHANGE);
+ savedInstanceState.remove(BUNDLE_READ_POSITION_CONFIG_CHANGE);
}
- }
- return null;
- }
- // prevent favicon.ico to be loaded automatically
- @Override
- @SuppressLint("NewApi")
- public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
- if(!request.isForMainFrame() && request.getUrl().getPath().endsWith("/favicon.ico")) {
- try {
- return new WebResourceResponse("image/png", null, null);
- } catch (Exception e) {
- Log.e(TAG, "shouldInterceptRequest failed", e);
+ if (readPosition != null) {
+ Log.v(LOG_TAG, "-> scrollToSpan -> " + readPosition.getValue());
+ mWebview.loadUrl(String.format("javascript:scrollToSpan(%b, %s)",
+ readPosition.isUsingId(), readPosition.getValue()));
+ } else {
+ loadingView.hide();
}
- }
- return null;
- }
- });
- mWebview.setWebChromeClient(new WebChromeClient() {
- @Override
- public void onProgressChanged(WebView view, int progress) {
-
- if (view.getProgress() == 100) {
- mWebview.postDelayed(new Runnable() {
- @Override
- public void run() {
- Log.d("scroll y", "Scrolly" + mScrollY);
- mWebview.scrollTo(0, mScrollY);
- }
- }, 100);
+ } else {
+
+ if (mPosition == mActivityCallback.getChapterPosition() - 1) {
+ // Scroll to last, the page before current page
+ mWebview.loadUrl("javascript:scrollToLast()");
+ } else {
+ // Make loading view invisible for all other fragments
+ loadingView.hide();
+ }
}
}
+ }
- @Override
- public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
- if (FolioPageFragment.this.isVisible()) {
- String rangyPattern = "\\d+\\$\\d+\\$\\d+\\$\\w+\\$";
- Pattern pattern = Pattern.compile(rangyPattern);
- Matcher matcher = pattern.matcher(message);
- if (matcher.matches()) {
- HighlightImpl highlightImpl = HighLightTable.getHighlightForRangy(message);
- if (HighLightTable.deleteHighlight(message)) {
- String rangy = HighlightUtil.generateRangyString(getPageName());
- loadRangy(view, rangy);
- mTextSelectionSupport.endSelectionMode();
- if (highlightImpl != null) {
- HighlightUtil.sendHighlightBroadcastEvent(
- FolioPageFragment.this.getActivity().getApplicationContext(),
- highlightImpl,
- HighLight.HighLightAction.DELETE);
- }
- }
- } else if (TextUtils.isDigitsOnly(message)) {
- try {
- mTotalMinutes = Integer.parseInt(message);
- } catch (NumberFormatException e) {
- mTotalMinutes = 0;
- }
- } else {
- pattern = Pattern.compile(getString(R.string.pattern));
- matcher = pattern.matcher(message);
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ if (!url.isEmpty() && url.length() > 0) {
+ if (Uri.parse(url).getScheme().startsWith("highlight")) {
+ final Pattern pattern = Pattern.compile(getString(R.string.pattern));
+ try {
+ String htmlDecode = URLDecoder.decode(url, "UTF-8");
+ Matcher matcher = pattern.matcher(htmlDecode.substring(12));
if (matcher.matches()) {
double left = Double.parseDouble(matcher.group(1));
double top = Double.parseDouble(matcher.group(2));
double width = Double.parseDouble(matcher.group(3));
double height = Double.parseDouble(matcher.group(4));
- showTextSelectionMenu((int) (UiUtil.convertDpToPixel((float) left,
+ onHighlight((int) (UiUtil.convertDpToPixel((float) left,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) top,
getActivity())),
@@ -583,46 +574,115 @@ public boolean onJsAlert(WebView view, String url, String message, JsResult resu
getActivity())),
(int) (UiUtil.convertDpToPixel((float) height,
getActivity())));
- } else {
- // to handle TTS playback when highlight is deleted.
- Pattern p = Pattern.compile("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}");
- if (!p.matcher(message).matches() && (!message.equals("undefined")) && isCurrentFragment()) {
- mediaController.speakAudio(message);
- }
}
+ } catch (UnsupportedEncodingException e) {
+ Log.d(LOG_TAG, e.getMessage());
+ }
+ } else {
+ if (url.contains("storage")) {
+ mActivityCallback.setPagerToPosition(url);
+ } else if (url.endsWith(".xhtml") || url.endsWith(".html")) {
+ mActivityCallback.goToChapter(url);
+ } else {
+ // Otherwise, give the default behavior (open in browser)
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ startActivity(intent);
}
- result.confirm();
}
- return true;
}
- });
+ return true;
+ }
- mTextSelectionSupport = TextSelectionSupport.support(getActivity(), mWebview);
- mTextSelectionSupport.setSelectionListener(new TextSelectionSupport.SelectionListener() {
- @Override
- public void startSelection() {
+ // prevent favicon.ico to be loaded automatically
+ @Override
+ public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
+ if (url.toLowerCase().contains("/favicon.ico")) {
+ try {
+ return new WebResourceResponse("image/png", null, null);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "shouldInterceptRequest failed", e);
+ }
}
+ return null;
+ }
- @Override
- public void selectionChanged(String text) {
- mSelectedText = text;
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebview.loadUrl("javascript:alert(getRectForSelectedText())");
- }
- });
+ // prevent favicon.ico to be loaded automatically
+ @Override
+ @SuppressLint("NewApi")
+ public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
+ if (!request.isForMainFrame()
+ && request.getUrl().getPath() != null
+ && request.getUrl().getPath().endsWith("/favicon.ico")) {
+ try {
+ return new WebResourceResponse("image/png", null, null);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "shouldInterceptRequest failed", e);
+ }
}
+ return null;
+ }
+ };
- @Override
- public void endSelection() {
+ private WebChromeClient webChromeClient = new WebChromeClient() {
- }
- });
+ @Override
+ public void onProgressChanged(WebView view, int progress) {
+ }
- mWebview.getSettings().setDefaultTextEncodingName("utf-8");
- new HtmlTask(this).execute(getWebviewUrl());
- }
+ @Override
+ public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
+ if (FolioPageFragment.this.isVisible()) {
+ String rangyPattern = "\\d+\\$\\d+\\$\\d+\\$\\w+\\$";
+ Pattern pattern = Pattern.compile(rangyPattern);
+ Matcher matcher = pattern.matcher(message);
+ if (matcher.matches()) {
+ HighlightImpl highlightImpl = HighLightTable.getHighlightForRangy(message);
+ if (HighLightTable.deleteHighlight(message)) {
+ String rangy = HighlightUtil.generateRangyString(getPageName());
+ loadRangy(view, rangy);
+ mTextSelectionSupport.endSelectionMode();
+ if (highlightImpl != null) {
+ HighlightUtil.sendHighlightBroadcastEvent(
+ FolioPageFragment.this.getActivity().getApplicationContext(),
+ highlightImpl,
+ HighLight.HighLightAction.DELETE);
+ }
+ }
+ } else if (TextUtils.isDigitsOnly(message)) {
+ try {
+ mTotalMinutes = Integer.parseInt(message);
+ } catch (NumberFormatException e) {
+ mTotalMinutes = 0;
+ }
+ } else {
+ pattern = Pattern.compile(getString(R.string.pattern));
+ matcher = pattern.matcher(message);
+ if (matcher.matches()) {
+ double left = Double.parseDouble(matcher.group(1));
+ double top = Double.parseDouble(matcher.group(2));
+ double width = Double.parseDouble(matcher.group(3));
+ double height = Double.parseDouble(matcher.group(4));
+ showTextSelectionMenu((int) (UiUtil.convertDpToPixel((float) left,
+ getActivity())),
+ (int) (UiUtil.convertDpToPixel((float) top,
+ getActivity())),
+ (int) (UiUtil.convertDpToPixel((float) width,
+ getActivity())),
+ (int) (UiUtil.convertDpToPixel((float) height,
+ getActivity())));
+ } else {
+ // to handle TTS playback when highlight is deleted.
+ Pattern p = Pattern.compile("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}");
+ if (!p.matcher(message).matches() && (!message.equals("undefined")) && isCurrentFragment()) {
+ mediaController.speakAudio(message);
+ }
+ }
+ }
+ result.confirm();
+ }
+ return true;
+ }
+ };
/**
* Calls the /assets/js/Bridge.js#getFirstVisibleSpan(boolean)
@@ -630,19 +690,31 @@ public void endSelection() {
@Override
public void onStop() {
super.onStop();
+ Log.v(LOG_TAG, "-> onStop -> " + spineItem.originalHref + " -> " + isCurrentFragment());
+
mediaController.stop();
//TODO save last media overlay item
- if (isCurrentFragment()) {
- try {
- synchronized (this) {
- mWebview.loadUrl("javascript:getFirstVisibleSpan(false)");
- wait(2000);
- }
- } catch (InterruptedException e) {
- Log.e(TAG, "-> " + e);
+ if (isCurrentFragment())
+ getLastReadPosition();
+ }
+
+ public ReadPosition getLastReadPosition() {
+ Log.v(LOG_TAG, "-> getLastReadPosition -> " + spineItem.originalHref);
+
+ try {
+ synchronized (this) {
+ boolean isHorizontal = mActivityCallback.getDirection() ==
+ Config.Direction.HORIZONTAL;
+ mWebview.loadUrl("javascript:getFirstVisibleSpan(" + isHorizontal +")");
+
+ wait(2000);
}
+ } catch (InterruptedException e) {
+ Log.e(LOG_TAG, "-> " + e);
}
+
+ return lastReadPosition;
}
/**
@@ -652,19 +724,30 @@ public void onStop() {
* @param usingId if span tag has id then true or else false
* @param value if usingId true then span id else span index
*/
+ @SuppressWarnings("unused")
@JavascriptInterface
public void storeFirstVisibleSpan(boolean usingId, String value) {
synchronized (this) {
- ReadPositionImpl readPositionImpl = new ReadPositionImpl(mBookId, spineItem.getId(),
+ lastReadPosition = new ReadPositionImpl(mBookId, spineItem.getId(),
spineItem.getOriginalHref(), mPosition, usingId, value);
Intent intent = new Intent(FolioReader.ACTION_SAVE_READ_POSITION);
- intent.putExtra(FolioReader.EXTRA_READ_POSITION, readPositionImpl);
+ intent.putExtra(FolioReader.EXTRA_READ_POSITION, lastReadPosition);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
+
notify();
}
}
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void setHorizontalPageCount(int horizontalPageCount) {
+ Log.v(LOG_TAG, "-> setHorizontalPageCount = " + horizontalPageCount
+ + " -> " + spineItem.originalHref);
+
+ mWebview.setHorizontalPageCount(horizontalPageCount);
+ }
+
private void loadRangy(WebView view, String rangy) {
view.loadUrl(String.format("javascript:if(typeof ssReader !== \"undefined\"){ssReader.setHighlights('%s');}", rangy));
}
@@ -725,7 +808,7 @@ private void updatePagesLeftText(int scrollY) {
mMinutesLeftTextView.setText(minutesRemainingStr);
mPagesLeftTextView.setText(pagesRemainingStr);
- } catch (java.lang.ArithmeticException exp) {
+ } catch (java.lang.ArithmeticException | IllegalStateException exp) {
Log.d("divide error", exp.toString());
}
}
@@ -788,9 +871,22 @@ public void onDestroyView() {
super.onDestroyView();
}
+ /**
+ * If called, this method will occur after onStop() for applications targeting platforms
+ * starting with Build.VERSION_CODES.P. For applications targeting earlier platform versions
+ * this method will occur before onStop() and there are no guarantees about whether it will
+ * occur before or after onPause()
+ *
+ * @see Activity#onSaveInstanceState(Bundle) of Build.VERSION_CODES.P
+ */
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
+ this.outState = outState;
+
+ if (isCurrentFragment())
+ Log.v(LOG_TAG, "-> onSaveInstanceState");
+
outState.putInt(KEY_FRAGMENT_FOLIO_POSITION, mPosition);
outState.putString(KEY_FRAGMENT_FOLIO_BOOK_TITLE, mBookTitle);
outState.putString(KEY_FRAGMENT_EPUB_FILE_NAME, mEpubFileName);
@@ -994,30 +1090,6 @@ private String getPageName() {
return mBookTitle + "$" + spineItem.href;
}
- @SuppressWarnings("unused")
- @Subscribe(threadMode = ThreadMode.MAIN)
- public void setWebView(final WebViewPosition position) {
- if (position.getHref().equals(spineItem.href) && isAdded()) {
- highlightId = position.getHighlightId();
-
- if (mWebview.getContentHeight() > 0) {
- scrollToHighlightId();
- //Webview.loadUrl(String.format(getString(R.string.goto_highlight), highlightId));
- }
- }
- }
-
- public void setWebViewPosition(final int position) {
- mWebview.post(new Runnable() {
- @Override
- public void run() {
- if (isAdded()) {
- mWebview.scrollTo(0, position);
- }
- }
- });
- }
-
@Override
public void highLightText(String fragmentId) {
mWebview.loadUrl(String.format(getString(R.string.audio_mark_id), fragmentId));
@@ -1051,22 +1123,34 @@ public void run() {
@Override
public void onDestroy() {
super.onDestroy();
+
+ if (isCurrentFragment()) {
+ if (outState != null)
+ outState.putParcelable(BUNDLE_READ_POSITION_CONFIG_CHANGE, lastReadPosition);
+ mActivityCallback.storeLastReadPosition(lastReadPosition);
+ }
if (mWebview != null) mWebview.destroy();
}
private boolean isCurrentFragment() {
- return isAdded() && mActivityCallback.getChapterPosition() == mPos;
- }
-
- public void setFragmentPos(int pos) {
- mPos = pos;
+// Log.d(LOG_TAG, "-> isCurrentFragment -> "
+// + ", isAdded = " + isAdded()
+// + ", mActivityCallback.getChapterPosition() = " + mActivityCallback.getChapterPosition()
+// + ", mPosition = " + mPosition);
+ return isAdded() && mActivityCallback.getChapterPosition() == mPosition;
}
@Override
public void onError() {
}
- private void scrollToHighlightId() {
- mWebview.loadUrl(String.format(getString(R.string.goto_highlight), highlightId));
+ public void scrollToHighlightId(String highlightId) {
+ this.highlightId = highlightId;
+
+ if (loadingView != null && loadingView.getVisibility() != View.VISIBLE) {
+ loadingView.show();
+ mWebview.loadUrl(String.format(getString(R.string.go_to_highlight), highlightId));
+ this.highlightId = null;
+ }
}
}
diff --git a/folioreader/src/main/java/com/folioreader/util/AppUtil.java b/folioreader/src/main/java/com/folioreader/util/AppUtil.java
index a06c69f8f..d6fef82dc 100644
--- a/folioreader/src/main/java/com/folioreader/util/AppUtil.java
+++ b/folioreader/src/main/java/com/folioreader/util/AppUtil.java
@@ -1,7 +1,9 @@
package com.folioreader.util;
import android.content.Context;
+import android.os.Build;
import android.util.Log;
+import android.view.MotionEvent;
import com.folioreader.Config;
import com.folioreader.Constants;
@@ -89,12 +91,13 @@ public static void saveConfig(Context context, Config config) {
try {
obj.put(Config.CONFIG_FONT, config.getFont());
obj.put(Config.CONFIG_FONT_SIZE, config.getFontSize());
- obj.put(Config.CONFIG_IS_NIGHTMODE, config.isNightMode());
- obj.put(Config.CONFIG_IS_THEMECOLOR, config.getThemeColor());
- obj.put(Config.CONFIG_IS_TTS,config.isShowTts());
- SharedPreferenceUtil.
- putSharedPreferencesString(
- context, Config.INTENT_CONFIG, obj.toString());
+ obj.put(Config.CONFIG_IS_NIGHT_MODE, config.isNightMode());
+ obj.put(Config.CONFIG_IS_THEME_COLOR, config.getThemeColor());
+ obj.put(Config.CONFIG_IS_TTS, config.isShowTts());
+ obj.put(Config.CONFIG_ALLOWED_DIRECTION, config.getAllowedDirection().toString());
+ obj.put(Config.CONFIG_DIRECTION, config.getDirection().toString());
+ SharedPreferenceUtil.putSharedPreferencesString(context, Config.INTENT_CONFIG,
+ obj.toString());
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
@@ -113,6 +116,48 @@ public static Config getSavedConfig(Context context) {
}
return null;
}
+
+ public static String actionToString(int action) {
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ return "ACTION_DOWN";
+ case MotionEvent.ACTION_UP:
+ return "ACTION_UP";
+ case MotionEvent.ACTION_CANCEL:
+ return "ACTION_CANCEL";
+ case MotionEvent.ACTION_OUTSIDE:
+ return "ACTION_OUTSIDE";
+ case MotionEvent.ACTION_MOVE:
+ return "ACTION_MOVE";
+ case MotionEvent.ACTION_HOVER_MOVE:
+ return "ACTION_HOVER_MOVE";
+ case MotionEvent.ACTION_SCROLL:
+ return "ACTION_SCROLL";
+ case MotionEvent.ACTION_HOVER_ENTER:
+ return "ACTION_HOVER_ENTER";
+ case MotionEvent.ACTION_HOVER_EXIT:
+ return "ACTION_HOVER_EXIT";
+ }
+
+ if (Build.VERSION.SDK_INT >= 23) {
+ switch(action) {
+ case MotionEvent.ACTION_BUTTON_PRESS:
+ return "ACTION_BUTTON_PRESS";
+ case MotionEvent.ACTION_BUTTON_RELEASE:
+ return "ACTION_BUTTON_RELEASE";
+ }
+ }
+
+ int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_POINTER_DOWN:
+ return "ACTION_POINTER_DOWN(" + index + ")";
+ case MotionEvent.ACTION_POINTER_UP:
+ return "ACTION_POINTER_UP(" + index + ")";
+ default:
+ return Integer.toString(action);
+ }
+ }
}
diff --git a/folioreader/src/main/java/com/folioreader/util/UiUtil.java b/folioreader/src/main/java/com/folioreader/util/UiUtil.java
index 7676ed6de..9ccb78946 100644
--- a/folioreader/src/main/java/com/folioreader/util/UiUtil.java
+++ b/folioreader/src/main/java/com/folioreader/util/UiUtil.java
@@ -120,7 +120,7 @@ public static void setBackColorToTextView(UnderlinedTextView textView, String ty
}
- private static void setUnderLineColor(UnderlinedTextView underlinedTextView, Context context, int background,int underlinecolor) {
+ private static void setUnderLineColor(UnderlinedTextView underlinedTextView, Context context, int background, int underlinecolor) {
underlinedTextView.setBackgroundColor(ContextCompat.getColor(context,
background));
underlinedTextView.setUnderLineColor(ContextCompat.getColor(context,
diff --git a/folioreader/src/main/java/com/folioreader/view/ConfigBottomSheetDialogFragment.kt b/folioreader/src/main/java/com/folioreader/view/ConfigBottomSheetDialogFragment.kt
index f6623dc51..bf03e5aec 100644
--- a/folioreader/src/main/java/com/folioreader/view/ConfigBottomSheetDialogFragment.kt
+++ b/folioreader/src/main/java/com/folioreader/view/ConfigBottomSheetDialogFragment.kt
@@ -4,6 +4,7 @@ import android.animation.Animator
import android.animation.ArgbEvaluator
import android.animation.ValueAnimator
import android.app.Activity
+import android.os.Build
import android.os.Bundle
import android.support.design.widget.BottomSheetBehavior
import android.support.design.widget.BottomSheetDialog
@@ -18,6 +19,8 @@ import com.folioreader.Config
import com.folioreader.Constants
import com.folioreader.R
import com.folioreader.model.event.ReloadDataEvent
+import com.folioreader.ui.folio.activity.FolioActivity
+import com.folioreader.ui.folio.activity.FolioActivityCallback
import com.folioreader.util.AppUtil
import com.folioreader.util.UiUtil
import kotlinx.android.synthetic.main.view_config.*
@@ -27,20 +30,26 @@ import org.greenrobot.eventbus.EventBus
* Created by mobisys2 on 11/16/2016.
*/
class ConfigBottomSheetDialogFragment : BottomSheetDialogFragment() {
- private lateinit var callback: ConfigDialogCallback
- private lateinit var config: Config
- private var isNightMode = false
- interface ConfigDialogCallback {
- fun onOrientationChange(orientation: Int)
+ companion object {
+ const val FADE_DAY_NIGHT_MODE = 500
+ @JvmField val LOG_TAG:String = ConfigBottomSheetDialogFragment::class.java.simpleName
}
+ private lateinit var config: Config
+ private var isNightMode = false
+ private lateinit var activityCallback: FolioActivityCallback
+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.view_config, container)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+
+ if (activity is FolioActivity)
+ activityCallback = activity as FolioActivity
+
view.viewTreeObserver.addOnGlobalLayoutListener {
val dialog = dialog as BottomSheetDialog
val bottomSheet = dialog.findViewById(android.support.design.R.id.design_bottom_sheet) as FrameLayout?
@@ -82,11 +91,16 @@ class ConfigBottomSheetDialogFragment : BottomSheetDialogFragment() {
UiUtil.setColorToImage(activity, config.themeColor, view_config_ib_day_mode!!.drawable)
UiUtil.setColorToImage(activity, R.color.app_gray, view_config_ib_night_mode.drawable)
}
-
- callback = activity as ConfigDialogCallback
}
private fun inflateView() {
+
+ if (config.allowedDirection != Config.AllowedDirection.VERTICAL_AND_HORIZONTAL) {
+ view5.visibility = View.GONE
+ buttonVertical.visibility = View.GONE
+ buttonHorizontal.visibility = View.GONE
+ }
+
view_config_ib_day_mode.setOnClickListener {
isNightMode = true
toggleBlackTheme()
@@ -97,41 +111,57 @@ class ConfigBottomSheetDialogFragment : BottomSheetDialogFragment() {
UiUtil.setColorToImage(activity, R.color.app_gray, view_config_ib_night_mode.drawable)
UiUtil.setColorToImage(activity, config.themeColor, view_config_ib_day_mode.drawable)
}
+
view_config_ib_night_mode.setOnClickListener {
isNightMode = false
toggleBlackTheme()
view_config_ib_day_mode.isSelected = false
view_config_ib_night_mode.isSelected = true
- UiUtil.setColorToImage(activity, config.themeColor, view_config_ib_day_mode.drawable)
- UiUtil.setColorToImage(activity, R.color.app_gray, view_config_ib_night_mode.drawable)
+ UiUtil.setColorToImage(activity, R.color.app_gray, view_config_ib_day_mode.drawable)
+ UiUtil.setColorToImage(activity, config.themeColor, view_config_ib_night_mode.drawable)
setToolBarColor()
setAudioPlayerBackground()
}
- view_config_btn_vertical_orientation.isSelected = true
+
+ if (activityCallback.direction == Config.Direction.HORIZONTAL) {
+ buttonHorizontal.isSelected = true
+ } else if (activityCallback.direction == Config.Direction.VERTICAL) {
+ buttonVertical.isSelected = true
+ }
+
+ buttonVertical.setOnClickListener {
+ config = AppUtil.getSavedConfig(context)
+ config.direction = Config.Direction.VERTICAL
+ AppUtil.saveConfig(context, config)
+ activityCallback.onDirectionChange(Config.Direction.VERTICAL)
+ buttonHorizontal.isSelected = false
+ buttonVertical.isSelected = true
+ }
+
+ buttonHorizontal.setOnClickListener {
+ config = AppUtil.getSavedConfig(context)
+ config.direction = Config.Direction.HORIZONTAL
+ AppUtil.saveConfig(context, config)
+ activityCallback.onDirectionChange(Config.Direction.HORIZONTAL)
+ buttonHorizontal.isSelected = true
+ buttonVertical.isSelected = false
+ }
}
private fun configFonts() {
- view_config_font_andada.setTextColor(UiUtil.getColorList(activity, config.themeColor, R.color.grey_color))
- view_config_font_lato.setTextColor(UiUtil.getColorList(activity, config.themeColor, R.color.grey_color))
- view_config_font_lora.setTextColor(UiUtil.getColorList(activity, config.themeColor, R.color.grey_color))
- view_config_font_raleway.setTextColor(UiUtil.getColorList(activity, config.themeColor, R.color.grey_color))
- view_config_btn_vertical_orientation.setTextColor(UiUtil.getColorList(activity, config.themeColor, R.color.grey_color))
- view_config_btn_horizontal_orientation.setTextColor(UiUtil.getColorList(activity, config.themeColor, R.color.grey_color))
+
+ val colorStateList = UiUtil.getColorList(activity, config.themeColor, R.color.grey_color)
+ buttonVertical.setTextColor(colorStateList)
+ buttonHorizontal.setTextColor(colorStateList)
+ view_config_font_andada.setTextColor(colorStateList)
+ view_config_font_lato.setTextColor(colorStateList)
+ view_config_font_lora.setTextColor(colorStateList)
+ view_config_font_raleway.setTextColor(colorStateList)
+
view_config_font_andada.setOnClickListener { selectFont(Constants.FONT_ANDADA, true) }
view_config_font_lato.setOnClickListener { selectFont(Constants.FONT_LATO, true) }
view_config_font_lora.setOnClickListener { selectFont(Constants.FONT_LORA, true) }
view_config_font_raleway.setOnClickListener { selectFont(Constants.FONT_RALEWAY, true) }
- view_config_btn_vertical_orientation.setOnClickListener {
- callback.onOrientationChange(1)
- view_config_btn_horizontal_orientation.isSelected = false
- view_config_btn_vertical_orientation.isSelected = true
- }
-
- view_config_btn_horizontal_orientation.setOnClickListener {
- callback.onOrientationChange(0)
- view_config_btn_horizontal_orientation.isSelected = true
- view_config_btn_vertical_orientation.isSelected = false
- }
}
private fun selectFont(selectedFont: Int, isReloadNeeded: Boolean) {
@@ -156,11 +186,14 @@ class ConfigBottomSheetDialogFragment : BottomSheetDialogFragment() {
}
private fun toggleBlackTheme() {
+
val day = ContextCompat.getColor(context!!, R.color.white)
val night = ContextCompat.getColor(context!!, R.color.night)
+
val colorAnimation = ValueAnimator.ofObject(ArgbEvaluator(),
if (isNightMode) night else day, if (isNightMode) day else night)
colorAnimation.duration = FADE_DAY_NIGHT_MODE.toLong()
+
colorAnimation.addUpdateListener { animator ->
val value = animator.animatedValue as Int
container.setBackgroundColor(value)
@@ -182,6 +215,28 @@ class ConfigBottomSheetDialogFragment : BottomSheetDialogFragment() {
})
colorAnimation.duration = FADE_DAY_NIGHT_MODE.toLong()
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+
+ val attrs = intArrayOf(android.R.attr.navigationBarColor)
+ val typedArray = activity?.theme?.obtainStyledAttributes(attrs)
+ val defaultNavigationBarColor = typedArray?.getColor(0,
+ ContextCompat.getColor(context!!, R.color.white))
+ val black = ContextCompat.getColor(context!!, R.color.black)
+
+ val navigationColorAnim = ValueAnimator.ofObject(ArgbEvaluator(),
+ if (isNightMode) black else defaultNavigationBarColor,
+ if (isNightMode) defaultNavigationBarColor else black)
+
+ navigationColorAnim.addUpdateListener { valueAnimator ->
+ val value = valueAnimator.animatedValue as Int
+ activity?.window?.navigationBarColor = value
+ }
+
+ navigationColorAnim.duration = FADE_DAY_NIGHT_MODE.toLong()
+ navigationColorAnim.start()
+ }
+
colorAnimation.start()
}
@@ -220,8 +275,4 @@ class ConfigBottomSheetDialogFragment : BottomSheetDialogFragment() {
(context as Activity).findViewById(R.id.container).setBackgroundColor(ContextCompat.getColor(context!!, R.color.night))
}
}
-
- companion object {
- const val FADE_DAY_NIGHT_MODE = 500
- }
}
diff --git a/folioreader/src/main/java/com/folioreader/view/DirectionalViewpager.java b/folioreader/src/main/java/com/folioreader/view/DirectionalViewpager.java
index 7ea607bac..fd5a67ca7 100644
--- a/folioreader/src/main/java/com/folioreader/view/DirectionalViewpager.java
+++ b/folioreader/src/main/java/com/folioreader/view/DirectionalViewpager.java
@@ -48,6 +48,7 @@
import android.view.animation.Interpolator;
import android.widget.Scroller;
+import com.folioreader.Config;
import com.folioreader.R;
import java.lang.reflect.Method;
@@ -4109,6 +4110,11 @@ public void setDirection(Direction direction) {
initViewPager();
}
+ public void setDirection(Config.Direction direction) {
+ mDirection = direction.name();
+ initViewPager();
+ }
+
private String logDestroyItem(int pos, View object) {
return "populate() - destroyItem() with pos: " + pos + " view: " + object;
}
diff --git a/folioreader/src/main/java/com/folioreader/view/FolioToolbar.kt b/folioreader/src/main/java/com/folioreader/view/FolioToolbar.kt
index bedc2d992..cea80ae3c 100644
--- a/folioreader/src/main/java/com/folioreader/view/FolioToolbar.kt
+++ b/folioreader/src/main/java/com/folioreader/view/FolioToolbar.kt
@@ -20,7 +20,7 @@ import kotlinx.android.synthetic.main.folio_toolbar.view.*
*/
class FolioToolbar : RelativeLayout {
private lateinit var config: Config
- private var visible: Boolean = false
+ var visible: Boolean = true
lateinit var callback: FolioToolbarCallback
constructor(context: Context) : this(context, null, 0)
@@ -65,9 +65,7 @@ class FolioToolbar : RelativeLayout {
}
fun setTitle(title: String?) {
- title?.let {
- label_center?.text = title
- }
+ label_center?.text = title
}
fun showOrHideIfVisible() {
@@ -79,7 +77,7 @@ class FolioToolbar : RelativeLayout {
visible = !visible
}
- private fun show() {
+ fun show() {
this.animate().translationY(0f)
.setInterpolator(DecelerateInterpolator(2f))
.start()
@@ -95,10 +93,10 @@ class FolioToolbar : RelativeLayout {
label_center.setTextColor(ContextCompat.getColor(context, R.color.black))
}
- private fun hide() {
- this.animate().translationY((-this.height)
+ fun hide() {
+ post({ this.animate().translationY((-this.height)
.toFloat())
.setInterpolator(AccelerateInterpolator(2f))
- .start()
+ .start() })
}
}
diff --git a/folioreader/src/main/java/com/folioreader/view/FolioWebView.java b/folioreader/src/main/java/com/folioreader/view/FolioWebView.java
new file mode 100644
index 000000000..08091ccef
--- /dev/null
+++ b/folioreader/src/main/java/com/folioreader/view/FolioWebView.java
@@ -0,0 +1,261 @@
+package com.folioreader.view;
+
+import android.content.Context;
+import android.os.Handler;
+import android.support.v4.view.GestureDetectorCompat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.webkit.JavascriptInterface;
+import android.webkit.WebView;
+
+import com.folioreader.Config;
+import com.folioreader.R;
+import com.folioreader.ui.folio.activity.FolioActivityCallback;
+
+/**
+ * @author by mahavir on 3/31/16.
+ */
+public class FolioWebView extends WebView
+ implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
+
+ private static final String LOG_TAG = FolioWebView.class.getSimpleName();
+ private float touchSlop;
+ private int horizontalPageCount = 0;
+ private float density;
+ private ScrollListener mScrollListener;
+ private SeekBarListener mSeekBarListener;
+ private ToolBarListener mToolBarListener;
+ private GestureDetectorCompat gestureDetector;
+ private MotionEvent eventActionDown;
+ private int pageWidthCssPixels;
+ private WebViewPager webViewPager;
+ private Handler handler;
+ private FolioActivityCallback folioActivityCallback;
+
+ public FolioWebView(Context context) {
+ super(context);
+ if (!isInEditMode())
+ init();
+ }
+
+ public FolioWebView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ if (!isInEditMode())
+ init();
+ }
+
+ public FolioWebView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ if (!isInEditMode())
+ init();
+ }
+
+ private void init() {
+
+ handler = new Handler();
+ gestureDetector = new GestureDetectorCompat(getContext(), this);
+ gestureDetector.setOnDoubleTapListener(this);
+ density = getResources().getDisplayMetrics().density;
+ touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+ }
+
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void setCompatMode(String compatMode) {
+ Log.v(LOG_TAG, "-> setCompatMode -> compatMode = " + compatMode);
+ if (compatMode.equals(getContext().getString(R.string.back_compat))) {
+ Log.e(LOG_TAG, "-> Web page loaded in Quirks mode. Please report to developer " +
+ "for debugging with current EPUB file as many features might stop working " +
+ "(ex. Horizontal scroll feature).");
+ }
+ }
+
+ public void setFolioActivityCallback(FolioActivityCallback folioActivityCallback) {
+ this.folioActivityCallback = folioActivityCallback;
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+
+ double widthDp = Math.ceil((getMeasuredWidth() / density));
+ pageWidthCssPixels = (int) (widthDp * density);
+ }
+
+ public void setScrollListener(ScrollListener listener) {
+ mScrollListener = listener;
+ }
+
+ public void setSeekBarListener(SeekBarListener listener) {
+ mSeekBarListener = listener;
+ }
+
+ public void setToolBarListener(ToolBarListener listener) {
+ mToolBarListener = listener;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> onTouchEvent -> " + AppUtil.actionToString(event.getAction()));
+
+ hideOrShowToolBar(event);
+
+ if (folioActivityCallback.getDirection() == Config.Direction.HORIZONTAL) {
+ return computeHorizontalScroll(event);
+ } else {
+ return computeVerticalScroll(event);
+ }
+ }
+
+ private boolean computeVerticalScroll(MotionEvent event) {
+ return super.onTouchEvent(event);
+ }
+
+ private boolean computeHorizontalScroll(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> computeHorizontalScroll");
+
+ webViewPager.dispatchTouchEvent(event);
+ boolean gestureReturn = gestureDetector.onTouchEvent(event);
+ if (gestureReturn)
+ return true;
+ return super.onTouchEvent(event);
+ }
+
+ public int getScrollXForPage(int page) {
+ //Log.v(LOG_TAG, "-> getScrollXForPage -> page = " + page);
+ return page * pageWidthCssPixels;
+ }
+
+ private void hideOrShowToolBar(MotionEvent event) {
+
+ switch (event.getAction()) {
+
+ case MotionEvent.ACTION_DOWN:
+ eventActionDown = MotionEvent.obtain(event);
+ if (mSeekBarListener != null)
+ mSeekBarListener.fadeInSeekBarIfInvisible();
+ break;
+
+ case MotionEvent.ACTION_UP:
+ if (mToolBarListener != null &&
+ ((Math.abs(event.getY() - eventActionDown.getY()) < touchSlop) &&
+ (Math.abs(event.getX() - eventActionDown.getX()) < touchSlop))) {
+ //SingleTap
+ mToolBarListener.hideOrShowToolBar();
+ }
+ break;
+ }
+ }
+
+ public void setHorizontalPageCount(int horizontalPageCount) {
+ this.horizontalPageCount = horizontalPageCount;
+
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (webViewPager == null)
+ webViewPager = ((View) getParent()).findViewById(R.id.webViewPager);
+
+ webViewPager.setHorizontalPageCount(FolioWebView.this.horizontalPageCount);
+ }
+ });
+ }
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ if (mToolBarListener != null) mToolBarListener.hideToolBarIfVisible();
+ if (mScrollListener != null) mScrollListener.onScrollChange(t);
+ super.onScrollChanged(l, t, oldl, oldt);
+ }
+
+ public int getContentHeightVal() {
+ return (int) Math.floor(this.getContentHeight() * this.getScale());
+ }
+
+ public int getWebViewHeight() {
+ return this.getMeasuredHeight();
+ }
+
+ @Override
+ public boolean onDown(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> onDown -> " + event.toString());
+
+ eventActionDown = MotionEvent.obtain(event);
+ super.onTouchEvent(event);
+ return true;
+ }
+
+ @Override
+ public boolean onFling(MotionEvent event1, MotionEvent event2,
+ float velocityX, float velocityY) {
+
+ if (!webViewPager.isScrolling()) {
+ //TODO: -> check for right edge to left flings from right edge
+ // Need to complete the scroll as ViewPager thinks these touch events should not
+ // scroll it's pages.
+ //Log.d(LOG_TAG, "-> onFling -> completing scroll");
+ invalidate();
+ scrollTo(getScrollXForPage(webViewPager.getCurrentItem()), 0);
+ }
+ return true;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> onLongPress -> " + event.toString());
+ }
+
+ @Override
+ public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
+ float distanceY) {
+ //Log.v(LOG_TAG, "-> onScroll -> " + event1.toString() + event2.toString() + ", distanceX = " + distanceX + ", distanceY = " + distanceY);
+ return false;
+ }
+
+ @Override
+ public void onShowPress(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> onShowPress -> " + event.toString());
+ }
+
+ @Override
+ public boolean onSingleTapUp(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> onSingleTapUp -> " + event.toString());
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> onDoubleTap -> " + event.toString());
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTapEvent(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> onDoubleTapEvent -> " + event.toString());
+ return false;
+ }
+
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent event) {
+ //Log.v(LOG_TAG, "-> onSingleTapConfirmed -> " + event.toString());
+ return false;
+ }
+
+ public interface ScrollListener {
+ void onScrollChange(int percent);
+ }
+
+ public interface SeekBarListener {
+ void fadeInSeekBarIfInvisible();
+ }
+
+ public interface ToolBarListener {
+ void hideOrShowToolBar();
+
+ void hideToolBarIfVisible();
+ }
+}
diff --git a/folioreader/src/main/java/com/folioreader/view/LoadingView.java b/folioreader/src/main/java/com/folioreader/view/LoadingView.java
new file mode 100644
index 000000000..8baa5701f
--- /dev/null
+++ b/folioreader/src/main/java/com/folioreader/view/LoadingView.java
@@ -0,0 +1,110 @@
+package com.folioreader.view;
+
+import android.content.Context;
+import android.os.Handler;
+import android.support.constraint.ConstraintLayout;
+import android.support.v4.content.ContextCompat;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.webkit.JavascriptInterface;
+import android.widget.FrameLayout;
+import android.widget.ProgressBar;
+
+import com.folioreader.Config;
+import com.folioreader.R;
+import com.folioreader.util.AppUtil;
+import com.folioreader.util.UiUtil;
+
+@SuppressWarnings("PMD.AvoidDuplicateLiterals")
+public class LoadingView extends FrameLayout {
+
+ private ConstraintLayout rootView;
+ private ProgressBar progressBar;
+ private static final int VISIBLE_DURATION = 6000;
+ private Handler handler;
+
+ private Runnable hideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ hide();
+ }
+ };
+
+ private static final String LOG_TAG = LoadingView.class.getSimpleName();
+
+ public LoadingView(Context context) {
+ super(context);
+ init(context, null, 0);
+ }
+
+ public LoadingView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs, 0);
+ }
+
+ public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context, attrs, defStyleAttr);
+ }
+
+ private void init(Context context, AttributeSet attrs, int defStyleAttr) {
+
+ LayoutInflater.from(context).inflate(R.layout.view_loading, this);
+
+ if (isInEditMode())
+ return;
+
+ handler = new Handler();
+ rootView = findViewById(R.id.rootView);
+ progressBar = findViewById(R.id.progressBar);
+
+ updateTheme();
+ show();
+ }
+
+ public void updateTheme() {
+
+ Config config = AppUtil.getSavedConfig(getContext());
+ if (config == null)
+ config = new Config();
+ UiUtil.setColorToImage(getContext(), config.getThemeColor(), progressBar.getIndeterminateDrawable());
+ if (config.isNightMode()) {
+ rootView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.webview_night));
+ } else {
+ rootView.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.white));
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void show() {
+ //Log.d(LOG_TAG, "-> show");
+
+ handler.removeCallbacks(hideRunnable);
+ setVisibility(VISIBLE);
+ handler.postDelayed(hideRunnable, VISIBLE_DURATION);
+ }
+
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void hide() {
+ //Log.d(LOG_TAG, "-> hide");
+
+ handler.removeCallbacks(hideRunnable);
+ setVisibility(INVISIBLE);
+ }
+
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void visible() {
+ //Log.d(LOG_TAG, "-> visible");
+ setVisibility(VISIBLE);
+ }
+
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void invisible() {
+ //Log.d(LOG_TAG, "-> invisible");
+ setVisibility(INVISIBLE);
+ }
+}
diff --git a/folioreader/src/main/java/com/folioreader/view/ObservableWebView.java b/folioreader/src/main/java/com/folioreader/view/ObservableWebView.java
deleted file mode 100644
index d472a31d3..000000000
--- a/folioreader/src/main/java/com/folioreader/view/ObservableWebView.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package com.folioreader.view;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.util.AttributeSet;
-import android.view.ActionMode;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.webkit.WebView;
-
-/**
- * Created by mahavir on 3/31/16.
- */
-public class ObservableWebView extends WebView {
-
- private float mDownPosX = 0;
- private float mDownPosY = 0;
-
- public interface ScrollListener {
- void onScrollChange(int percent);
- }
-
- public interface SeekBarListener {
- void fadeInSeekBarIfInvisible();
- }
-
- public interface ToolBarListener {
- void hideOrShowToolBar();
- }
-
- private ScrollListener mScrollListener;
- private SeekBarListener mSeekBarListener;
- private ToolBarListener mToolBarListener;
-
- public ObservableWebView(Context context) {
- super(context);
- }
-
- public ObservableWebView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public ObservableWebView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public ObservableWebView(Context context, AttributeSet attrs,
- int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- public void setScrollListener(ScrollListener listener) {
- mScrollListener = listener;
- }
-
- public void setSeekBarListener(SeekBarListener listener) {
- mSeekBarListener = listener;
- }
-
- public void setToolBarListener(ToolBarListener listener) {
- mToolBarListener = listener;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- final int action = event.getAction();
- float MOVE_THRESHOLD_DP = 20 * getResources().getDisplayMetrics().density;
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- mDownPosX = event.getX();
- mDownPosY = event.getY();
- if (mSeekBarListener != null) mSeekBarListener.fadeInSeekBarIfInvisible();
- break;
- case MotionEvent.ACTION_UP:
- if (mToolBarListener != null &&
- (Math.abs(event.getX() - mDownPosX) < MOVE_THRESHOLD_DP
- || Math.abs(event.getY() - mDownPosY) < MOVE_THRESHOLD_DP)) {
- mToolBarListener.hideOrShowToolBar();
- }
- break;
- }
- return super.onTouchEvent(event);
- }
-
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- if (mToolBarListener != null) mToolBarListener.hideOrShowToolBar();
- if (mScrollListener != null) mScrollListener.onScrollChange(t);
- super.onScrollChanged(l, t, oldl, oldt);
- }
-
- public int getContentHeightVal() {
- return (int) Math.floor(this.getContentHeight() * this.getScale());
- }
-
- public int getWebViewHeight() {
- return this.getMeasuredHeight();
- }
-
- @Override
- public ActionMode startActionMode(ActionMode.Callback callback, int type) {
- return this.dummyActionMode();
- }
-
- @Override
- public ActionMode startActionMode(ActionMode.Callback callback) {
- return this.dummyActionMode();
- }
-
- public ActionMode dummyActionMode() {
- return new ActionMode() {
- @Override
- public void setTitle(CharSequence title) {
- }
-
- @Override
- public void setTitle(int resId) {
- }
-
- @Override
- public void setSubtitle(CharSequence subtitle) {
- }
-
- @Override
- public void setSubtitle(int resId) {
- }
-
- @Override
- public void setCustomView(View view) {
- }
-
- @Override
- public void invalidate() {
- }
-
- @Override
- public void finish() {
- }
-
- @Override
- public Menu getMenu() {
- return null;
- }
-
- @Override
- public CharSequence getTitle() {
- return null;
- }
-
- @Override
- public CharSequence getSubtitle() {
- return null;
- }
-
- @Override
- public View getCustomView() {
- return null;
- }
-
- @Override
- public MenuInflater getMenuInflater() {
- return null;
- }
- };
- }
-}
diff --git a/folioreader/src/main/java/com/folioreader/view/WebViewPager.java b/folioreader/src/main/java/com/folioreader/view/WebViewPager.java
new file mode 100644
index 000000000..91678c9ca
--- /dev/null
+++ b/folioreader/src/main/java/com/folioreader/view/WebViewPager.java
@@ -0,0 +1,192 @@
+package com.folioreader.view;
+
+import android.content.Context;
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.JavascriptInterface;
+
+import com.folioreader.R;
+
+public class WebViewPager extends ViewPager {
+
+ private static final String LOG_TAG = WebViewPager.class.getSimpleName();
+ private int horizontalPageCount;
+ private FolioWebView folioWebView;
+ private boolean takeOverScrolling;
+ private boolean scrolling;
+ private Handler handler;
+
+ public WebViewPager(@NonNull Context context) {
+ super(context);
+ init();
+ }
+
+ public WebViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ private void init() {
+
+ handler = new Handler();
+
+ addOnPageChangeListener(new OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+// Log.d(LOG_TAG, "-> onPageScrolled -> position = " + position +
+// ", positionOffset = " + positionOffset + ", positionOffsetPixels = " + positionOffsetPixels);
+
+ scrolling = true;
+
+ if (takeOverScrolling && folioWebView != null) {
+ int scrollX = folioWebView.getScrollXForPage(position) + positionOffsetPixels;
+ //Log.d(LOG_TAG, "-> onPageScrolled -> scrollX = " + scrollX);
+ folioWebView.scrollTo(scrollX, 0);
+ }
+
+ if (positionOffsetPixels == 0) {
+ takeOverScrolling = false;
+ scrolling = false;
+ }
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ Log.v(LOG_TAG, "-> onPageSelected -> " + position);
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
+ });
+ }
+
+ public boolean isScrolling() {
+ return scrolling;
+ }
+
+ private String getScrollStateString(int state) {
+ switch (state) {
+ case SCROLL_STATE_IDLE:
+ return "SCROLL_STATE_IDLE";
+ case SCROLL_STATE_DRAGGING:
+ return "SCROLL_STATE_DRAGGING";
+ case SCROLL_STATE_SETTLING:
+ return "SCROLL_STATE_SETTLING";
+ default:
+ return "UNKNOWN_STATE";
+ }
+ }
+
+ public void setHorizontalPageCount(int horizontalPageCount) {
+ //Log.d(LOG_TAG, "-> horizontalPageCount = " + horizontalPageCount);
+
+ this.horizontalPageCount = horizontalPageCount;
+ setAdapter(new WebViewPagerAdapter());
+ setCurrentItem(0);
+
+ if (folioWebView == null)
+ folioWebView = ((View) getParent()).findViewById(R.id.folioWebView);
+ }
+
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void setCurrentPage(final int pageIndex) {
+ Log.v(LOG_TAG, "-> setCurrentItem -> pageIndex = " + pageIndex);
+
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ folioWebView.postInvalidate();
+ setCurrentItem(pageIndex, false);
+ }
+ });
+ }
+
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void setPageToLast() {
+
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ folioWebView.postInvalidate();
+ setCurrentItem(horizontalPageCount - 1);
+ }
+ });
+ }
+
+ @SuppressWarnings("unused")
+ @JavascriptInterface
+ public void setPageToFirst() {
+
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ folioWebView.postInvalidate();
+ setCurrentItem(0);
+ }
+ });
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ //Log.d(LOG_TAG, "-> onTouchEvent -> " + AppUtil.actionToString(event.getAction()));
+
+ boolean superReturn = super.onTouchEvent(event);
+
+ if (event.getAction() == MotionEvent.ACTION_UP)
+ takeOverScrolling = true;
+
+ return superReturn;
+ }
+
+ private class WebViewPagerAdapter extends PagerAdapter {
+
+ @Override
+ public int getCount() {
+ return horizontalPageCount;
+ }
+
+ @Override
+ public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
+ return view == object;
+ }
+
+ @NonNull
+ @Override
+ public Object instantiateItem(@NonNull ViewGroup container, int position) {
+
+ View view = LayoutInflater.from(container.getContext())
+ .inflate(R.layout.view_webview_pager, container, false);
+
+ // Debug code
+ // Set alpha for folioWebView in folio_page_fragment.xml to 0.5f also.
+ /*if (position % 2 == 0) {
+ view.setBackgroundResource(R.drawable.green_border_background);
+ } else {
+ view.setBackgroundResource(R.drawable.blue_border_background);
+ }
+
+ TextView textView = view.findViewById(R.id.textView);
+ textView.setText(Integer.toString(position));*/
+
+ container.addView(view);
+ return view;
+ }
+
+ @Override
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ container.removeView((View) object);
+ }
+ }
+}
diff --git a/gradle.properties b/gradle.properties
index 9f1fbf99c..5c64d0435 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,7 +1,20 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
VERSION_NAME=1.0
VERSION_CODE=1
-ANDROID_BUILD_TOOLS_VERSION=23.0.2
-ANDROID_COMPILE_SDK_VERSION=23
-ANDROID_TARGET_SDK_VERSION=23
+ANDROID_COMPILE_SDK_VERSION=28
+ANDROID_TARGET_SDK_VERSION=28
ANDROID_MIN_SDK=14
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 8c0fb64a8..7a3265ee9 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 868b7fb98..a0ac26c85 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Wed May 09 16:00:44 IST 2018
+#Tue Jun 05 17:41:05 IST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index 91a7e269e..cccdd3d51 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -6,20 +6,38 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -30,6 +48,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
+nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -40,31 +59,11 @@ case "`uname`" in
MINGW* )
msys=true
;;
+ NONSTOP* )
+ nonstop=true
+ ;;
esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -90,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -114,6 +113,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index aec99730b..e95643d6a 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail
:init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
diff --git a/sample/.gitignore b/sample/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/sample/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/sample/build.gradle b/sample/build.gradle
index 1e6d345a6..f1d4ccb3c 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -3,60 +3,60 @@ apply plugin: 'checkstyle'
android {
+ compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
+
+ defaultConfig {
+ applicationId "com.folioreader.android.sample"
+ minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK)
+ targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION)
+ versionCode Integer.parseInt(project.VERSION_CODE)
+ versionName project.VERSION_NAME
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ dexOptions {
+ javaMaxHeapSize "4G"
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
- dexOptions {
- javaMaxHeapSize "4G"
- }
-
- compileSdkVersion 27
- buildToolsVersion "27.0.3"
-
- defaultConfig {
- applicationId "com.folioreader.android.sample"
- versionCode Integer.parseInt(project.VERSION_CODE)
- versionName project.VERSION_NAME
- minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK)
- targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION)
- }
-
- sourceSets {
- main {
- manifest.srcFile 'AndroidManifest.xml'
- java.srcDirs = ['src/main/java']
- res.srcDirs = ['res']
+ packagingOptions {
+ exclude 'META-INF/ASL2.0'
+ exclude 'META-INF/DEPENDENCIES.txt'
+ exclude 'META-INF/LICENSE.txt'
+ exclude 'META-INF/NOTICE.txt'
+ exclude 'META-INF/NOTICE'
+ exclude 'META-INF/LICENSE'
+ exclude 'META-INF/DEPENDENCIES'
+ exclude 'META-INF/notice.txt'
+ exclude 'META-INF/license.txt'
+ exclude 'META-INF/dependencies.txt'
+ exclude 'META-INF/LGPL2.1'
+ exclude 'META-INF/services/javax.annotation.processing.Processor'
}
- test {
- java.srcDirs = ['src/test/java']
+
+ lintOptions {
+ abortOnError false
}
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
-
- packagingOptions {
- exclude 'META-INF/ASL2.0'
- exclude 'META-INF/DEPENDENCIES.txt'
- exclude 'META-INF/LICENSE.txt'
- exclude 'META-INF/NOTICE.txt'
- exclude 'META-INF/NOTICE'
- exclude 'META-INF/LICENSE'
- exclude 'META-INF/DEPENDENCIES'
- exclude 'META-INF/notice.txt'
- exclude 'META-INF/license.txt'
- exclude 'META-INF/dependencies.txt'
- exclude 'META-INF/LGPL2.1'
- exclude 'META-INF/services/javax.annotation.processing.Processor'
- }
-
- lintOptions {
- abortOnError false
- }
}
dependencies {
- implementation project(':folioreader')
- implementation 'com.android.support.constraint:constraint-layout:1.1.0'
- implementation 'com.android.support:appcompat-v7:27.1.1'
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation "com.android.support:appcompat-v7:$ANDROID_LIB_VERSION"
+ implementation 'com.android.support.constraint:constraint-layout:1.1.2'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+
+ implementation project(':folioreader')
}
diff --git a/sample/hs_err_pid10790.log b/sample/hs_err_pid10790.log
deleted file mode 100644
index 4ef854fb6..000000000
--- a/sample/hs_err_pid10790.log
+++ /dev/null
@@ -1,636 +0,0 @@
-#
-# There is insufficient memory for the Java Runtime Environment to continue.
-# Native memory allocation (mmap) failed to map 286261248 bytes for committing reserved memory.
-# Possible reasons:
-# The system is out of physical RAM or swap space
-# In 32 bit mode, the process size limit was hit
-# Possible solutions:
-# Reduce memory load on the system
-# Increase physical memory or swap space
-# Check if swap backing store is full
-# Use 64 bit Java on a 64 bit OS
-# Decrease Java heap size (-Xmx/-Xms)
-# Decrease number of Java threads
-# Decrease Java thread stack sizes (-Xss)
-# Set larger code cache with -XX:ReservedCodeCacheSize=
-# This output file may be truncated or incomplete.
-#
-# Out of Memory Error (os_linux.cpp:2627), pid=10790, tid=0x00007f832b0f0700
-#
-# JRE version: OpenJDK Runtime Environment (8.0_112-b224) (build 1.8.0_112-release-b736)
-# Java VM: OpenJDK 64-Bit Server VM (25.112-b736 mixed mode linux-amd64 compressed oops)
-# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
-#
-
---------------- T H R E A D ---------------
-
-Current thread (0x00007f8354077800): VMThread [stack: 0x00007f832aff0000,0x00007f832b0f1000] [id=10813]
-
-Stack: [0x00007f832aff0000,0x00007f832b0f1000], sp=0x00007f832b0ef4c0, free space=1021k
-Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
-V [libjvm.so+0x9e476d] VMError::report_and_die()+0x15d
-V [libjvm.so+0x4b6ada] report_vm_out_of_memory(char const*, int, unsigned long, VMErrorType, char const*)+0x8a
-V [libjvm.so+0x84c890] os::pd_commit_memory(char*, unsigned long, unsigned long, bool)+0xf0
-V [libjvm.so+0x8473af] os::commit_memory(char*, unsigned long, unsigned long, bool)+0x1f
-V [libjvm.so+0x8bd40b] PSVirtualSpace::expand_by(unsigned long)+0x5b
-V [libjvm.so+0x8be080] PSYoungGen::resize_generation(unsigned long, unsigned long)+0xb0
-V [libjvm.so+0x8be39b] PSYoungGen::resize(unsigned long, unsigned long)+0x1b
-V [libjvm.so+0x8baa8c] PSScavenge::invoke_no_policy()+0xdac
-V [libjvm.so+0x8bb268] PSScavenge::invoke()+0x38
-V [libjvm.so+0x86fd23] ParallelScavengeHeap::failed_mem_allocate(unsigned long)+0x63
-V [libjvm.so+0x9e6234] VM_ParallelGCFailedAllocation::doit()+0x84
-V [libjvm.so+0x9ea647] VM_Operation::evaluate()+0x47
-V [libjvm.so+0x9e9108] VMThread::evaluate_operation(VM_Operation*)+0x2c8
-V [libjvm.so+0x9e9589] VMThread::loop()+0x219
-V [libjvm.so+0x9e99d2] VMThread::run()+0x72
-V [libjvm.so+0x849cb2] java_start(Thread*)+0xf2
-
-VM_Operation (0x00007f835c73ae90): ParallelGCFailedAllocation, mode: safepoint, requested by thread 0x00007f835400a000
-
-
---------------- P R O C E S S ---------------
-
-Java Threads: ( => current thread )
- 0x00007f83540bf800 JavaThread "Service Thread" daemon [_thread_blocked, id=10840, stack(0x00007f832a611000,0x00007f832a712000)]
- 0x00007f83540bc800 JavaThread "C1 CompilerThread2" daemon [_thread_blocked, id=10836, stack(0x00007f832a712000,0x00007f832a813000)]
- 0x00007f83540ba800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=10834, stack(0x00007f832a813000,0x00007f832a914000)]
- 0x00007f83540b8000 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=10829, stack(0x00007f832a914000,0x00007f832aa15000)]
- 0x00007f83540b6800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=10826, stack(0x00007f832aa15000,0x00007f832ab16000)]
- 0x00007f8354084000 JavaThread "Finalizer" daemon [_thread_blocked, id=10817, stack(0x00007f832adee000,0x00007f832aeef000)]
- 0x00007f835407f000 JavaThread "Reference Handler" daemon [_thread_blocked, id=10816, stack(0x00007f832aeef000,0x00007f832aff0000)]
- 0x00007f835400a000 JavaThread "main" [_thread_blocked, id=10792, stack(0x00007f835c63c000,0x00007f835c73d000)]
-
-Other Threads:
-=>0x00007f8354077800 VMThread [stack: 0x00007f832aff0000,0x00007f832b0f1000] [id=10813]
- 0x00007f83540c2000 WatcherThread [stack: 0x00007f832a510000,0x00007f832a611000] [id=10841]
-
-VM state:at safepoint (normal execution)
-
-VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event])
-[0x00007f83540066c0] Threads_lock - owner thread: 0x00007f8354077800
-[0x00007f8354006bc0] Heap_lock - owner thread: 0x00007f835400a000
-
-Heap:
- PSYoungGen total 274944K, used 29165K [0x000000076ab00000, 0x000000077d800000, 0x00000007c0000000)
- eden space 245760K, 0% used [0x000000076ab00000,0x000000076ab00000,0x0000000779b00000)
- from space 29184K, 99% used [0x0000000779b00000,0x000000077b77b708,0x000000077b780000)
- to space 25088K, 0% used [0x000000077b780000,0x000000077b780000,0x000000077d000000)
- ParOldGen total 83456K, used 70447K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 84% used [0x00000006c0000000,0x00000006c44cbdd8,0x00000006c5180000)
- Metaspace used 6472K, capacity 7218K, committed 7296K, reserved 1056768K
- class space used 595K, capacity 618K, committed 640K, reserved 1048576K
-
-Card table byte_map: [0x00007f8358cca000,0x00007f83594cb000] byte_map_base: 0x00007f83556ca000
-
-Marking Bits: (ParMarkBitMap*) 0x00007f835bb06340
- Begin Bits: [0x00007f833d000000, 0x00007f8341000000)
- End Bits: [0x00007f8341000000, 0x00007f8345000000)
-
-Polling page: 0x00007f835c758000
-
-CodeCache: size=245760Kb used=8073Kb max_used=8073Kb free=237686Kb
- bounds [0x00007f8345000000, 0x00007f83457f0000, 0x00007f8354000000]
- total_blobs=2392 nmethods=2124 adapters=182
- compilation: enabled
-
-Compilation events (10 events):
-Event: 10.106 Thread 0x00007f83540bc800 2433 3 com.android.dx.dex.code.StdCatchBuilder::hasAnyCatches (57 bytes)
-Event: 10.107 Thread 0x00007f83540bc800 nmethod 2433 0x00007f83457e11d0 code [0x00007f83457e13e0, 0x00007f83457e20f8]
-Event: 10.183 Thread 0x00007f83540bc800 2434 % 3 com.android.dx.dex.file.CodeItem::addContents @ 142 (174 bytes)
-Event: 10.189 Thread 0x00007f83540bc800 nmethod 2434% 0x00007f83457e2650 code [0x00007f83457e2960, 0x00007f83457e43c8]
-Event: 10.189 Thread 0x00007f83540bc800 2435 3 com.android.dx.dex.file.CodeItem::addContents (174 bytes)
-Event: 10.190 Thread 0x00007f83540bc800 nmethod 2435 0x00007f83457e4ed0 code [0x00007f83457e51e0, 0x00007f83457e6be8]
-Event: 10.305 Thread 0x00007f83540bc800 2439 2 java.util.HashSet:: (17 bytes)
-Event: 10.305 Thread 0x00007f83540bc800 nmethod 2439 0x00007f83457e76d0 code [0x00007f83457e7860, 0x00007f83457e7a68]
-Event: 10.308 Thread 0x00007f83540bc800 2440 2 com.android.dx.dex.code.StdCatchBuilder::getCatchTypes (97 bytes)
-Event: 10.309 Thread 0x00007f83540bc800 nmethod 2440 0x00007f83457e7b50 code [0x00007f83457e7d60, 0x00007f83457e8318]
-
-GC Heap History (10 events):
-Event: 3.371 GC heap after
-Heap after GC invocations=2 (full 0):
- PSYoungGen total 67584K, used 5106K [0x000000076ab00000, 0x000000076f200000, 0x00000007c0000000)
- eden space 62464K, 0% used [0x000000076ab00000,0x000000076ab00000,0x000000076e800000)
- from space 5120K, 99% used [0x000000076ed00000,0x000000076f1fcb58,0x000000076f200000)
- to space 5120K, 0% used [0x000000076e800000,0x000000076e800000,0x000000076ed00000)
- ParOldGen total 83456K, used 5754K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 6% used [0x00000006c0000000,0x00000006c059eaa8,0x00000006c5180000)
- Metaspace used 5812K, capacity 6832K, committed 7040K, reserved 1056768K
- class space used 570K, capacity 616K, committed 640K, reserved 1048576K
-}
-Event: 4.660 GC heap before
-{Heap before GC invocations=3 (full 0):
- PSYoungGen total 67584K, used 67570K [0x000000076ab00000, 0x000000076f200000, 0x00000007c0000000)
- eden space 62464K, 100% used [0x000000076ab00000,0x000000076e800000,0x000000076e800000)
- from space 5120K, 99% used [0x000000076ed00000,0x000000076f1fcb58,0x000000076f200000)
- to space 5120K, 0% used [0x000000076e800000,0x000000076e800000,0x000000076ed00000)
- ParOldGen total 83456K, used 5754K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 6% used [0x00000006c0000000,0x00000006c059eaa8,0x00000006c5180000)
- Metaspace used 5897K, capacity 6896K, committed 7040K, reserved 1056768K
- class space used 571K, capacity 616K, committed 640K, reserved 1048576K
-Event: 4.811 GC heap after
-Heap after GC invocations=3 (full 0):
- PSYoungGen total 67584K, used 5106K [0x000000076ab00000, 0x0000000772f00000, 0x00000007c0000000)
- eden space 62464K, 0% used [0x000000076ab00000,0x000000076ab00000,0x000000076e800000)
- from space 5120K, 99% used [0x000000076e800000,0x000000076ecfc810,0x000000076ed00000)
- to space 5120K, 0% used [0x0000000772a00000,0x0000000772a00000,0x0000000772f00000)
- ParOldGen total 83456K, used 15268K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 18% used [0x00000006c0000000,0x00000006c0ee9128,0x00000006c5180000)
- Metaspace used 5897K, capacity 6896K, committed 7040K, reserved 1056768K
- class space used 571K, capacity 616K, committed 640K, reserved 1048576K
-}
-Event: 5.410 GC heap before
-{Heap before GC invocations=4 (full 0):
- PSYoungGen total 67584K, used 67570K [0x000000076ab00000, 0x0000000772f00000, 0x00000007c0000000)
- eden space 62464K, 100% used [0x000000076ab00000,0x000000076e800000,0x000000076e800000)
- from space 5120K, 99% used [0x000000076e800000,0x000000076ecfc810,0x000000076ed00000)
- to space 5120K, 0% used [0x0000000772a00000,0x0000000772a00000,0x0000000772f00000)
- ParOldGen total 83456K, used 15268K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 18% used [0x00000006c0000000,0x00000006c0ee9128,0x00000006c5180000)
- Metaspace used 5969K, capacity 6960K, committed 7040K, reserved 1056768K
- class space used 571K, capacity 616K, committed 640K, reserved 1048576K
-Event: 5.496 GC heap after
-Heap after GC invocations=4 (full 0):
- PSYoungGen total 130048K, used 5094K [0x000000076ab00000, 0x0000000772f00000, 0x00000007c0000000)
- eden space 124928K, 0% used [0x000000076ab00000,0x000000076ab00000,0x0000000772500000)
- from space 5120K, 99% used [0x0000000772a00000,0x0000000772ef9850,0x0000000772f00000)
- to space 5120K, 0% used [0x0000000772500000,0x0000000772500000,0x0000000772a00000)
- ParOldGen total 83456K, used 23906K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 28% used [0x00000006c0000000,0x00000006c1758878,0x00000006c5180000)
- Metaspace used 5969K, capacity 6960K, committed 7040K, reserved 1056768K
- class space used 571K, capacity 616K, committed 640K, reserved 1048576K
-}
-Event: 6.593 GC heap before
-{Heap before GC invocations=5 (full 0):
- PSYoungGen total 130048K, used 130022K [0x000000076ab00000, 0x0000000772f00000, 0x00000007c0000000)
- eden space 124928K, 100% used [0x000000076ab00000,0x0000000772500000,0x0000000772500000)
- from space 5120K, 99% used [0x0000000772a00000,0x0000000772ef9850,0x0000000772f00000)
- to space 5120K, 0% used [0x0000000772500000,0x0000000772500000,0x0000000772a00000)
- ParOldGen total 83456K, used 23906K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 28% used [0x00000006c0000000,0x00000006c1758878,0x00000006c5180000)
- Metaspace used 6101K, capacity 7088K, committed 7296K, reserved 1056768K
- class space used 571K, capacity 616K, committed 640K, reserved 1048576K
-Event: 6.745 GC heap after
-Heap after GC invocations=5 (full 0):
- PSYoungGen total 130048K, used 5099K [0x000000076ab00000, 0x000000077d000000, 0x00000007c0000000)
- eden space 124928K, 0% used [0x000000076ab00000,0x000000076ab00000,0x0000000772500000)
- from space 5120K, 99% used [0x0000000772500000,0x00000007729fae18,0x0000000772a00000)
- to space 25088K, 0% used [0x000000077b780000,0x000000077b780000,0x000000077d000000)
- ParOldGen total 83456K, used 42782K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 51% used [0x00000006c0000000,0x00000006c29c7af0,0x00000006c5180000)
- Metaspace used 6101K, capacity 7088K, committed 7296K, reserved 1056768K
- class space used 571K, capacity 616K, committed 640K, reserved 1048576K
-}
-Event: 7.800 GC heap before
-{Heap before GC invocations=6 (full 0):
- PSYoungGen total 130048K, used 130027K [0x000000076ab00000, 0x000000077d000000, 0x00000007c0000000)
- eden space 124928K, 100% used [0x000000076ab00000,0x0000000772500000,0x0000000772500000)
- from space 5120K, 99% used [0x0000000772500000,0x00000007729fae18,0x0000000772a00000)
- to space 25088K, 0% used [0x000000077b780000,0x000000077b780000,0x000000077d000000)
- ParOldGen total 83456K, used 42782K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 51% used [0x00000006c0000000,0x00000006c29c7af0,0x00000006c5180000)
- Metaspace used 6202K, capacity 7152K, committed 7296K, reserved 1056768K
- class space used 571K, capacity 616K, committed 640K, reserved 1048576K
-Event: 7.944 GC heap after
-Heap after GC invocations=6 (full 0):
- PSYoungGen total 270848K, used 24117K [0x000000076ab00000, 0x000000077d800000, 0x00000007c0000000)
- eden space 245760K, 0% used [0x000000076ab00000,0x000000076ab00000,0x0000000779b00000)
- from space 25088K, 96% used [0x000000077b780000,0x000000077cf0d438,0x000000077d000000)
- to space 29184K, 0% used [0x0000000779b00000,0x0000000779b00000,0x000000077b780000)
- ParOldGen total 83456K, used 42782K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 51% used [0x00000006c0000000,0x00000006c29c7af0,0x00000006c5180000)
- Metaspace used 6202K, capacity 7152K, committed 7296K, reserved 1056768K
- class space used 571K, capacity 616K, committed 640K, reserved 1048576K
-}
-Event: 10.575 GC heap before
-{Heap before GC invocations=7 (full 0):
- PSYoungGen total 270848K, used 269877K [0x000000076ab00000, 0x000000077d800000, 0x00000007c0000000)
- eden space 245760K, 100% used [0x000000076ab00000,0x0000000779b00000,0x0000000779b00000)
- from space 25088K, 96% used [0x000000077b780000,0x000000077cf0d438,0x000000077d000000)
- to space 29184K, 0% used [0x0000000779b00000,0x0000000779b00000,0x000000077b780000)
- ParOldGen total 83456K, used 42782K [0x00000006c0000000, 0x00000006c5180000, 0x000000076ab00000)
- object space 83456K, 51% used [0x00000006c0000000,0x00000006c29c7af0,0x00000006c5180000)
- Metaspace used 6472K, capacity 7218K, committed 7296K, reserved 1056768K
- class space used 595K, capacity 618K, committed 640K, reserved 1048576K
-
-Deoptimization events (10 events):
-Event: 8.554 Thread 0x00007f8354132000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f83452f7074 method=java.util.HashMap.putVal(ILjava/lang/Object;Ljava/lang/Object;ZZ)Ljava/lang/Object; @ 162
-Event: 8.566 Thread 0x00007f8354132000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f834520c658 method=java.util.HashMap.getNode(ILjava/lang/Object;)Ljava/util/HashMap$Node; @ 84
-Event: 8.566 Thread 0x00007f8354132000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f83456800bc method=java.util.HashMap.getNode(ILjava/lang/Object;)Ljava/util/HashMap$Node; @ 84
-Event: 9.263 Thread 0x00007f8354132000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f83454ee508 method=com.android.dx.ssa.SCCP.simulateStmt(Lcom/android/dx/ssa/SsaInsn;)V @ 53
-Event: 9.523 Thread 0x00007f835413b000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007f83456b7cc8 method=java.util.HashMap.putVal(ILjava/lang/Object;Ljava/lang/Object;ZZ)Ljava/lang/Object; @ 162
-Event: 9.728 Thread 0x00007f835400a000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00007f834540409c method=java.util.Arrays.hashCode([Ljava/lang/Object;)I @ 43
-Event: 9.728 Thread 0x00007f835400a000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00007f834540409c method=java.util.Arrays.hashCode([Ljava/lang/Object;)I @ 43
-Event: 9.729 Thread 0x00007f835400a000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00007f834540409c method=java.util.Arrays.hashCode([Ljava/lang/Object;)I @ 43
-Event: 9.729 Thread 0x00007f835400a000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00007f834540409c method=java.util.Arrays.hashCode([Ljava/lang/Object;)I @ 43
-Event: 9.729 Thread 0x00007f835400a000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00007f83453f94bc method=java.util.Arrays.hashCode([Ljava/lang/Object;)I @ 43
-
-Internal exceptions (7 events):
-Event: 0.055 Thread 0x00007f835400a000 Exception (0x000000076ab07c78) thrown at [/ssd/Android/AOSP-openjdk-git/jdk8u/hotspot/src/share/vm/prims/jni.cp
-Event: 0.056 Thread 0x00007f835400a000 Exception (0x000000076ab07f60) thrown at [/ssd/Android/AOSP-openjdk-git/jdk8u/hotspot/src/share/vm/prims/jni.cpp, line 4011]
-Event: 2.560 Thread 0x00007f835413b000 Implicit null exception at 0x00007f83452d990a to 0x00007f83452dc01d
-Event: 3.904 Thread 0x00007f835413e800 Implicit null exception at 0x00007f8345273162 to 0x00007f834527325b
-Event: 8.561 Thread 0x00007f8354132000 Exception (0x000000077092b7a0) thrown at [/ssd/Android/AOSP-openjdk-git/jdk8u/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp, line 366]
-Event: 8.562 Thread 0x00007f8354132000 Exception (0x000000077092d320) thrown at [/ssd/Android/AOSP-openjdk-git/jdk8u/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp, line 366]
-Event: 8.564 Thread 0x00007f8354132000 Exception (0x000000077092e608) thrown at [/ssd/Android/AOSP-openjdk-git/jdk8u/hotspot/src/share/vm/runtime/sharedRuntime.cpp, line 605]
-
-Events (10 events):
-Event: 9.970 Thread 0x00007f835400a000 DEOPT UNPACKING pc=0x00007f8345047373 sp=0x00007f835c73b198 mode 0
-Event: 9.972 Thread 0x00007f835400a000 DEOPT PACKING pc=0x00007f8345530819 sp=0x00007f835c73b4b0
-Event: 9.972 Thread 0x00007f835400a000 DEOPT UNPACKING pc=0x00007f8345047373 sp=0x00007f835c73b200 mode 0
-Event: 9.989 Thread 0x00007f835400a000 DEOPT PACKING pc=0x00007f83457d68d6 sp=0x00007f835c73b4b0
-Event: 9.989 Thread 0x00007f835400a000 DEOPT UNPACKING pc=0x00007f8345047373 sp=0x00007f835c73b260 mode 0
-Event: 10.107 Thread 0x00007f835400a000 DEOPT PACKING pc=0x00007f83457d7314 sp=0x00007f835c73b4e0
-Event: 10.107 Thread 0x00007f835400a000 DEOPT UNPACKING pc=0x00007f8345047373 sp=0x00007f835c73b250 mode 0
-Event: 10.190 Thread 0x00007f835400a000 DEOPT PACKING pc=0x00007f83457d7fe8 sp=0x00007f835c73b570
-Event: 10.190 Thread 0x00007f835400a000 DEOPT UNPACKING pc=0x00007f8345047373 sp=0x00007f835c73b310 mode 0
-Event: 10.575 Executing VM operation: ParallelGCFailedAllocation
-
-
-Dynamic libraries:
-00400000-00401000 r-xp 00000000 08:05 1336328 /home/gautam/android-studio-3/jre/bin/java
-00600000-00601000 r--p 00000000 08:05 1336328 /home/gautam/android-studio-3/jre/bin/java
-00601000-00602000 rw-p 00001000 08:05 1336328 /home/gautam/android-studio-3/jre/bin/java
-00d5e000-00d7f000 rw-p 00000000 00:00 0 [heap]
-6c0000000-6c5180000 rw-p 00000000 00:00 0
-6c5180000-76ab00000 ---p 00000000 00:00 0
-76ab00000-77d800000 rw-p 00000000 00:00 0
-78e900000-7c0000000 ---p 00000000 00:00 0
-7c0000000-7c00a0000 rw-p 00000000 00:00 0
-7c00a0000-800000000 ---p 00000000 00:00 0
-7f82ec000000-7f82ec021000 rw-p 00000000 00:00 0
-7f82ec021000-7f82f0000000 ---p 00000000 00:00 0
-7f82f4000000-7f82f4028000 rw-p 00000000 00:00 0
-7f82f4028000-7f82f8000000 ---p 00000000 00:00 0
-7f82f8000000-7f82f8021000 rw-p 00000000 00:00 0
-7f82f8021000-7f82fc000000 ---p 00000000 00:00 0
-7f82fc000000-7f82fc033000 rw-p 00000000 00:00 0
-7f82fc033000-7f8300000000 ---p 00000000 00:00 0
-7f8300000000-7f8300021000 rw-p 00000000 00:00 0
-7f8300021000-7f8304000000 ---p 00000000 00:00 0
-7f8304000000-7f8304021000 rw-p 00000000 00:00 0
-7f8304021000-7f8308000000 ---p 00000000 00:00 0
-7f8308000000-7f8308021000 rw-p 00000000 00:00 0
-7f8308021000-7f830c000000 ---p 00000000 00:00 0
-7f830c000000-7f830ca26000 rw-p 00000000 00:00 0
-7f830ca26000-7f8310000000 ---p 00000000 00:00 0
-7f8310000000-7f8310a2d000 rw-p 00000000 00:00 0
-7f8310a2d000-7f8314000000 ---p 00000000 00:00 0
-7f8314000000-7f8314cb4000 rw-p 00000000 00:00 0
-7f8314cb4000-7f8318000000 ---p 00000000 00:00 0
-7f8318000000-7f8318021000 rw-p 00000000 00:00 0
-7f8318021000-7f831c000000 ---p 00000000 00:00 0
-7f831c000000-7f831c021000 rw-p 00000000 00:00 0
-7f831c021000-7f8320000000 ---p 00000000 00:00 0
-7f8320000000-7f8320021000 rw-p 00000000 00:00 0
-7f8320021000-7f8324000000 ---p 00000000 00:00 0
-7f8324000000-7f832427e000 rw-p 00000000 00:00 0
-7f832427e000-7f8328000000 ---p 00000000 00:00 0
-7f832a00b000-7f832a00e000 ---p 00000000 00:00 0
-7f832a00e000-7f832a10c000 rw-p 00000000 00:00 0
-7f832a10c000-7f832a10f000 ---p 00000000 00:00 0
-7f832a10f000-7f832a20d000 rw-p 00000000 00:00 0
-7f832a20d000-7f832a210000 ---p 00000000 00:00 0
-7f832a210000-7f832a30e000 rw-p 00000000 00:00 0
-7f832a30e000-7f832a311000 ---p 00000000 00:00 0
-7f832a311000-7f832a40f000 rw-p 00000000 00:00 0
-7f832a40f000-7f832a412000 ---p 00000000 00:00 0
-7f832a412000-7f832a510000 rw-p 00000000 00:00 0
-7f832a510000-7f832a511000 ---p 00000000 00:00 0
-7f832a511000-7f832a611000 rw-p 00000000 00:00 0
-7f832a611000-7f832a614000 ---p 00000000 00:00 0
-7f832a614000-7f832a712000 rw-p 00000000 00:00 0
-7f832a712000-7f832a715000 ---p 00000000 00:00 0
-7f832a715000-7f832a813000 rw-p 00000000 00:00 0
-7f832a813000-7f832a816000 ---p 00000000 00:00 0
-7f832a816000-7f832a914000 rw-p 00000000 00:00 0
-7f832a914000-7f832a917000 ---p 00000000 00:00 0
-7f832a917000-7f832aa15000 rw-p 00000000 00:00 0
-7f832aa15000-7f832aa18000 ---p 00000000 00:00 0
-7f832aa18000-7f832ab16000 rw-p 00000000 00:00 0
-7f832ab16000-7f832adee000 r--p 00000000 08:05 1703 /usr/lib/locale/locale-archive
-7f832adee000-7f832adf1000 ---p 00000000 00:00 0
-7f832adf1000-7f832aeef000 rw-p 00000000 00:00 0
-7f832aeef000-7f832aef2000 ---p 00000000 00:00 0
-7f832aef2000-7f832aff0000 rw-p 00000000 00:00 0
-7f832aff0000-7f832aff1000 ---p 00000000 00:00 0
-7f832aff1000-7f832c000000 rw-p 00000000 00:00 0
-7f832c000000-7f832c021000 rw-p 00000000 00:00 0
-7f832c021000-7f8330000000 ---p 00000000 00:00 0
-7f8330000000-7f8330021000 rw-p 00000000 00:00 0
-7f8330021000-7f8334000000 ---p 00000000 00:00 0
-7f8334000000-7f8334021000 rw-p 00000000 00:00 0
-7f8334021000-7f8338000000 ---p 00000000 00:00 0
-7f8338000000-7f8338021000 rw-p 00000000 00:00 0
-7f8338021000-7f833c000000 ---p 00000000 00:00 0
-7f833c000000-7f833c680000 rw-p 00000000 00:00 0
-7f833c680000-7f833c800000 ---p 00000000 00:00 0
-7f833c800000-7f8345000000 rw-p 00000000 00:00 0
-7f8345000000-7f83457f0000 rwxp 00000000 00:00 0
-7f83457f0000-7f8354000000 ---p 00000000 00:00 0
-7f8354000000-7f835437a000 rw-p 00000000 00:00 0
-7f835437a000-7f8358000000 ---p 00000000 00:00 0
-7f8358038000-7f835812b000 rw-p 00000000 00:00 0
-7f835812b000-7f83582fa000 r--s 03c21000 08:05 1336386 /home/gautam/android-studio-3/jre/jre/lib/rt.jar
-7f83582fa000-7f8358370000 rw-p 00000000 00:00 0
-7f8358370000-7f8358371000 ---p 00000000 00:00 0
-7f8358371000-7f8358471000 rw-p 00000000 00:00 0
-7f8358471000-7f8358472000 ---p 00000000 00:00 0
-7f8358472000-7f8358572000 rw-p 00000000 00:00 0
-7f8358572000-7f8358573000 ---p 00000000 00:00 0
-7f8358573000-7f8358673000 rw-p 00000000 00:00 0
-7f8358673000-7f8358674000 ---p 00000000 00:00 0
-7f8358674000-7f835879d000 rw-p 00000000 00:00 0
-7f835879d000-7f8358cca000 ---p 00000000 00:00 0
-7f8358cca000-7f8358cf3000 rw-p 00000000 00:00 0
-7f8358cf3000-7f835921f000 ---p 00000000 00:00 0
-7f835921f000-7f83592b6000 rw-p 00000000 00:00 0
-7f83592b6000-7f83594ca000 ---p 00000000 00:00 0
-7f83594ca000-7f83594eb000 rw-p 00000000 00:00 0
-7f83594eb000-7f835988b000 ---p 00000000 00:00 0
-7f835988b000-7f83598a5000 r-xp 00000000 08:05 1336414 /home/gautam/android-studio-3/jre/jre/lib/amd64/libzip.so
-7f83598a5000-7f8359aa5000 ---p 0001a000 08:05 1336414 /home/gautam/android-studio-3/jre/jre/lib/amd64/libzip.so
-7f8359aa5000-7f8359aa6000 r--p 0001a000 08:05 1336414 /home/gautam/android-studio-3/jre/jre/lib/amd64/libzip.so
-7f8359aa6000-7f8359aa7000 rw-p 0001b000 08:05 1336414 /home/gautam/android-studio-3/jre/jre/lib/amd64/libzip.so
-7f8359aa7000-7f8359ab2000 r-xp 00000000 08:05 1836131 /lib/x86_64-linux-gnu/libnss_files-2.23.so
-7f8359ab2000-7f8359cb1000 ---p 0000b000 08:05 1836131 /lib/x86_64-linux-gnu/libnss_files-2.23.so
-7f8359cb1000-7f8359cb2000 r--p 0000a000 08:05 1836131 /lib/x86_64-linux-gnu/libnss_files-2.23.so
-7f8359cb2000-7f8359cb3000 rw-p 0000b000 08:05 1836131 /lib/x86_64-linux-gnu/libnss_files-2.23.so
-7f8359cb3000-7f8359cb9000 rw-p 00000000 00:00 0
-7f8359cb9000-7f8359cc4000 r-xp 00000000 08:05 1836123 /lib/x86_64-linux-gnu/libnss_nis-2.23.so
-7f8359cc4000-7f8359ec3000 ---p 0000b000 08:05 1836123 /lib/x86_64-linux-gnu/libnss_nis-2.23.so
-7f8359ec3000-7f8359ec4000 r--p 0000a000 08:05 1836123 /lib/x86_64-linux-gnu/libnss_nis-2.23.so
-7f8359ec4000-7f8359ec5000 rw-p 0000b000 08:05 1836123 /lib/x86_64-linux-gnu/libnss_nis-2.23.so
-7f8359ec5000-7f8359edb000 r-xp 00000000 08:05 1836125 /lib/x86_64-linux-gnu/libnsl-2.23.so
-7f8359edb000-7f835a0da000 ---p 00016000 08:05 1836125 /lib/x86_64-linux-gnu/libnsl-2.23.so
-7f835a0da000-7f835a0db000 r--p 00015000 08:05 1836125 /lib/x86_64-linux-gnu/libnsl-2.23.so
-7f835a0db000-7f835a0dc000 rw-p 00016000 08:05 1836125 /lib/x86_64-linux-gnu/libnsl-2.23.so
-7f835a0dc000-7f835a0de000 rw-p 00000000 00:00 0
-7f835a0de000-7f835a0e6000 r-xp 00000000 08:05 1836135 /lib/x86_64-linux-gnu/libnss_compat-2.23.so
-7f835a0e6000-7f835a2e5000 ---p 00008000 08:05 1836135 /lib/x86_64-linux-gnu/libnss_compat-2.23.so
-7f835a2e5000-7f835a2e6000 r--p 00007000 08:05 1836135 /lib/x86_64-linux-gnu/libnss_compat-2.23.so
-7f835a2e6000-7f835a2e7000 rw-p 00008000 08:05 1836135 /lib/x86_64-linux-gnu/libnss_compat-2.23.so
-7f835a2e7000-7f835a314000 r-xp 00000000 08:05 1336424 /home/gautam/android-studio-3/jre/jre/lib/amd64/libjava.so
-7f835a314000-7f835a513000 ---p 0002d000 08:05 1336424 /home/gautam/android-studio-3/jre/jre/lib/amd64/libjava.so
-7f835a513000-7f835a514000 r--p 0002c000 08:05 1336424 /home/gautam/android-studio-3/jre/jre/lib/amd64/libjava.so
-7f835a514000-7f835a516000 rw-p 0002d000 08:05 1336424 /home/gautam/android-studio-3/jre/jre/lib/amd64/libjava.so
-7f835a516000-7f835a526000 r-xp 00000000 08:05 1336440 /home/gautam/android-studio-3/jre/jre/lib/amd64/libverify.so
-7f835a526000-7f835a725000 ---p 00010000 08:05 1336440 /home/gautam/android-studio-3/jre/jre/lib/amd64/libverify.so
-7f835a725000-7f835a727000 r--p 0000f000 08:05 1336440 /home/gautam/android-studio-3/jre/jre/lib/amd64/libverify.so
-7f835a727000-7f835a728000 rw-p 00011000 08:05 1336440 /home/gautam/android-studio-3/jre/jre/lib/amd64/libverify.so
-7f835a728000-7f835a72f000 r-xp 00000000 08:05 1836153 /lib/x86_64-linux-gnu/librt-2.23.so
-7f835a72f000-7f835a92e000 ---p 00007000 08:05 1836153 /lib/x86_64-linux-gnu/librt-2.23.so
-7f835a92e000-7f835a92f000 r--p 00006000 08:05 1836153 /lib/x86_64-linux-gnu/librt-2.23.so
-7f835a92f000-7f835a930000 rw-p 00007000 08:05 1836153 /lib/x86_64-linux-gnu/librt-2.23.so
-7f835a930000-7f835aa38000 r-xp 00000000 08:05 1836124 /lib/x86_64-linux-gnu/libm-2.23.so
-7f835aa38000-7f835ac37000 ---p 00108000 08:05 1836124 /lib/x86_64-linux-gnu/libm-2.23.so
-7f835ac37000-7f835ac38000 r--p 00107000 08:05 1836124 /lib/x86_64-linux-gnu/libm-2.23.so
-7f835ac38000-7f835ac39000 rw-p 00108000 08:05 1836124 /lib/x86_64-linux-gnu/libm-2.23.so
-7f835ac39000-7f835b829000 r-xp 00000000 08:05 1336444 /home/gautam/android-studio-3/jre/jre/lib/amd64/server/libjvm.so
-7f835b829000-7f835ba29000 ---p 00bf0000 08:05 1336444 /home/gautam/android-studio-3/jre/jre/lib/amd64/server/libjvm.so
-7f835ba29000-7f835bac8000 r--p 00bf0000 08:05 1336444 /home/gautam/android-studio-3/jre/jre/lib/amd64/server/libjvm.so
-7f835bac8000-7f835baf1000 rw-p 00c8f000 08:05 1336444 /home/gautam/android-studio-3/jre/jre/lib/amd64/server/libjvm.so
-7f835baf1000-7f835bb35000 rw-p 00000000 00:00 0
-7f835bb35000-7f835bb4d000 r-xp 00000000 08:05 1836160 /lib/x86_64-linux-gnu/libpthread-2.23.so
-7f835bb4d000-7f835bd4c000 ---p 00018000 08:05 1836160 /lib/x86_64-linux-gnu/libpthread-2.23.so
-7f835bd4c000-7f835bd4d000 r--p 00017000 08:05 1836160 /lib/x86_64-linux-gnu/libpthread-2.23.so
-7f835bd4d000-7f835bd4e000 rw-p 00018000 08:05 1836160 /lib/x86_64-linux-gnu/libpthread-2.23.so
-7f835bd4e000-7f835bd52000 rw-p 00000000 00:00 0
-7f835bd52000-7f835bd55000 r-xp 00000000 08:05 1836122 /lib/x86_64-linux-gnu/libdl-2.23.so
-7f835bd55000-7f835bf54000 ---p 00003000 08:05 1836122 /lib/x86_64-linux-gnu/libdl-2.23.so
-7f835bf54000-7f835bf55000 r--p 00002000 08:05 1836122 /lib/x86_64-linux-gnu/libdl-2.23.so
-7f835bf55000-7f835bf56000 rw-p 00003000 08:05 1836122 /lib/x86_64-linux-gnu/libdl-2.23.so
-7f835bf56000-7f835c115000 r-xp 00000000 08:05 1836126 /lib/x86_64-linux-gnu/libc-2.23.so
-7f835c115000-7f835c315000 ---p 001bf000 08:05 1836126 /lib/x86_64-linux-gnu/libc-2.23.so
-7f835c315000-7f835c319000 r--p 001bf000 08:05 1836126 /lib/x86_64-linux-gnu/libc-2.23.so
-7f835c319000-7f835c31b000 rw-p 001c3000 08:05 1836126 /lib/x86_64-linux-gnu/libc-2.23.so
-7f835c31b000-7f835c31f000 rw-p 00000000 00:00 0
-7f835c31f000-7f835c335000 r-xp 00000000 08:05 1336302 /home/gautam/android-studio-3/jre/lib/amd64/jli/libjli.so
-7f835c335000-7f835c534000 ---p 00016000 08:05 1336302 /home/gautam/android-studio-3/jre/lib/amd64/jli/libjli.so
-7f835c534000-7f835c535000 r--p 00015000 08:05 1336302 /home/gautam/android-studio-3/jre/lib/amd64/jli/libjli.so
-7f835c535000-7f835c536000 rw-p 00016000 08:05 1336302 /home/gautam/android-studio-3/jre/lib/amd64/jli/libjli.so
-7f835c536000-7f835c55c000 r-xp 00000000 08:05 1836127 /lib/x86_64-linux-gnu/ld-2.23.so
-7f835c569000-7f835c63c000 rw-p 00000000 00:00 0
-7f835c63c000-7f835c63f000 ---p 00000000 00:00 0
-7f835c63f000-7f835c741000 rw-p 00000000 00:00 0
-7f835c741000-7f835c74f000 r--s 000e0000 08:05 932687 /home/gautam/Android/Sdk/build-tools/25.0.0/lib/dx.jar
-7f835c74f000-7f835c757000 rw-s 00000000 08:05 1194232 /tmp/hsperfdata_gautam/10790
-7f835c757000-7f835c758000 rw-p 00000000 00:00 0
-7f835c758000-7f835c759000 ---p 00000000 00:00 0
-7f835c759000-7f835c75b000 rw-p 00000000 00:00 0
-7f835c75b000-7f835c75c000 r--p 00025000 08:05 1836127 /lib/x86_64-linux-gnu/ld-2.23.so
-7f835c75c000-7f835c75d000 rw-p 00026000 08:05 1836127 /lib/x86_64-linux-gnu/ld-2.23.so
-7f835c75d000-7f835c75e000 rw-p 00000000 00:00 0
-7fff3b477000-7fff3b498000 rw-p 00000000 00:00 0 [stack]
-7fff3b4f0000-7fff3b4f2000 r--p 00000000 00:00 0 [vvar]
-7fff3b4f2000-7fff3b4f4000 r-xp 00000000 00:00 0 [vdso]
-ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
-
-VM Arguments:
-jvm_args: -Djava.awt.headless=true -Xmx4G -Dfile.encoding=UTF-8 -Duser.country=IN -Duser.language=en -Duser.variant
-java_command: com.android.dx.command.Main --dex --num-threads=4 --output /home/gautam/workspace/work/FolioReader-Android/sample/build/intermediates/pre-dexed/debug/jackson-databind-2.8.6_f01c2a29d5fb6662f6d226bb5ea7931a9ac47a70.jar /home/gautam/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-databind/2.8.6/c43de61f74ecc61322ef8f402837ba65b0aa2bf4/jackson-databind-2.8.6.jar
-java_class_path (initial): /home/gautam/Android/Sdk/build-tools/25.0.0/lib/dx.jar
-Launcher Type: SUN_STANDARD
-
-Environment Variables:
-JAVA_HOME=/usr/local/java/jdk1.8.0_65
-JRE_HOME=/usr/local/java/jre
-PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/bin:/bin
-LD_LIBRARY_PATH=/home/gautam/android-studio-3/bin:
-SHELL=/bin/bash
-DISPLAY=:0
-
-Signal Handlers:
-SIGSEGV: [libjvm.so+0x9e5260], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGBUS: [libjvm.so+0x9e5260], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGFPE: [libjvm.so+0x848480], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGPIPE: [libjvm.so+0x848480], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGXFSZ: [libjvm.so+0x848480], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGILL: [libjvm.so+0x848480], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none
-SIGUSR2: [libjvm.so+0x848350], sa_mask[0]=00100000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO
-SIGHUP: [libjvm.so+0x848540], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGINT: [libjvm.so+0x848540], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGTERM: [libjvm.so+0x848540], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-SIGQUIT: [libjvm.so+0x848540], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
-
-
---------------- S Y S T E M ---------------
-
-OS:DISTRIB_ID=Ubuntu
-DISTRIB_RELEASE=16.04
-DISTRIB_CODENAME=xenial
-DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS"
-
-uname:Linux 4.4.0-79-generic #100-Ubuntu SMP Wed May 17 19:58:14 UTC 2017 x86_64
-libc:glibc 2.23 NPTL 2.23
-rlimit: STACK 8192k, CORE 0k, NPROC 30580, NOFILE 65536, AS infinity
-load average:6.07 2.17 1.13
-
-/proc/meminfo:
-MemTotal: 7869244 kB
-MemFree: 156696 kB
-MemAvailable: 70240 kB
-Buffers: 1292 kB
-Cached: 1064008 kB
-SwapCached: 0 kB
-Active: 6615360 kB
-Inactive: 880956 kB
-Active(anon): 6593172 kB
-Inactive(anon): 861152 kB
-Active(file): 22188 kB
-Inactive(file): 19804 kB
-Unevictable: 128 kB
-Mlocked: 128 kB
-SwapTotal: 0 kB
-SwapFree: 0 kB
-Dirty: 1176 kB
-Writeback: 0 kB
-AnonPages: 6431560 kB
-Mapped: 352344 kB
-Shmem: 1022972 kB
-Slab: 98664 kB
-SReclaimable: 54872 kB
-SUnreclaim: 43792 kB
-KernelStack: 13136 kB
-PageTables: 50852 kB
-NFS_Unstable: 0 kB
-Bounce: 0 kB
-WritebackTmp: 0 kB
-CommitLimit: 3934620 kB
-Committed_AS: 12828968 kB
-VmallocTotal: 34359738367 kB
-VmallocUsed: 0 kB
-VmallocChunk: 0 kB
-HardwareCorrupted: 0 kB
-AnonHugePages: 3416064 kB
-CmaTotal: 0 kB
-CmaFree: 0 kB
-HugePages_Total: 0
-HugePages_Free: 0
-HugePages_Rsvd: 0
-HugePages_Surp: 0
-Hugepagesize: 2048 kB
-DirectMap4k: 155512 kB
-DirectMap2M: 7923712 kB
-
-
-CPU:total 4 (2 cores per cpu, 2 threads per core) family 6 model 58 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, aes, clmul, erms, ht, tsc, tscinvbit, tscinv
-
-/proc/cpuinfo:
-processor : 0
-vendor_id : GenuineIntel
-cpu family : 6
-model : 58
-model name : Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
-stepping : 9
-microcode : 0x1c
-cpu MHz : 3099.992
-cache size : 3072 KB
-physical id : 0
-siblings : 4
-core id : 0
-cpu cores : 2
-apicid : 0
-initial apicid : 0
-fpu : yes
-fpu_exception : yes
-cpuid level : 13
-wp : yes
-flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts
-bugs :
-bogomips : 5188.09
-clflush size : 64
-cache_alignment : 64
-address sizes : 36 bits physical, 48 bits virtual
-power management:
-
-processor : 1
-vendor_id : GenuineIntel
-cpu family : 6
-model : 58
-model name : Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
-stepping : 9
-microcode : 0x1c
-cpu MHz : 3099.992
-cache size : 3072 KB
-physical id : 0
-siblings : 4
-core id : 0
-cpu cores : 2
-apicid : 1
-initial apicid : 1
-fpu : yes
-fpu_exception : yes
-cpuid level : 13
-wp : yes
-flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts
-bugs :
-bogomips : 5188.09
-clflush size : 64
-cache_alignment : 64
-address sizes : 36 bits physical, 48 bits virtual
-power management:
-
-processor : 2
-vendor_id : GenuineIntel
-cpu family : 6
-model : 58
-model name : Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
-stepping : 9
-microcode : 0x1c
-cpu MHz : 3099.992
-cache size : 3072 KB
-physical id : 0
-siblings : 4
-core id : 1
-cpu cores : 2
-apicid : 2
-initial apicid : 2
-fpu : yes
-fpu_exception : yes
-cpuid level : 13
-wp : yes
-flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts
-bugs :
-bogomips : 5188.09
-clflush size : 64
-cache_alignment : 64
-address sizes : 36 bits physical, 48 bits virtual
-power management:
-
-processor : 3
-vendor_id : GenuineIntel
-cpu family : 6
-model : 58
-model name : Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
-stepping : 9
-microcode : 0x1c
-cpu MHz : 3099.992
-cache size : 3072 KB
-physical id : 0
-siblings : 4
-core id : 1
-cpu cores : 2
-apicid : 3
-initial apicid : 3
-fpu : yes
-fpu_exception : yes
-cpuid level : 13
-wp : yes
-flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts
-bugs :
-bogomips : 5188.09
-clflush size : 64
-cache_alignment : 64
-address sizes : 36 bits physical, 48 bits virtual
-power management:
-
-
-
-Memory: 4k page, physical 7869244k(156696k free), swap 0k(0k free)
-
-vm_info: OpenJDK 64-Bit Server VM (25.112-b736) for linux-amd64 JRE (1.8.0_112-release-b736), built on Mar 6 2017 09:31:19 by "builder" with gcc 4.8.4
-
-time: Thu Jun 8 15:56:01 2017
-elapsed time: 11 seconds (0d 0h 0m 11s)
-
diff --git a/sample/proguard-rules.pro b/sample/proguard-rules.pro
new file mode 100644
index 000000000..f1b424510
--- /dev/null
+++ b/sample/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/sample/res/mipmap-hdpi/ic_launcher.png b/sample/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index cde69bccc..000000000
Binary files a/sample/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/res/mipmap-mdpi/ic_launcher.png b/sample/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index c133a0cbd..000000000
Binary files a/sample/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/res/mipmap-xhdpi/ic_launcher.png b/sample/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index bfa42f0e7..000000000
Binary files a/sample/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/res/mipmap-xxhdpi/ic_launcher.png b/sample/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 324e72cdd..000000000
Binary files a/sample/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/sample/res/values-w820dp/dimens.xml b/sample/res/values-w820dp/dimens.xml
deleted file mode 100644
index f11f7450a..000000000
--- a/sample/res/values-w820dp/dimens.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/sample/res/values/dimens.xml b/sample/res/values/dimens.xml
deleted file mode 100644
index f11f7450a..000000000
--- a/sample/res/values/dimens.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/sample/res/values/strings.xml b/sample/res/values/strings.xml
deleted file mode 100644
index 64644c568..000000000
--- a/sample/res/values/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
- FolioReader sample
-
-
diff --git a/sample/res/values/styles.xml b/sample/res/values/styles.xml
deleted file mode 100644
index 1355d0900..000000000
--- a/sample/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
diff --git a/sample/src/androidTest/java/com/folioreader/android/sample/ExampleInstrumentedTest.java b/sample/src/androidTest/java/com/folioreader/android/sample/ExampleInstrumentedTest.java
new file mode 100644
index 000000000..414b25209
--- /dev/null
+++ b/sample/src/androidTest/java/com/folioreader/android/sample/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.folioreader.android.sample;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.folioreader.android.sample", appContext.getPackageName());
+ }
+}
diff --git a/sample/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
similarity index 68%
rename from sample/AndroidManifest.xml
rename to sample/src/main/AndroidManifest.xml
index d34928ff6..330ec6898 100644
--- a/sample/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -1,32 +1,33 @@
+ package="com.folioreader.android.sample">
+ android:largeHeap="true"
+ android:networkSecurityConfig="@xml/network_security_config"
+ android:roundIcon="@mipmap/ic_launcher_round"
+ android:supportsRtl="false"
+ android:theme="@style/AppTheme">
+
+ android:label="@string/app_name">
-
+
-
+ android:theme="@style/AppTheme.NoActionBar" />
+
-
+
\ No newline at end of file
diff --git a/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java b/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java
index 4a98f319b..8503046bd 100644
--- a/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java
+++ b/sample/src/main/java/com/folioreader/android/sample/HomeActivity.java
@@ -1,18 +1,18 @@
/*
-* Copyright (C) 2016 Pedro Paulo de Amorim
-*
-* 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.
-*/
+ * Copyright (C) 2016 Pedro Paulo de Amorim
+ *
+ * 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.folioreader.android.sample;
import android.os.Bundle;
@@ -25,11 +25,13 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
+import com.folioreader.Config;
+import com.folioreader.FolioReader;
import com.folioreader.model.HighLight;
import com.folioreader.model.ReadPosition;
import com.folioreader.model.ReadPositionImpl;
import com.folioreader.ui.base.OnSaveHighlight;
-import com.folioreader.FolioReader;
+import com.folioreader.util.AppUtil;
import com.folioreader.util.ObjectMapperSingleton;
import com.folioreader.util.OnHighlightListener;
import com.folioreader.util.ReadPositionListener;
@@ -56,49 +58,61 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
.setOnHighlightListener(this)
.setReadPositionListener(this);
+ getHighlightsAndSave();
+
findViewById(R.id.btn_raw).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- folioReader.openBook(R.raw.adventures);
+
+ Config config = AppUtil.getSavedConfig(getApplicationContext());
+ if (config == null)
+ config = new Config();
+
+ config.setAllowedDirection(Config.AllowedDirection.VERTICAL_AND_HORIZONTAL);
+
+ folioReader.setConfig(config, true)
+ .openBook(R.raw.adventures);
}
});
findViewById(R.id.btn_assest).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- folioReader.openBook("file:///android_asset/TheSilverChair.epub");
+
+ ReadPosition readPosition = getLastReadPosition();
+
+ Config config = AppUtil.getSavedConfig(getApplicationContext());
+ if (config == null)
+ config = new Config();
+
+ config.setAllowedDirection(Config.AllowedDirection.VERTICAL_AND_HORIZONTAL);
+
+ folioReader.setReadPosition(readPosition)
+ .setConfig(config, true)
+ .openBook("file:///android_asset/TheSilverChair.epub");
}
});
-
- getHighlightsAndSave();
- getLastReadPosition();
}
- private void getLastReadPosition() {
+ private ReadPosition getLastReadPosition() {
- new Thread(new Runnable() {
- @Override
- public void run() {
-
- ObjectReader objectReader = ObjectMapperSingleton.getObjectMapper().reader();
- ReadPosition readPosition = null;
+ ReadPosition readPosition = null;
+ ObjectReader objectReader = ObjectMapperSingleton.getObjectMapper().reader();
- try {
- readPosition = objectReader.forType(ReadPositionImpl.class)
- .readValue(getAssets().open("read_positions/read_position.json"));
- } catch (IOException e) {
- e.printStackTrace();
- }
+ try {
+ readPosition = objectReader.forType(ReadPositionImpl.class)
+ .readValue(getAssets().open("read_positions/read_position.json"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
- folioReader.setReadPosition(readPosition);
- }
- }).start();
+ return readPosition;
}
@Override
public void saveReadPosition(ReadPosition readPosition) {
- Toast.makeText(this, "ReadPosition = " + readPosition.toJson(), Toast.LENGTH_SHORT).show();
+ //Toast.makeText(this, "ReadPosition = " + readPosition.toJson(), Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "-> ReadPosition = " + readPosition.toJson());
}
diff --git a/sample/src/main/java/com/folioreader/android/sample/TestFragment.java b/sample/src/main/java/com/folioreader/android/sample/TestFragment.java
deleted file mode 100644
index 5707b9142..000000000
--- a/sample/src/main/java/com/folioreader/android/sample/TestFragment.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.folioreader.android.sample;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.webkit.WebView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-/**
- * Created by priyank on 4/1/16.
- */
-public class TestFragment extends Fragment {
- private static final String KEY_CONTENT = "TestFragment:Content";
- private static final String HTML = "\n" +
- "The Silver Chair
The Silver Chair Copyright © 2014 epubBooks
All Rights Reserved.
This publication is protected by copyright. By payment of the required fees, you have been granted the non-exclusive, non-transferable right to access and read the text of this ebook on-screen or via personal text-to-speech computer systems. No part of this text may be reproduced, transmitted, downloaded, decompiled, reverse engineered, stored in or introduced into any information storage and retrieval system, in any form or by any means, whether electronic or mechanical, now known or hereinafter invented, without the express written permission of epubBooks.
This publication is protected by copyright. By payment of the required fees, you have been granted the non-exclusive, non-transferable right to access and read the text of this ebook on-screen or via personal text-to-speech computer systems. No part of this text may be reproduced, transmitted, downloaded, decompiled, reverse engineered, stored in or introduced into any information storage and retrieval system, in any form or by any means, whether electronic or mechanical, now known or hereinafter invented, without the express written permission of epubBooks.
\n" +
- "
www.epubbooks.com ";
-
- public static TestFragment newInstance(String content) {
- TestFragment fragment = new TestFragment();
- return fragment;
- }
-
- private String mContent = "???";
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- if ((savedInstanceState != null) && savedInstanceState.containsKey(KEY_CONTENT)) {
- mContent = savedInstanceState.getString(KEY_CONTENT);
- }
-
- WebView webView = new WebView(getActivity());
- webView.loadData(HTML, null, null);
-
- LinearLayout layout = new LinearLayout(getActivity());
- layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- layout.setGravity(Gravity.CENTER);
- layout.addView(webView);
-
- return layout;
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putString(KEY_CONTENT, mContent);
- }
-}
diff --git a/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml b/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 000000000..c7bd21dbd
--- /dev/null
+++ b/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/src/main/res/drawable/ic_launcher_background.xml b/sample/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 000000000..d5fccc538
--- /dev/null
+++ b/sample/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/res/layout/activity_home.xml b/sample/src/main/res/layout/activity_home.xml
similarity index 100%
rename from sample/res/layout/activity_home.xml
rename to sample/src/main/res/layout/activity_home.xml
diff --git a/sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher.png b/sample/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..a2f590828
Binary files /dev/null and b/sample/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..1b5239980
Binary files /dev/null and b/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher.png b/sample/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..ff10afd6e
Binary files /dev/null and b/sample/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..115a4c768
Binary files /dev/null and b/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..dcd3cd808
Binary files /dev/null and b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..459ca609d
Binary files /dev/null and b/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..8ca12fe02
Binary files /dev/null and b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..8e19b410a
Binary files /dev/null and b/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..b824ebdd4
Binary files /dev/null and b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..4c19a13c2
Binary files /dev/null and b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/sample/res/raw/adventures.epub b/sample/src/main/res/raw/adventures.epub
similarity index 100%
rename from sample/res/raw/adventures.epub
rename to sample/src/main/res/raw/adventures.epub
diff --git a/sample/res/raw/barrett.epub b/sample/src/main/res/raw/barrett.epub
similarity index 100%
rename from sample/res/raw/barrett.epub
rename to sample/src/main/res/raw/barrett.epub
diff --git a/sample/res/raw/varun.epub b/sample/src/main/res/raw/varun.epub
similarity index 100%
rename from sample/res/raw/varun.epub
rename to sample/src/main/res/raw/varun.epub
diff --git a/sample/src/main/res/values/colors.xml b/sample/src/main/res/values/colors.xml
new file mode 100644
index 000000000..3ab3e9cbc
--- /dev/null
+++ b/sample/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml
new file mode 100644
index 000000000..e062e03fa
--- /dev/null
+++ b/sample/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ FolioReader sample
+
diff --git a/sample/src/main/res/values/styles.xml b/sample/src/main/res/values/styles.xml
new file mode 100644
index 000000000..5885930df
--- /dev/null
+++ b/sample/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/sample/src/test/java/com/folioreader/android/sample/ExampleUnitTest.java b/sample/src/test/java/com/folioreader/android/sample/ExampleUnitTest.java
new file mode 100644
index 000000000..0fa9acaf6
--- /dev/null
+++ b/sample/src/test/java/com/folioreader/android/sample/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.folioreader.android.sample;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/webViewMarker/build.gradle b/webViewMarker/build.gradle
index 78a8b04e0..fa97f71f3 100644
--- a/webViewMarker/build.gradle
+++ b/webViewMarker/build.gradle
@@ -13,7 +13,7 @@ ext {
siteUrl = 'https://github.com/FolioReader/FolioReader-Android'
gitUrl = 'https://github.com/FolioReader/FolioReader-Android.git'
- libraryVersion = '0.3.11'
+ libraryVersion = '0.4.0'
developerId = 'mobisystech'
developerName = 'Folio Reader'
@@ -25,14 +25,13 @@ ext {
}
android {
- compileSdkVersion 27
- buildToolsVersion '27.0.3'
+ compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
defaultConfig {
- versionCode Integer.parseInt(project.VERSION_CODE)
- versionName project.VERSION_NAME
minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK)
targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION)
+ versionCode Integer.parseInt(project.VERSION_CODE)
+ versionName project.VERSION_NAME
}
buildTypes {