Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Support added for loading local files through file:// handler
Browse files Browse the repository at this point in the history
  • Loading branch information
keianhzo committed Oct 11, 2018
1 parent 73cba99 commit 1415b5e
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.mozilla.vrbrowser;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.util.Log;

import org.mozilla.geckoview.GeckoSession;
Expand Down Expand Up @@ -54,7 +56,7 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in
}
}

private void handleContentPermission(final String aUri, final PermissionWidget.PermissionType aType, final Callback aCallback) {
public void handlePermission(final String aUri, final PermissionWidget.PermissionType aType, final Callback aCallback) {
if (mPermissionWidget == null) {
mPermissionWidget = new PermissionWidget(mContext);
mPermissionWidget.getPlacement().parentHandle = mParentWidgetHandle;
Expand Down Expand Up @@ -122,7 +124,7 @@ public void onContentPermissionRequest(GeckoSession aSession, String aUri, int a
return;
}

handleContentPermission(aUri, type, callback);
handlePermission(aUri, type, callback);
}

@Override
Expand Down Expand Up @@ -155,6 +157,51 @@ public void reject() {
}
};

handleContentPermission(aUri, type, callback);
handlePermission(aUri, type, callback);
}

public boolean isPermissionGranted(@NonNull String permission) {
return mContext.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
}

// Handle app permissions that Gecko doesn't handle itself yet
public void onAppPermissionRequest(final GeckoSession aSession, String aUri, final String permission, final Callback callback) {
Log.d(LOGTAG, "onAppPermissionRequest: " + aUri);

// If the permission is already granted we just grant
if (mContext.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {

// Check if we support a rationale for that permission
PermissionWidget.PermissionType type = null;
if (permission.equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {
type = PermissionWidget.PermissionType.ReadExternalStorage;
}

if (type != null) {
// Show rationale
handlePermission(mContext.getString(R.string.app_name), type, new Callback() {
@Override
public void grant() {
onAndroidPermissionsRequest(aSession, new String[]{permission}, callback);
}

@Override
public void reject() {
if (callback != null) {
callback.reject();
}
}
});

} else {
// Let Android handle the permission request
onAndroidPermissionsRequest(aSession, new String[]{permission}, callback);
}

} else {
if (callback != null) {
callback.grant();
}
}
}
}
39 changes: 35 additions & 4 deletions app/src/common/shared/org/mozilla/vrbrowser/SessionStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,30 @@
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;

import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.geckoview.*;
import org.mozilla.geckoview.GeckoResult;
import org.mozilla.geckoview.GeckoRuntime;
import org.mozilla.geckoview.GeckoRuntimeSettings;
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.geckoview.GeckoSessionSettings;
import org.mozilla.vrbrowser.telemetry.TelemetryWrapper;
import org.mozilla.vrbrowser.utils.ValueHolder;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class SessionStore implements GeckoSession.NavigationDelegate, GeckoSession.ProgressDelegate,
GeckoSession.ContentDelegate, GeckoSession.TextInputDelegate, GeckoSession.TrackingProtectionDelegate,
Expand Down Expand Up @@ -787,14 +801,31 @@ public GeckoResult<Boolean> onLoadRequest(@NonNull GeckoSession aSession,
@NonNull String aUri,
@TargetWindow int target,
@LoadRequestFlags int flags) {
GeckoResult<Boolean> result = new GeckoResult<>();

final GeckoResult<Boolean> result = new GeckoResult<>();
if (aUri.equalsIgnoreCase(PRIVATE_BROWSING_URI)) {
switchPrivateMode();
result.complete(true);

} else {
result.complete(false);
final ValueHolder<Integer> count = new ValueHolder(new Integer(0));
final ValueHolder<Boolean> listenersResult = new ValueHolder(new Boolean(false));
for (GeckoSession.NavigationDelegate listener: mNavigationListeners) {
GeckoResult<Boolean> listenerResult = listener.onLoadRequest(aSession, aUri, target, flags);
listenerResult.then(new GeckoResult.OnValueListener<Boolean, Object>() {
@Nullable
@Override
public GeckoResult<Object> onValue(@Nullable Boolean value) {
listenersResult.setValue(listenersResult.getValue().booleanValue() | value);
if (count.getValue() == mNavigationListeners.size() - 1) {
result.complete(listenersResult.getValue());
}
count.setValue(count.getValue().intValue() + 1);

return null;
}
});
}
}

return result;
Expand Down
27 changes: 25 additions & 2 deletions app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,30 @@
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Keep;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

import org.mozilla.gecko.GeckoVRManager;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.geckoview.CrashReporter;
import org.mozilla.geckoview.GeckoRuntime;
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.vrbrowser.audio.AudioEngine;
import org.mozilla.vrbrowser.audio.VRAudioTheme;
import org.mozilla.vrbrowser.search.SearchEngine;
import org.mozilla.vrbrowser.telemetry.TelemetryWrapper;
import org.mozilla.vrbrowser.ui.*;
import org.mozilla.vrbrowser.ui.BrowserWidget;
import org.mozilla.vrbrowser.ui.CrashDialogWidget;
import org.mozilla.vrbrowser.ui.KeyboardWidget;
import org.mozilla.vrbrowser.ui.NavigationBarWidget;
import org.mozilla.vrbrowser.ui.OffscreenDisplay;
import org.mozilla.vrbrowser.ui.RootWidget;
import org.mozilla.vrbrowser.ui.TopBarWidget;
import org.mozilla.vrbrowser.ui.TrayWidget;

import java.io.IOException;
import java.net.URISyntaxException;
Expand Down Expand Up @@ -851,6 +860,20 @@ public void run() {
});
}

