Bug 1788720 - Expose private browsing flag in StorageController.getPermissions r=geckoview-reviewers,jonalmeida

Differential Revision: https://phabricator.services.mozilla.com/D160424
This commit is contained in:
Arturo Mejia 2022-11-02 13:20:13 +00:00
parent 22b049303e
commit 3307fe95de
8 changed files with 122 additions and 18 deletions

View File

@ -1904,7 +1904,8 @@ package org.mozilla.geckoview {
method @AnyThread @NonNull public GeckoResult<Void> clearDataFromHost(@NonNull String, long);
method @AnyThread @NonNull public GeckoResult<List<GeckoSession.PermissionDelegate.ContentPermission>> getAllPermissions();
method @AnyThread @NonNull public GeckoResult<List<GeckoSession.PermissionDelegate.ContentPermission>> getPermissions(@NonNull String);
method @AnyThread @NonNull public GeckoResult<List<GeckoSession.PermissionDelegate.ContentPermission>> getPermissions(@NonNull String, @Nullable String);
method @AnyThread @NonNull public GeckoResult<List<GeckoSession.PermissionDelegate.ContentPermission>> getPermissions(@NonNull String, boolean);
method @AnyThread @NonNull public GeckoResult<List<GeckoSession.PermissionDelegate.ContentPermission>> getPermissions(@NonNull String, @Nullable String, boolean);
method @AnyThread public void setPermission(@NonNull GeckoSession.PermissionDelegate.ContentPermission, int);
method @AnyThread public void setPrivateBrowsingPermanentPermission(@NonNull GeckoSession.PermissionDelegate.ContentPermission, int);
}
@ -2297,6 +2298,7 @@ package org.mozilla.geckoview {
field public static final Parcelable.Creator<WebNotification> CREATOR;
field @Nullable public final String imageUrl;
field @Nullable public final String lang;
field public final boolean privateBrowsing;
field @NonNull public final boolean requireInteraction;
field public final boolean silent;
field @Nullable public final String source;

View File

@ -20,22 +20,18 @@ import org.mozilla.geckoview.test.TrackingPermissionService.TrackingPermissionIn
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.Criteria
import android.location.Location
import android.location.LocationManager
import android.os.Build
import android.os.SystemClock
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.filters.MediumTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.platform.app.InstrumentationRegistry
import org.hamcrest.Matchers.*
import org.json.JSONArray
import org.junit.Assert.fail
import org.junit.Assume.assumeThat
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Ignore
import org.mozilla.geckoview.GeckoSessionSettings
@RunWith(AndroidJUnit4::class)
@ -579,7 +575,7 @@ class PermissionDelegateTest : BaseSessionTest() {
assertThat("Permission should be granted",
result as String, equalTo("granted"))
val perms = sessionRule.waitForResult(storageController.getPermissions(url))
val perms = sessionRule.waitForResult(storageController.getPermissions(url, false))
assertThat("Permissions should not be null", perms, notNullValue())
var permFound = false
@ -635,7 +631,7 @@ class PermissionDelegateTest : BaseSessionTest() {
assertThat("Permission should be granted",
result2 as String, equalTo("granted"))
val perms2 = sessionRule.waitForResult(storageController.getPermissions(url))
val perms2 = sessionRule.waitForResult(storageController.getPermissions(url, false))
assertThat("Permissions should not be null", perms, notNullValue())
permFound = false

View File

@ -78,6 +78,12 @@ class WebNotificationTest : BaseSessionTest() {
assertThat("Source should match", notification.source, equalTo(createTestUrl(HELLO_HTML_PATH)))
}
@GeckoSessionTestRule.Setting.List(
GeckoSessionTestRule.Setting(
key = GeckoSessionTestRule.Setting.Key.USE_PRIVATE_MODE,
value = "true"
)
)
@Test fun onShowNotification() {
sessionRule.setPrefsUntilTestEnd(mapOf("dom.webnotifications.vibrate.enabled" to true))
val notificationResult = GeckoResult<Void>()
@ -88,6 +94,7 @@ class WebNotificationTest : BaseSessionTest() {
@GeckoSessionTestRule.AssertCalled
override fun onShowNotification(notification: WebNotification) {
assertNotificationData(notification, requireInteraction)
assertThat("privateBrowsing should match", notification.privateBrowsing, equalTo(true))
notificationResult.complete(null)
}
})
@ -152,6 +159,7 @@ class WebNotificationTest : BaseSessionTest() {
val notification = sessionRule.waitForResult(notificationResult)
assertNotificationData(notification, requireInteraction)
assertThat("privateBrowsing should match", notification.privateBrowsing, equalTo(false))
// Test that we can click from a deserialized notification
val parcel = Parcel.obtain()
@ -160,6 +168,61 @@ class WebNotificationTest : BaseSessionTest() {
val deserialized = WebNotification.CREATOR.createFromParcel(parcel)
assertNotificationData(deserialized, requireInteraction)
assertThat("privateBrowsing should match", deserialized.privateBrowsing, equalTo(false))
deserialized!!.click()
assertThat("Promise should have been resolved.", promiseResult.value as Double, equalTo(1.0))
}
@GeckoSessionTestRule.Setting.List(
GeckoSessionTestRule.Setting(
key = GeckoSessionTestRule.Setting.Key.USE_PRIVATE_MODE,
value = "true"
)
)
@Test fun clickPrivateNotificationParceled() {
sessionRule.setPrefsUntilTestEnd(mapOf("dom.webnotifications.vibrate.enabled" to true))
val notificationResult = GeckoResult<WebNotification>()
val requireInteraction =
sessionRule.getPrefs("dom.webnotifications.requireinteraction.enabled")[0] as Boolean
sessionRule.delegateDuringNextWait(object : WebNotificationDelegate {
@GeckoSessionTestRule.AssertCalled
override fun onShowNotification(notification: WebNotification) {
notificationResult.complete(notification)
}
})
val promiseResult = mainSession.evaluatePromiseJS("""
new Promise(resolve => {
const notification = new Notification('The Title', {
body: 'The Text',
cookie: 'Cookie',
icon: 'icon.png',
tag: 'Tag',
dir: 'ltr',
lang: 'en-US',
requireInteraction: true,
vibrate: [1,2,3,4]
});
notification.onclick = function() {
resolve(1);
}
});
""".trimIndent())
val notification = sessionRule.waitForResult(notificationResult)
assertNotificationData(notification, requireInteraction)
assertThat("privateBrowsing should match", notification.privateBrowsing, equalTo(true))
// Test that we can click from a deserialized notification
val parcel = Parcel.obtain()
notification.writeToParcel(parcel, 0)
parcel.setDataPosition(0);
val deserialized = WebNotification.CREATOR.createFromParcel(parcel)
assertNotificationData(deserialized, requireInteraction)
assertThat("privateBrowsing should match", deserialized.privateBrowsing, equalTo(true))
deserialized!!.click()
assertThat("Promise should have been resolved.", promiseResult.value as Double, equalTo(1.0))

View File

@ -204,7 +204,9 @@ public final class StorageController {
}
/**
* Get all currently stored permissions for a given URI and default (unset) context ID.
* Get all currently stored permissions for a given URI and default (unset) context ID, in normal
* mode This API will be deprecated in the future
* https://bugzilla.mozilla.org/show_bug.cgi?id=1797379
*
* @param uri A String representing the URI to get permissions for.
* @return A {@link GeckoResult} that will complete with a list of all currently stored {@link
@ -212,7 +214,22 @@ public final class StorageController {
*/
@AnyThread
public @NonNull GeckoResult<List<ContentPermission>> getPermissions(final @NonNull String uri) {
return getPermissions(uri, null);
return getPermissions(uri, null, false);
}
/**
* 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.
* @param privateMode indicate where the {@link ContentPermission}s should be in private or normal
* mode.
* @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 boolean privateMode) {
return getPermissions(uri, null, privateMode);
}
/**
@ -220,15 +237,19 @@ public final class StorageController {
*
* @param uri A String representing the URI to get permissions for.
* @param contextId A String specifying the context ID.
* @param privateMode indicate where the {@link ContentPermission}s should be in private or normal
* mode
* @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 @NonNull String uri, final @Nullable String contextId, final boolean privateMode) {
final GeckoBundle msg = new GeckoBundle(2);
final int privateBrowsingId = (privateMode) ? 1 : 0;
msg.putString("uri", uri);
msg.putString("contextId", createSafeSessionContextId(contextId));
msg.putInt("privateBrowsingId", privateBrowsingId);
return EventDispatcher.getInstance()
.queryBundle("GeckoView:GetPermissionsByURI", msg)
.map(

View File

@ -103,6 +103,9 @@ public class WebNotification implements Parcelable {
*/
public final boolean silent;
/** indicates whether the notification came from private browsing mode or not. */
public final boolean privateBrowsing;
/**
* A vibration pattern to run with the display of the notification. A vibration pattern can be an
* array with as few as one member. The values are times in milliseconds where the even indices
@ -126,6 +129,7 @@ public class WebNotification implements Parcelable {
@NonNull final boolean requireInteraction,
@NonNull final String source,
final boolean silent,
final boolean privateBrowsing,
@NonNull final int[] vibrate) {
this.tag = tag;
this.mCookie = cookie;
@ -138,6 +142,7 @@ public class WebNotification implements Parcelable {
this.source = "".equals(source) ? null : source;
this.silent = silent;
this.vibrate = vibrate;
this.privateBrowsing = privateBrowsing;
}
/**
@ -189,6 +194,7 @@ public class WebNotification implements Parcelable {
dest.writeInt(requireInteraction ? 1 : 0);
dest.writeString(source);
dest.writeInt(silent ? 1 : 0);
dest.writeInt(privateBrowsing ? 1 : 0);
dest.writeIntArray(vibrate);
}
@ -203,6 +209,7 @@ public class WebNotification implements Parcelable {
requireInteraction = in.readInt() == 1;
source = in.readString();
silent = in.readInt() == 1;
privateBrowsing = in.readInt() == 1;
vibrate = in.createIntArray();
}

View File

@ -1257,4 +1257,4 @@ to allow adding gecko profiler markers.
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport(android.content.Context,android.os.Bundle,java.lang.String)
[65.25]: {{javadoc_uri}}/GeckoResult.html
[api-version]: 0996b9058eab189d80b636b07d61bdb7db45c367
[api-version]: 5d853b0411014ac0c6d1059a5d69e69913f8c4c9

View File

@ -133,7 +133,12 @@ const GeckoViewStorageController = {
const uri = Services.io.newURI(aData.uri);
const principal = Services.scriptSecurityManager.createContentPrincipal(
uri,
aData.contextId ? { geckoViewSessionContextId: aData.contextId } : {}
aData.contextId
? {
geckoViewSessionContextId: aData.contextId,
privateBrowsingId: aData.privateBrowsingId,
}
: { privateBrowsingId: aData.privateBrowsingId }
);
const rawPerms = Services.perms.getAllForPrincipal(principal);
const permissions = rawPerms.map(p => {
@ -162,17 +167,23 @@ const GeckoViewStorageController = {
aData.newValue
);
} else {
const expirePolicy = aData.privateMode
? Ci.nsIPermissionManager.EXPIRE_SESSION
: Ci.nsIPermissionManager.EXPIRE_NEVER;
Services.perms.addFromPrincipal(
principal,
key,
aData.newValue,
Ci.nsIPermissionManager.EXPIRE_NEVER
expirePolicy
);
}
break;
}
case "GeckoView:SetPermissionByURI": {
const uri = Services.io.newURI(aData.uri);
const expirePolicy = aData.privateId
? Ci.nsIPermissionManager.EXPIRE_SESSION
: Ci.nsIPermissionManager.EXPIRE_NEVER;
const principal = Services.scriptSecurityManager.createContentPrincipal(
uri,
{
@ -184,7 +195,7 @@ const GeckoViewStorageController = {
principal,
aData.perm,
aData.newValue,
Ci.nsIPermissionManager.EXPIRE_NEVER
expirePolicy
);
break;
}

View File

@ -91,6 +91,10 @@ AndroidAlerts::ShowPersistentNotification(const nsAString& aPersistentData,
rv = aAlert->GetSilent(&silent);
NS_ENSURE_SUCCESS(rv, NS_OK);
bool privateBrowsing;
rv = aAlert->GetInPrivateBrowsing(&privateBrowsing);
NS_ENSURE_SUCCESS(rv, NS_OK);
nsTArray<uint32_t> vibrate;
rv = aAlert->GetVibrate(vibrate);
NS_ENSURE_SUCCESS(rv, NS_OK);
@ -105,7 +109,7 @@ AndroidAlerts::ShowPersistentNotification(const nsAString& aPersistentData,
java::WebNotification::LocalRef notification = notification->New(
title, name, cookie, text, imageUrl, dir, lang, requireInteraction, spec,
silent, jni::IntArray::From(vibrate));
silent, privateBrowsing, jni::IntArray::From(vibrate));
java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance();
if (runtime != NULL) {
runtime->NotifyOnShow(notification);