Bug 1699480 - Add setPermission, update onContentPermissionRequest to use ContentPermission, and let Gecko manage and persist permissions in GV. r=agi,geckoview-reviewers,owlish

Differential Revision: https://phabricator.services.mozilla.com/D112042
This commit is contained in:
Dylan Roeh 2021-05-17 15:55:21 +00:00
Родитель 0e8b28fb35
Коммит ff4369ad7c
14 изменённых файлов: 208 добавлений и 151 удалений

Просмотреть файл

@ -127,16 +127,6 @@ static const nsLiteralCString kPreloadPermissions[] = {
// removed. See bug 1428130.
"cookie"_ns};
// Certain permissions should never be persisted to disk under GeckoView; it's
// the responsibility of the app to manage storing these beyond the scope of
// a single session.
#ifdef ANDROID
static const nsLiteralCString kGeckoViewRestrictedPermissions[] = {
"MediaManagerVideo"_ns, "geolocation"_ns,
"desktop-notification"_ns, "persistent-storage"_ns,
"trackingprotection"_ns, "trackingprotection-pb"_ns};
#endif
// NOTE: nullptr can be passed as aType - if it is this function will return
// "false" unconditionally.
bool IsPreloadPermission(const nsACString& aType) {
@ -554,11 +544,6 @@ bool IsExpandedPrincipal(nsIPrincipal* aPrincipal) {
bool IsPersistentExpire(uint32_t aExpire, const nsACString& aType) {
bool res = (aExpire != nsIPermissionManager::EXPIRE_SESSION &&
aExpire != nsIPermissionManager::EXPIRE_POLICY);
#ifdef ANDROID
for (const auto& perm : kGeckoViewRestrictedPermissions) {
res = res && !perm.Equals(aType);
}
#endif
return res;
}

Просмотреть файл

@ -10,6 +10,7 @@ const { XPCOMUtils } = ChromeUtils.import(
);
XPCOMUtils.defineLazyModuleGetters(this, {
E10SUtils: "resource://gre/modules/E10SUtils.jsm",
GeckoViewUtils: "resource://gre/modules/GeckoViewUtils.jsm",
Services: "resource://gre/modules/Services.jsm",
});
@ -245,31 +246,37 @@ class GeckoViewPermission {
.sendRequestForResult({
type: "GeckoView:ContentPermission",
uri: aRequest.principal.URI.displaySpec,
principal: E10SUtils.serializePrincipal(aRequest.principal),
perm: perm.type,
value: perm.capability,
contextId:
aRequest.principal.originAttributes.geckoViewSessionContextId ?? null,
privateMode: aRequest.principal.privateBrowsingId != 0,
})
.then(granted => {
if (!granted) {
return false;
.then(value => {
if (value == Services.perms.ALLOW_ACTION) {
// Ask for app permission after asking for content permission.
if (perm.type === "geolocation") {
return this.getAppPermissions(dispatcher, [
PERM_ACCESS_FINE_LOCATION,
]);
}
}
// Ask for app permission after asking for content permission.
if (perm.type === "geolocation") {
return this.getAppPermissions(dispatcher, [
PERM_ACCESS_FINE_LOCATION,
]);
}
return true;
return value;
})
.catch(error => {
Cu.reportError("Permission error: " + error);
return /* granted */ false;
return /* value */ Services.perms.DENY_ACTION;
})
.then(granted => {
(granted ? aRequest.allow : aRequest.cancel)();
.then(value => {
(value == Services.perms.ALLOW_ACTION
? aRequest.allow
: aRequest.cancel)();
Services.perms.addFromPrincipal(
aRequest.principal,
perm.type,
granted ? Services.perms.ALLOW_ACTION : Services.perms.DENY_ACTION,
Services.perms.EXPIRE_SESSION
value,
Services.perms.EXPIRE_NEVER
);
// Manually release the target request here to facilitate garbage collection.
aRequest = undefined;

Просмотреть файл

@ -103,6 +103,7 @@ class GeckoViewStartup {
"GeckoView:ClearHostData",
"GeckoView:GetAllPermissions",
"GeckoView:GetPermissionsByURI",
"GeckoView:SetPermission",
],
});

Просмотреть файл

@ -25,9 +25,9 @@ class OpenWindowTest : BaseSessionTest() {
// Grant "desktop notification" permission
mainSession.delegateUntilTestEnd(object : Callbacks.PermissionDelegate {
override fun onContentPermissionRequest(session: GeckoSession, uri: String?, type: Int, callback: GeckoSession.PermissionDelegate.Callback) {
assertThat("Should grant DESKTOP_NOTIFICATIONS permission", type, equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
callback.grant()
override fun onContentPermissionRequest(session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission): GeckoResult<Int>? {
assertThat("Should grant DESKTOP_NOTIFICATIONS permission", perm.permission, equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW);
}
})
}

Просмотреть файл

@ -4,6 +4,7 @@
package org.mozilla.geckoview.test
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.RejectedPromiseException
@ -157,12 +158,12 @@ class PermissionDelegateTest : BaseSessionTest() {
// Ensure the content permission is asked first, before the Android permission.
@AssertCalled(count = 1, order = [1])
override fun onContentPermissionRequest(
session: GeckoSession, uri: String?, type: Int,
callback: GeckoSession.PermissionDelegate.Callback) {
assertThat("URI should match", uri, endsWith(url))
assertThat("Type should match", type,
session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission):
GeckoResult<Int>? {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat("Type should match", perm.permission,
equalTo(GeckoSession.PermissionDelegate.PERMISSION_GEOLOCATION))
callback.grant()
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW)
}
@AssertCalled(count = 1, order = [2])
@ -227,9 +228,9 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : Callbacks.PermissionDelegate {
@AssertCalled(count = 1)
override fun onContentPermissionRequest(
session: GeckoSession, uri: String?, type: Int,
callback: GeckoSession.PermissionDelegate.Callback) {
callback.reject()
session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission):
GeckoResult<Int>? {
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_DENY)
}
@AssertCalled(count = 0)
@ -286,12 +287,12 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : Callbacks.PermissionDelegate {
@AssertCalled(count = 1)
override fun onContentPermissionRequest(
session: GeckoSession, uri: String?, type: Int,
callback: GeckoSession.PermissionDelegate.Callback) {
assertThat("URI should match", uri, endsWith(url))
assertThat("Type should match", type,
session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission):
GeckoResult<Int>? {
assertThat("URI should match", perm.uri, endsWith(url))
assertThat("Type should match", perm.permission,
equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
callback.grant()
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW)
}
})
@ -339,9 +340,9 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : Callbacks.PermissionDelegate {
@AssertCalled(count = 1)
override fun onContentPermissionRequest(
session: GeckoSession, uri: String?, type: Int,
callback: GeckoSession.PermissionDelegate.Callback) {
callback.reject()
session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission):
GeckoResult<Int>? {
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_DENY)
}
})
@ -390,10 +391,11 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.waitUntilCalled(object : Callbacks.PermissionDelegate {
@AssertCalled(count = 2)
override fun onContentPermissionRequest(session: GeckoSession, uri: String?, type: Int, callback: GeckoSession.PermissionDelegate.Callback) {
override fun onContentPermissionRequest(session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission):
GeckoResult<Int>? {
val expectedType = if (sessionRule.currentCall.counter == 1) GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY_AUDIBLE else GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY_INAUDIBLE
assertThat("Type should match", type, equalTo(expectedType))
callback.reject()
assertThat("Type should match", perm.permission, equalTo(expectedType))
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_DENY)
}
})
}

Просмотреть файл

@ -100,8 +100,8 @@ public class TestRunnerActivity extends Activity {
private GeckoSession.PermissionDelegate mPermissionDelegate = new GeckoSession.PermissionDelegate() {
@Override
public void onContentPermissionRequest(@NonNull final GeckoSession session, @Nullable final String uri, final int type, @NonNull final Callback callback) {
callback.grant();
public GeckoResult<Integer> onContentPermissionRequest(@NonNull final GeckoSession session, @NonNull GeckoSession.PermissionDelegate.ContentPermission perm) {
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW);
}
@Override

Просмотреть файл

@ -25,9 +25,10 @@ class WebNotificationTest : BaseSessionTest() {
// Grant "desktop notification" permission
mainSession.delegateUntilTestEnd(object : Callbacks.PermissionDelegate {
override fun onContentPermissionRequest(session: GeckoSession, uri: String?, type: Int, callback: GeckoSession.PermissionDelegate.Callback) {
assertThat("Should grant DESKTOP_NOTIFICATIONS permission", type, equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
callback.grant()
override fun onContentPermissionRequest(session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission):
GeckoResult<Int>? {
assertThat("Should grant DESKTOP_NOTIFICATIONS permission", perm.permission, equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW)
}
})

Просмотреть файл

@ -60,9 +60,10 @@ class WebPushTest : BaseSessionTest() {
sessionRule.setPrefsUntilTestEnd(mapOf("dom.webnotifications.requireuserinteraction" to false))
// Grant "desktop notification" permission
mainSession.delegateUntilTestEnd(object : Callbacks.PermissionDelegate {
override fun onContentPermissionRequest(session: GeckoSession, uri: String?, type: Int, callback: GeckoSession.PermissionDelegate.Callback) {
assertThat("Should grant DESKTOP_NOTIFICATIONS permission", type, equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
callback.grant()
override fun onContentPermissionRequest(session: GeckoSession, perm: GeckoSession.PermissionDelegate.ContentPermission):
GeckoResult<Int>? {
assertThat("Should grant DESKTOP_NOTIFICATIONS permission", perm.permission, equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
return GeckoResult.fromValue(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW)
}
})

Просмотреть файл

@ -716,33 +716,13 @@ public class GeckoSession {
GeckoSession.this, message.getStringArray("perms"),
new PermissionCallback("android", callback));
} else if ("GeckoView:ContentPermission".equals(event)) {
final String typeString = message.getString("perm");
final int type;
if ("geolocation".equals(typeString)) {
type = PermissionDelegate.PERMISSION_GEOLOCATION;
} else if ("desktop-notification".equals(typeString)) {
type = PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION;
} else if ("persistent-storage".equals(typeString)) {
type = PermissionDelegate.PERMISSION_PERSISTENT_STORAGE;
} else if ("xr".equals(typeString)) {
type = PermissionDelegate.PERMISSION_XR;
} else if ("midi".equals(typeString)) {
// We can get this from WPT and presumably other content, but Gecko
// doesn't support Web MIDI.
callback.sendError("Unsupported");
final GeckoResult<Integer> res = delegate.onContentPermissionRequest(GeckoSession.this, new PermissionDelegate.ContentPermission(message));
if (res == null) {
callback.sendSuccess(PermissionDelegate.ContentPermission.VALUE_PROMPT);
return;
} else if ("autoplay-media-inaudible".equals(typeString)) {
type = PermissionDelegate.PERMISSION_AUTOPLAY_INAUDIBLE;
} else if ("autoplay-media-audible".equals(typeString)) {
type = PermissionDelegate.PERMISSION_AUTOPLAY_AUDIBLE;
} else if ("media-key-system-access".equals(typeString)) {
type = PermissionDelegate.PERMISSION_MEDIA_KEY_SYSTEM_ACCESS;
} else {
throw new IllegalArgumentException("Unknown permission request: " + typeString);
}
delegate.onContentPermissionRequest(
GeckoSession.this, message.getString("uri"),
type, new PermissionCallback(typeString, callback));
callback.resolveTo(res);
} else if ("GeckoView:MediaPermission".equals(event)) {
final GeckoBundle[] videoBundles = message.getBundleArray("video");
final GeckoBundle[] audioBundles = message.getBundleArray("audio");
@ -5495,6 +5475,12 @@ public class GeckoSession {
*/
final public @Value int value;
/**
* The context ID associated with the permission if any.
* @see GeckoSessionSettings.Builder#contextId
*/
final public @Nullable String contextId;
final private String mPrincipal;
protected ContentPermission() {
@ -5503,6 +5489,7 @@ public class GeckoSession {
this.permission = PERMISSION_GEOLOCATION;
this.value = VALUE_ALLOW;
this.mPrincipal = "";
this.contextId = null;
}
private ContentPermission(final @NonNull GeckoBundle bundle) {
@ -5510,10 +5497,11 @@ public class GeckoSession {
this.mPrincipal = bundle.getString("principal");
this.privateMode = bundle.getBoolean("privateMode");
final String permission = bundle.getString("type");
final String permission = bundle.getString("perm");
this.permission = convertType(permission);
this.value = bundle.getInt("value");
this.contextId = StorageController.retrieveUnsafeSessionContextId(bundle.getString("contextId"));
}
private static int convertType(final @NonNull String type) {
@ -5536,6 +5524,27 @@ public class GeckoSession {
}
}
private static String convertType(final int type) {
switch (type) {
case PERMISSION_GEOLOCATION:
return "geolocation";
case PERMISSION_DESKTOP_NOTIFICATION:
return "desktop-notification";
case PERMISSION_PERSISTENT_STORAGE:
return "persistent-storage";
case PERMISSION_XR:
return "xr";
case PERMISSION_AUTOPLAY_INAUDIBLE:
return "autoplay-media-inaudible";
case PERMISSION_AUTOPLAY_AUDIBLE:
return "autoplay-media-audible";
case PERMISSION_MEDIA_KEY_SYSTEM_ACCESS:
return "media-key-system-access";
default:
return "";
}
}
/* package */ static @NonNull ArrayList<ContentPermission> fromBundleArray(final @NonNull GeckoBundle[] bundleArray) {
final ArrayList<ContentPermission> res = new ArrayList<ContentPermission>();
if (bundleArray == null) {
@ -5551,6 +5560,17 @@ public class GeckoSession {
}
return res;
}
/* package */ @NonNull GeckoBundle toGeckoBundle() {
final GeckoBundle res = new GeckoBundle(5);
res.putString("uri", uri);
res.putString("principal", mPrincipal);
res.putBoolean("privateMode", privateMode);
res.putString("perm", convertType(permission));
res.putInt("value", value);
res.putString("contextId", contextId);
return res;
}
}
/**
@ -5599,18 +5619,14 @@ public class GeckoSession {
* from being redisplayed to the user.
*
* @param session GeckoSession instance requesting the permission.
* @param uri The URI of the content requesting the permission.
* @param type The type of the requested permission; possible values are,
* PERMISSION_GEOLOCATION
* PERMISSION_DESKTOP_NOTIFICATION
* PERMISSION_PERSISTENT_STORAGE
* PERMISSION_XR
* @param callback Callback interface.
* @param perm An {@link ContentPermission} describing the permission being requested and its current status.
*
* @return A {@link GeckoResult} resolving to one of {@link ContentPermission#VALUE_PROMPT VALUE_*}, determining
* the response to the permission request and updating the permissions for this site.
*/
@UiThread
default void onContentPermissionRequest(@NonNull final GeckoSession session, @Nullable final String uri,
@Permission final int type, @NonNull final Callback callback) {
callback.reject();
default @Nullable GeckoResult<Integer> onContentPermissionRequest(@NonNull final GeckoSession session, @NonNull ContentPermission perm) {
return GeckoResult.fromValue(ContentPermission.VALUE_PROMPT);
}
class MediaSource {

Просмотреть файл

@ -9,6 +9,7 @@ package org.mozilla.geckoview;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Locale;
@ -168,7 +169,7 @@ public final class StorageController {
"GeckoView:ClearSessionContextData", bundle);
}
/* package */ static @NonNull String createSafeSessionContextId(
/* package */ static @Nullable String createSafeSessionContextId(
final @Nullable String contextId) {
if (contextId == null) {
return null;
@ -184,6 +185,18 @@ public final class StorageController {
.toLowerCase(Locale.ROOT);
}
/* package */ static @Nullable String retrieveUnsafeSessionContextId(
final @Nullable String contextId) {
if (contextId == null || contextId.isEmpty()) {
return null;
}
if ("gvctxempty".equals(contextId)) {
return "";
}
final byte[] bytes = new BigInteger(contextId.substring(5), 16).toByteArray();
return new String(bytes, Charset.forName("UTF-8"));
}
/**
* Get all currently stored permissions.
*
@ -199,7 +212,7 @@ public final class StorageController {
}
/**
* Get all currently stored permissions for a given URI.
* Get all currently stored permissions for a given URI and default (unset) context ID.
*
* @param uri A String representing the URI to get permissions for.
*
@ -208,11 +221,39 @@ public final class StorageController {
*/
@AnyThread
public @NonNull GeckoResult<List<ContentPermission>> getPermissions(final @NonNull String uri) {
final GeckoBundle msg = new GeckoBundle(1);
return getPermissions(uri, null);
}
/**
* Get all currently stored permissions for a given URI and context ID.
*
* @param uri A String representing the URI to get permissions for.
* @param contextId A String specifying the context ID.
*
* @return A {@link GeckoResult} that will complete with a list of all
* currently stored {@link ContentPermission}s for the URI.
*/
@AnyThread
public @NonNull GeckoResult<List<ContentPermission>> getPermissions(final @NonNull String uri, final @Nullable String contextId) {
final GeckoBundle msg = new GeckoBundle(2);
msg.putString("uri", uri);
msg.putString("contextId", createSafeSessionContextId(contextId));
return EventDispatcher.getInstance().queryBundle("GeckoView:GetPermissionsByURI", msg).map(bundle -> {
final GeckoBundle[] permsArray = bundle.getBundleArray("permissions");
return ContentPermission.fromBundleArray(permsArray);
});
}
/**
* Set a new value for an existing permission.
*
* @param perm A {@link ContentPermission} that you wish to update the value of.
* @param value The new value for the permission.
*/
@AnyThread
public void setPermission(final @NonNull ContentPermission perm, final @ContentPermission.Value int value) {
final GeckoBundle msg = perm.toGeckoBundle();
msg.putInt("newValue", value);
EventDispatcher.getInstance().dispatch("GeckoView:SetPermission", msg);
}
}

Просмотреть файл

@ -869,30 +869,32 @@ final class BasicGeckoViewPrompt implements GeckoSession.PromptDelegate {
}
}
public void onPermissionPrompt(final GeckoSession session, final String title,
final GeckoSession.PermissionDelegate.Callback callback) {
public GeckoResult<Integer> onPermissionPrompt(final GeckoSession session, final String title,
final GeckoSession.PermissionDelegate.ContentPermission perm) {
final Activity activity = mActivity;
final GeckoResult<Integer> res = new GeckoResult<>();
if (activity == null) {
callback.reject();
return;
res.complete(GeckoSession.PermissionDelegate.ContentPermission.VALUE_PROMPT);
return res;
}
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(title)
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int which) {
callback.reject();
res.complete(GeckoSession.PermissionDelegate.ContentPermission.VALUE_DENY);
}
})
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int which) {
callback.grant();
res.complete(GeckoSession.PermissionDelegate.ContentPermission.VALUE_ALLOW);
}
});
final AlertDialog dialog = builder.create();
dialog.show();
return res;
}
public void onSlowScriptPrompt(GeckoSession geckoSession, String title, GeckoResult<SlowScriptResponse> reportAction) {

Просмотреть файл

@ -1779,51 +1779,39 @@ public class GeckoViewActivity
}
@Override
public void onContentPermissionRequest(final GeckoSession session, final String uri,
final int type, final Callback callback) {
public GeckoResult<Integer> onContentPermissionRequest(final GeckoSession session, final ContentPermission perm) {
final int resId;
Callback contentPermissionCallback = callback;
if (PERMISSION_GEOLOCATION == type) {
resId = R.string.request_geolocation;
} else if (PERMISSION_DESKTOP_NOTIFICATION == type) {
if (mShowNotificationsRejected) {
Log.w(LOGTAG, "Desktop notifications already denied by user.");
callback.reject();
return;
}
resId = R.string.request_notification;
contentPermissionCallback = new ExampleNotificationCallback(callback);
} else if (PERMISSION_PERSISTENT_STORAGE == type) {
if (mAcceptedPersistentStorage.contains(uri)) {
Log.w(LOGTAG, "Persistent Storage for " + uri + " already granted by user.");
callback.grant();
return;
}
resId = R.string.request_storage;
contentPermissionCallback = new ExamplePersistentStorageCallback(callback, uri);
} else if (PERMISSION_XR == type) {
resId = R.string.request_xr;
} else if (PERMISSION_AUTOPLAY_AUDIBLE == type || PERMISSION_AUTOPLAY_INAUDIBLE == type) {
if (!mAllowAutoplay.value()) {
Log.d(LOGTAG, "Rejecting autoplay request");
callback.reject();
} else {
Log.d(LOGTAG, "Granting autoplay request");
callback.grant();
}
return;
} else if (PERMISSION_MEDIA_KEY_SYSTEM_ACCESS == type) {
resId = R.string.request_media_key_system_access;
} else {
Log.w(LOGTAG, "Unknown permission: " + type);
callback.reject();
return;
switch (perm.permission) {
case PERMISSION_GEOLOCATION:
resId = R.string.request_geolocation;
break;
case PERMISSION_DESKTOP_NOTIFICATION:
resId = R.string.request_notification;
break;
case PERMISSION_PERSISTENT_STORAGE:
resId = R.string.request_storage;
break;
case PERMISSION_XR:
resId = R.string.request_xr;
break;
case PERMISSION_AUTOPLAY_AUDIBLE:
case PERMISSION_AUTOPLAY_INAUDIBLE:
if (!mAllowAutoplay.value()) {
return GeckoResult.fromValue(ContentPermission.VALUE_DENY);
} else {
return GeckoResult.fromValue(ContentPermission.VALUE_ALLOW);
}
case PERMISSION_MEDIA_KEY_SYSTEM_ACCESS:
resId = R.string.request_media_key_system_access;
break;
default:
return GeckoResult.fromValue(ContentPermission.VALUE_DENY);
}
final String title = getString(resId, Uri.parse(uri).getAuthority());
final String title = getString(resId, Uri.parse(perm.uri).getAuthority());
final BasicGeckoViewPrompt prompt = (BasicGeckoViewPrompt)
mTabSessionManager.getCurrentSession().getPromptDelegate();
prompt.onPermissionPrompt(session, title, contentPermissionCallback);
return prompt.onPermissionPrompt(session, title, perm);
}
private String[] normalizeMediaName(final MediaSource[] sources) {

Просмотреть файл

@ -567,8 +567,9 @@ class GeckoViewNavigation extends GeckoViewModule {
return {
uri: Services.io.createExposableURI(p.principal.URI).displaySpec,
principal: E10SUtils.serializePrincipal(p.principal),
type: p.type,
perm: p.type,
value: p.capability,
contextId: p.principal.originAttributes.geckoViewSessionContextId,
privateMode: p.principal.privateBrowsingId != 0,
};
});

Просмотреть файл

@ -115,8 +115,9 @@ const GeckoViewStorageController = {
return {
uri: Services.io.createExposableURI(p.principal.URI).displaySpec,
principal: E10SUtils.serializePrincipal(p.principal),
type: p.type,
perm: p.type,
value: p.capability,
contextId: p.principal.originAttributes.geckoViewSessionContextId,
privateMode: p.principal.privateBrowsingId != 0,
};
});
@ -125,23 +126,34 @@ const GeckoViewStorageController = {
}
case "GeckoView:GetPermissionsByURI": {
const uri = Services.io.newURI(aData.uri);
const prin = Services.scriptSecurityManager.createContentPrincipal(
const principal = Services.scriptSecurityManager.createContentPrincipal(
uri,
{}
aData.contextId ? { geckoViewSessionContextId: aData.contextId } : {}
);
const rawPerms = Services.perms.getAllForPrincipal(prin);
const rawPerms = Services.perms.getAllForPrincipal(principal);
const permissions = rawPerms.map(p => {
return {
uri: Services.io.createExposableURI(p.principal.URI).displaySpec,
principal: E10SUtils.serializePrincipal(p.principal),
type: p.type,
perm: p.type,
value: p.capability,
contextId: p.principal.originAttributes.geckoViewSessionContextId,
privateMode: p.principal.privateBrowsingId != 0,
};
});
aCallback.onSuccess({ permissions });
break;
}
case "GeckoView:SetPermission": {
const principal = E10SUtils.deserializePrincipal(aData.principal);
Services.perms.addFromPrincipal(
principal,
aData.perm,
aData.newValue,
Ci.nsIPermissionManager.EXPIRE_NEVER
);
break;
}
}
},