blob: 93b7d86455cd1452231fd76a50cb893bfbb11c5b [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview.permission;
import android.net.Uri;
import org.chromium.android_webview.CleanupReference;
import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
/**
* This class wraps permission request in Chromium side, and can only be created
* by native side.
*/
@JNINamespace("android_webview")
public class AwPermissionRequest {
private final Uri mOrigin;
private final long mResources;
private boolean mProcessed;
// AwPermissionRequest native instance.
private long mNativeAwPermissionRequest;
// Responsible for deleting native peer.
private CleanupReference mCleanupReference;
// This should be same as corresponding definition in PermissionRequest.
// We duplicate definition because it is used in Android L and afterwards, but is only
// defined in M.
// TODO(michaelbai) : Replace "android.webkit.resoruce.MIDI_SYSEX" with
// PermissionRequest.RESOURCE_MIDI_SYSEX once Android M SDK is used.
public static final String RESOURCE_MIDI_SYSEX = "android.webkit.resource.MIDI_SYSEX";
private static final class DestroyRunnable implements Runnable {
private final long mNativeAwPermissionRequest;
private DestroyRunnable(long nativeAwPermissionRequest) {
mNativeAwPermissionRequest = nativeAwPermissionRequest;
}
@Override
public void run() {
nativeDestroy(mNativeAwPermissionRequest);
}
}
@CalledByNative
private static AwPermissionRequest create(long nativeAwPermissionRequest, String url,
long resources) {
if (nativeAwPermissionRequest == 0) return null;
Uri origin = Uri.parse(url);
return new AwPermissionRequest(nativeAwPermissionRequest, origin, resources);
}
private AwPermissionRequest(long nativeAwPermissionRequest, Uri origin,
long resources) {
mNativeAwPermissionRequest = nativeAwPermissionRequest;
mOrigin = origin;
mResources = resources;
mCleanupReference =
new CleanupReference(this, new DestroyRunnable(mNativeAwPermissionRequest));
}
public Uri getOrigin() {
return mOrigin;
}
public long getResources() {
return mResources;
}
public void grant() {
validate();
if (mNativeAwPermissionRequest != 0) {
nativeOnAccept(mNativeAwPermissionRequest, true);
destroyNative();
}
mProcessed = true;
}
public void deny() {
validate();
if (mNativeAwPermissionRequest != 0) {
nativeOnAccept(mNativeAwPermissionRequest, false);
destroyNative();
}
mProcessed = true;
}
@CalledByNative
private void destroyNative() {
mCleanupReference.cleanupNow();
mCleanupReference = null;
mNativeAwPermissionRequest = 0;
}
private void validate() {
if (!ThreadUtils.runningOnUiThread())
throw new IllegalStateException(
"Either grant() or deny() should be called on UI thread");
if (mProcessed)
throw new IllegalStateException("Either grant() or deny() has been already called.");
}
private native void nativeOnAccept(long nativeAwPermissionRequest, boolean allowed);
private static native void nativeDestroy(long nativeAwPermissionRequest);
}