Giter VIP home page Giter VIP logo

grapheneos / pdfviewer Goto Github PK

View Code? Open in Web Editor NEW
526.0 21.0 93.0 2.43 MB

Simple Android PDF viewer based on pdf.js and content providers. The app doesn't require any permissions. The PDF stream is fed into the sandboxed WebView without giving it access to content or files. CSP is used to enforce that the JavaScript and styling properties within the WebView are entirely static.

Home Page: https://grapheneos.org/

License: MIT License

JavaScript 18.57% HTML 0.62% Java 53.90% CSS 2.74% Kotlin 24.18%
android pdf pdf-viewer security grapheneos pdfjs

pdfviewer's Introduction

Simple Android PDF viewer based on pdf.js and content providers. The app doesn't require any permissions. The PDF stream is fed into the sandboxed WebView without giving it access to content or files. Content-Security-Policy is used to enforce that the JavaScript and styling properties within the WebView are entirely static content from the apk assets. It reuses the hardened Chromium rendering stack while only exposing a tiny subset of the attack surface compared to actual web content. The PDF rendering code itself is memory safe with dynamic code evaluation disabled, and even if an attacker did gain code execution by exploiting the underlying web rendering engine, they're within the Chromium renderer sandbox with no access to the network (unlike a browser), files, or other content.

pdfviewer's People

Contributors

amalgame21 avatar atrate avatar dependabot-preview[bot] avatar dependabot[bot] avatar empratyush avatar emschu avatar flawedworld avatar girlbossceo avatar hanouta avatar inthewaves avatar mhshetty avatar octocorvus avatar patrykmis avatar quh4gko8 avatar randomhydrosol avatar thestinger avatar tommy-geenexus avatar virgiel avatar xsims avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pdfviewer's Issues

zoom

Basic zoom feature. Can be enhanced later.

Hiding app icon from launcher

I think it would be nice if there was an option to hide the app's icon from the launcher drawer.

I really liked Google's standalone pdf viewer app because it stayed quiet and hidden, and gave you just the minimal functionality you needed to view pdf documents. But of course, Google, you know. Plus they took down their pdf viewer some time ago anyway.

This pdf viewer is the closest I've seen to what I want, the only thing missing would be the ability to hide the app from my launcher. I'll never need to launch the app from the drawer, if I need to open a PDF I'll just open it directly from file manager.

consider supporting incremental rendering for non-zoom again

Rendering is currently done in an off-screen canvas and the page isn't updated until the rendering is completely finished. Ideally, it could render to a visible canvas to display the progress, but this proved to be incredibly slow compared to offscreen rendering. Perhaps it could regularly copy over the canvas as a way to work around that. It's possible that pdf.js will improve this at some point so that working around it won't be required anymore and it can be reverted to how it used to be rather than using the offscreen canvas.

Change the page with left or right side

Hello, I open an issue to request a feature

Is it possible, as in mupdf, to add an option so that when you touch the left or right side of the screen, it changes the page?

Thank you

Increase zoom range

Many common PDFs (with small page formats?) cannot be sufficiently enlarged to fit the screen, let alone zoomed into. An increase of the zoom range by a factor of 2, better 4, should fix this.

Fail to open PDF document

When opening a PDF file from another app, it fails to open the said file, displaying a blank white page. Checking document properties gives a "Failed to obtain document metadata" popup. The list of pages to jump to is empty. All of this also happens when using "open document" function in app.

Android version: 10
Affected app versions: 7 - 9

The application crashes when i Open pdf file

Expected behavior:

The application should not be crash when i open pdf file.

Actual behavior:

After configure the application when i open pdf file,the application is you can see in bug video proprealy.

How to reproduce:

1.Download the app
2.Open the application.
3.1st time going my device files
4.Then click on document of other.
5.click on pdf file and open
6.Note the Bug.

information

App version:v1
os:Android 8.1.0
Device: symphony i72

Recording of the bug

https://youtu.be/5O45_DwQbwo

Logcat:


07-21 14:17:21.905 18839 18839 E AndroidRuntime: FATAL EXCEPTION: main
07-21 14:17:21.905 18839 18839 E AndroidRuntime: Process: com.kaiserpudding.howtheywrite, PID: 18839
07-21 14:17:21.905 18839 18839 E AndroidRuntime: java.lang.IllegalArgumentException: navigation destination com.kaiserpudding.howtheywrite:id/action_characterList_to_characterDetail is unknown to this NavController
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at androidx.navigation.NavController.navigate(NavController.java:816)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at androidx.navigation.NavController.navigate(NavController.java:757)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at androidx.navigation.NavController.navigate(NavController.java:743)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at androidx.navigation.NavController.navigate(NavController.java:875)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at com.kaiserpudding.howtheywrite.main.MainActivity.onCharacterListItemInteraction(MainActivity.kt:99)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at com.kaiserpudding.howtheywrite.characterList.CharacterListFragment.onListInteraction(CharacterListFragment.kt:113)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at com.kaiserpudding.howtheywrite.shared.multiSelect.MultiSelectFragment.onMultiSelectAdapterInteraction(MultiSelectFragment.kt:86)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at com.kaiserpudding.howtheywrite.shared.multiSelect.MultiSelectAdapter$MultiSelectViewHolder$1.onClick(MultiSelectAdapter.kt:93)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at android.view.View.performClick(View.java:6319)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at android.view.View$PerformClick.run(View.java:24837)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at android.os.Handler.handleCallback(Handler.java:790)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at android.os.Handler.dispatchMessage(Handler.java:99)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at android.os.Looper.loop(Looper.java:164)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at android.app.ActivityThread.main(ActivityThread.java:6747)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at java.lang.reflect.Method.invoke(Native Method)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:449)
07-21 14:17:21.905 18839 18839 E AndroidRuntime:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Change web search to use other search engines