@Override
public boolean isPermissionGranted(@NonNull String permission) {
return mPermissionDelegate.isPermissionGranted(permission);
}

@Override
public void requestPermission(@NonNull String uri, @NonNull String permission, GeckoSession.PermissionDelegate.Callback aCallback) {
mPermissionDelegate.onAppPermissionRequest(
SessionStore.get().getCurrentSession(),
uri,
permission,
aCallback);
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import android.support.annotation.NonNull;
import android.view.View;

import org.mozilla.geckoview.GeckoSession;

public interface WidgetManagerDelegate {
interface UpdateListener {
void onWidgetUpdate(Widget aWidget);
Expand Down Expand Up @@ -30,8 +32,10 @@ interface FocusChangeListener {
void keyboardDismissed();
void updateEnvironment();
void updatePointerColor();
void addPermissionListener(@NonNull PermissionListener aListener);
void removePermissionListener(@NonNull PermissionListener aListener);
void addFocusChangeListener(@NonNull FocusChangeListener aListener);
void removeFocusChangeListener(@NonNull FocusChangeListener aListener);
void addPermissionListener(PermissionListener aListener);
void removePermissionListener(PermissionListener aListener);
boolean isPermissionGranted(@NonNull String permission);
void requestPermission(@NonNull String uri, @NonNull String permission, GeckoSession.PermissionDelegate.Callback aCallback);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package org.mozilla.vrbrowser.ui;

import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
Expand Down Expand Up @@ -404,12 +405,45 @@ public void onCanGoForward(GeckoSession aSession, boolean canGoForward) {
}

@Override
public GeckoResult<Boolean> onLoadRequest(GeckoSession aSession, String aUri, int target, int flags) {
public GeckoResult<Boolean> onLoadRequest(GeckoSession aSession, final String aUri, int target, int flags) {
if (mURLBar != null) {
Log.d(LOGTAG, "Got onLoadUri");
mURLBar.setURL(aUri);
}
return null;

final GeckoResult<Boolean> result = new GeckoResult<>();
if (aUri != null) {
Uri uri = Uri.parse(aUri);
if (uri.getScheme().equals("file")) {
if (!mWidgetManager.isPermissionGranted(android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
mWidgetManager.requestPermission(
aUri,
android.Manifest.permission.READ_EXTERNAL_STORAGE,
new GeckoSession.PermissionDelegate.Callback() {
@Override
public void grant() {
result.complete(false);
}

@Override
public void reject() {
result.complete(false);
}
});

} else {
result.complete(false);
}

} else {
result.complete(false);
}

} else {
result.complete(false);
}

return result;
}

// Progress Listener
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public enum PermissionType {
Microphone,
CameraAndMicrophone,
Location,
Notification
Notification,
ReadExternalStorage
}

public PermissionWidget(Context aContext) {
Expand Down Expand Up @@ -132,6 +133,10 @@ public void showPrompt(String aUri, PermissionType aType, GeckoSession.Permissio
messageId = R.string.permission_notification;
iconId = R.drawable.ic_icon_dialog_notification;
break;
case ReadExternalStorage:
messageId = R.string.permission_read_external_storage;
iconId = R.drawable.ic_icon_dialog_notification;
break;
default:
Log.e(LOGTAG, "Unimplemented permission type: " + aType);
aCallback.reject();
Expand Down
19 changes: 19 additions & 0 deletions app/src/common/shared/org/mozilla/vrbrowser/utils/ValueHolder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.mozilla.vrbrowser.utils;

public class ValueHolder<T> {

private T value;

public ValueHolder(T aValue) {
value = aValue;
}

public T getValue() {
return value;
}

public void setValue(Object newValue) {
value = (T) newValue;
}

}
6 changes: 3 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="org.mozilla.vrbrowser.CRASH_RECEIVER_PERMISSION"/>

<permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<permission android:name="org.mozilla.vrbrowser.CRASH_RECEIVER_PERMISSION"
android:protectionLevel="signature">
</permission>
<uses-permission android:name="org.mozilla.vrbrowser.CRASH_RECEIVER_PERMISSION"/>
android:protectionLevel="signature"/>

<application
android:name=".VRBrowserApplication"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
<string name="permission_location">Will you allow %1$s to access your location?</string>
<!-- Parameter will be replaced with the app name -->
<string name="permission_notification">Will you allow %1$s to send notifications?</string>
<!-- Parameter will be replaced with the app name -->
<string name="permission_read_external_storage">Will you allow %1$s to read your external storage?</string>
<string name="speak_now">Speak now</string>
<string name="settings_version">version %1$s</string>
<string name="settings_crash_reporting">Crash Reporting</string>
Expand Down

0 comments on commit 1415b5e

Please sign in to comment.