Highlighting text in a PDF file and tapping 'web search' will run Vanadium and search using Google. It would be good to be able to use another search engine like DuckDuckGo. Vanadium settings are already set to use DuckDuckGo which works for web searches in Vanadium.

PDF Viewer version: 5
Vanadium version: 83.0.4103.83

App crash

AndroidRuntime: FATAL EXCEPTION: ModernAsyncTask #1
AndroidRuntime: Process: org.grapheneos.pdfviewer, PID: 10038
AndroidRuntime: java.lang.RuntimeException: An error occurred while executing doInBackground()
AndroidRuntime: at p0.f.done(Unknown Source:4)
AndroidRuntime: at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
AndroidRuntime: at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:271)
AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
AndroidRuntime: at java.lang.Thread.run(Thread.java:920)
AndroidRuntime: Caused by: java.lang.NumberFormatException: null
AndroidRuntime: at java.lang.Long.parseLong(Long.java:557)
AndroidRuntime: at java.lang.Long.valueOf(Long.java:808)
AndroidRuntime: at p0.a.f(Unknown Source:2)
AndroidRuntime: at p0.e.call(Unknown Source:2)
AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
AndroidRuntime: ... 3 more

pinch to zoom touch gestures

This should likely use a CSS transform during the gesture and then render again once the gesture is finished.

move away from deprecated Loaders

https://developer.android.com/guide/components/loaders

Loaders have been deprecated as of Android P (API 28). The recommended option for dealing with loading data while handling the Activity and Fragment lifecycles is to use a combination of ViewModels and LiveData. ViewModels survive configuration changes like Loaders but with less boilerplate. LiveData provides a lifecycle-aware way of loading data that you can reuse in multiple ViewModels. You can also combine LiveData using MediatorLiveData , and any observable queries, such as those from a Room database, can be used to observe changes to the data. ViewModels and LiveData are also available in situations where you do not have access to the LoaderManager, such as in a Service. Using the two in tandem provides an easy way to access the data your app needs without having to deal with the UI lifecycle. To learn more about LiveData see the LiveData guide and to learn more about ViewModels see the ViewModel guide.

indicate when a page is loading

Pages now render in an offscreen canvas to drastically improve performance. This works around the ridiculously slow 2D canvas implementation in Chromium. However, it means people can no longer see the page rendering until it's done. It would be a good idea to show a loading icon or something like that.

[Feature Request] Other Format Support & Directory Listing

Not sure if this is out of the scope of the project, but I figure I should ask.

It would be absolutely amazing to be able to use your reader as a full reader, not just for pdf's. This is a limiting factor imo. It would be nice to at minimum have epub and archive support.

My second request was to have a directory view on launch, or basically a favorited directory where you can see all your books in that directory. Would be easier than browsing all the way to the directory each time. However I'm unsure if this was avoided purposely for a security reason, which would be understandable. But if possible, it would be nice.

Add/Change Next Page Button

It is tedious to progress to the next page in PDF files due to the next page button being inside the app menu.

It would be beneficial to add the next page button to the right of the previous page button, which is easily accessible outside of the menu, or replace the previous page button with the next page button, since the next page is used much more than the previous page button when progressing through a PDF file.

PDF Viewer crash

RQ2A.210505.002.2021.05.19.06

App constantly crashes
Different files attempted

move the PdfViewer activity to be hosted as a Fragment

Google seems to prefer and consider single-Activity architecture with Fragments as a best practice for managing UI, as seen by their Sunflower app and https://android-developers.googleblog.com/2018/05/use-android-jetpack-to-accelerate-your.html (though now they're looking into Compose and whatever new frameworks they want to move one to lol)

Using a Fragment for the WebView might be helpful for future features such as

  • supporting multiple tabs of PDFs (though this could be beyond the scope of a simple PDF reader)
  • supporting some initial blank screen to tell users to pick a document and, after document selection, swapping it out with the Fragment that holds the WebView

Issues displaying .PDF images which are placed inside PDF documents

Expected Behaviour:

The application should display images in the way described in the LaTeX document, e.g. centred

Actual Behaviour:

Images are displayed in the top left hand corner of the document.

How to reproduce:

  1. Create an image using Inkscape or Powerpoint and save it as a .pdf.
  2. Place image into a LaTeX document with appropriate alignment and justification and compile using pdfLaTeX.
  3. Open pdf document in Secure PDF viewer.
  4. .pdf images within the document are now displayed in top left hand corner.

Information:

App version: 3
OS: Android 10 (April 5, 2020 Security update)
Device: Pixel 3a (stock)

Notes:

I believe this is related to something called "Page Groups", please see here:
https://tex.stackexchange.com/questions/76273/multiple-pdfs-with-page-group-included-in-a-single-page-warning

This problem does not occur in other pdf document readers such as Adobe Reader or Microsoft Edge. I have attached the document for you to see the problem. Please open it in Secure PDF Viewer and any other pdf viewer to compare:
document.pdf

Bottom App bar support

Hello,

PdfViewer currently enforces the use of a top App bar and thus a top navigation, via the back/forward page selection, and top option selection via that component in the top corner.

This is not an ideal situation for people with some motor disabilities or people using mobile devices.

Would it be possible to add:

  • a bottom app bar;
  • a toggle or option to select between a top or bottom app bar?

Thank you!

investigate WebView still active after activity is destroyed

Consider the following changes, which passes the app Activity into the Channel as a variable to store it. If the app activity is considered destroyed, an exception is thrown:

Index: app/src/main/java/org/grapheneos/pdfviewer/PdfViewer.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- app/src/main/java/org/grapheneos/pdfviewer/PdfViewer.java	(revision 6f8a37c054b3bcd80259e08146d84b91931ee11f)
+++ app/src/main/java/org/grapheneos/pdfviewer/PdfViewer.java	(date 1598594097000)
@@ -24,6 +24,7 @@
 import android.widget.Toast;
 
 import androidx.appcompat.app.AppCompatActivity;
+import androidx.lifecycle.Lifecycle;
 import androidx.loader.app.LoaderManager;
 import androidx.loader.content.Loader;
 
@@ -101,34 +102,52 @@
     private Snackbar snackbar;
 
     private class Channel {
+        private PdfViewer mOwner;
+
+        Channel(PdfViewer owner) {
+            mOwner = owner;
+        }
+
+        private void throwIfOwnerDestroyed() {
+            if (mOwner.getLifecycle().getCurrentState().equals(Lifecycle.State.DESTROYED)) {
+                throw new AssertionError("JavaBridge/Channel thread still active!");
+            }
+        }
+
         @JavascriptInterface
         public int getWindowInsetTop() {
+            throwIfOwnerDestroyed();
             return windowInsetTop;
         }
 
         @JavascriptInterface
         public int getPage() {
+            throwIfOwnerDestroyed();
             return mPage;
         }
 
         @JavascriptInterface
         public float getZoomRatio() {
+            throwIfOwnerDestroyed();
             return mZoomRatio;
         }
 
         @JavascriptInterface
         public int getDocumentOrientationDegrees() {
+            throwIfOwnerDestroyed();
             return mDocumentOrientationDegrees;
         }
 
         @JavascriptInterface
         public void setNumPages(int numPages) {
+            throwIfOwnerDestroyed();
             mNumPages = numPages;
             runOnUiThread(PdfViewer.this::invalidateOptionsMenu);
         }
 
         @JavascriptInterface
         public void setDocumentProperties(final String properties) {
+            throwIfOwnerDestroyed();
             if (mDocumentProperties != null) {
                 throw new SecurityException("mDocumentProperties not null");
             }
@@ -171,7 +190,7 @@
 
         CookieManager.getInstance().setAcceptCookie(false);
 
-        mWebView.addJavascriptInterface(new Channel(), "channel");
+        mWebView.addJavascriptInterface(new Channel(this), "channel");
 
         mWebView.setWebViewClient(new WebViewClient() {
             private WebResourceResponse fromAsset(final String mime, final String path) {

Exceptions like these appear in logcat when I open a PDF that takes a while to load and then do orientation changes in quick succession (with auto-rotate turned on):

2020-08-27 22:55:53.235 26554-26732/org.grapheneos.pdfviewer.debug W/System.err: java.lang.AssertionError: JavaBridge/Channel thread still active!
2020-08-27 22:55:53.235 26554-26732/org.grapheneos.pdfviewer.debug W/System.err:     at org.grapheneos.pdfviewer.PdfViewer$Channel.throwIfOwnerDestroyed(PdfViewer.java:113)
2020-08-27 22:55:53.235 26554-26732/org.grapheneos.pdfviewer.debug W/System.err:     at org.grapheneos.pdfviewer.PdfViewer$Channel.setNumPages(PdfViewer.java:143)
2020-08-27 22:55:53.236 26554-26732/org.grapheneos.pdfviewer.debug W/System.err:     at android.os.MessageQueue.nativePollOnce(Native Method)
2020-08-27 22:55:53.236 26554-26732/org.grapheneos.pdfviewer.debug W/System.err:     at android.os.MessageQueue.next(MessageQueue.java:336)
2020-08-27 22:55:53.236 26554-26732/org.grapheneos.pdfviewer.debug W/System.err:     at android.os.Looper.loop(Looper.java:174)
2020-08-27 22:55:53.236 26554-26732/org.grapheneos.pdfviewer.debug W/System.err:     at android.os.HandlerThread.run(HandlerThread.java:67)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.