Daddoon / BlazorMobile

Create full C# driven hybrid-apps for iOS, Android, UWP & Desktop with Blazor!
MIT License
413 stars 55 forks source link

Option to use GeckoView PermissionDelegate #145

Open soend opened 5 years ago

soend commented 5 years ago

Add option to use PermissionDelegate to request users permission. For example if my blazor app wants to use geolocation the user has to allow that. More info about it here: Working with Site Permissions

Daddoon commented 5 years ago

Hi @soend .

There is no "generic" way to do that in BlazorMobile, i mean for all platform simultaneously, as it's very specific to the webview implementation,

However you can do this in two way:

The last one doesn't require to override anything at Browser level, and it may be more convenient if you find a Xamarin.Forms API that can do geolocation management directly, or any other compatible NuGet package.

If you really want to implement this directly at the WebView level on Android you must:

Then like i said by mail to someone recently:

BlazorMobile don’t use the PromptDelegate functionality at the moment, maybe this is something I have missed, but I never required to override the default behavior on this. There is no default inheritable class from BlazorMobile for PromptDelegate, but the interface is available through PromptDelegateClass, the name seem idiot, but it was because there was name collisions when creating C# bindings for GeckoView.

So on your side, the only things you have to do:

It must then work.

soend commented 5 years ago

Thanks again for a quick response. Your answere clears up some of it and gives me possible ways to continue. Since the goal is a hybrid-app then creating custom implementations for different platforms sounds not so great option. That leaves me to use Xamarin.Forms what i am totally ok with. Keep up the good work. :)

Daddoon commented 5 years ago

Thanks !

Forgot to specify that the override i mention is for the OnNewSession virtual method on the renderer. Take a look at the source code of the BlazorWebViewRenderer, on the OnNewSession, you should see multiple delegate override, as an exemple.

soend commented 5 years ago

Quick question about this topic, when creating solution with using BlazorMobile.Templates then in which project should i create my custom renderer in to be able to inherit from BlazorWebViewRenderer?

Daddoon commented 5 years ago

From memory, you should:

Then do what you want with the renderer! You will may have to instanciate your Webview by yourself instead of creating it by the helper returning the IBlazorWebView.

However, if you see that something is missing if not going through the Blazor Webview instanciator helper, tell me, that will mean that we must add a mecanism to forward the custom implementation when needed to the plugin.

soend commented 5 years ago

Thanks for the help. This is my first time using custom renderers in xamarin. The key to get it working was adding the ExportRenderer attribute to my custom renderers classes namespace. Just for information if anybody ever is reading this then it works by adding these 2 classes to android project:

[assembly: ExportRenderer(typeof(BlazorGeckoView), typeof(ExtendedBlazorGeckoViewRenderer))]
namespace MyProject.Droid.Renderer
{
    public class ExtendedBlazorGeckoViewRenderer : BlazorGeckoViewRenderer
    {
        public override Tuple<GeckoSession, GeckoRuntime> CreateNewSession(bool needSessionOpening, string uri)
        {
             var newSessionTuple = base.CreateNewSession(needSessionOpening, uri);
            newSessionTuple.Item1.PermissionDelegate = new BlazorPermissionDelegate(this);

            return newSessionTuple;
        }
    }
}
public class BlazorPermissionDelegate : Java.Lang.Object, GeckoSession.PermissionDelegateClass, IJavaObject, IDisposable
{
    public BlazorPermissionDelegate(GeckoViewRenderer renderer) : base()
    {
    }

    public async void OnAndroidPermissionsRequest(GeckoSession session, string[] permissions, GeckoSession.PermissionDelegateClassCallback callback)
    {
        // ToDo
    }

    public void OnContentPermissionRequest(GeckoSession session, string uri, int type, GeckoSession.PermissionDelegateClassCallback callback)
    {
        // ToDo
    }

    public void OnMediaPermissionRequest(GeckoSession session, string uri, GeckoSession.ermissionDelegateClassMediaSource[] video, GeckoSession.ermissionDelegateClassMediaSource[] audio, GeckoSession.PermissionDelegateClassMediaCallback callback)
    {
        // ToDo
    }
}

For example now when website is requesting to use browsers Geolocation then first the OnContentPermissionRequest is called and after that to get androids permissions OnAndroidPermissionsRequest. More info from the link in first post.

Daddoon commented 4 years ago

Congratulation ! Good to know you found how to finish ! And yes, when i was talking about "listening to your class" it was about the ExportRenderer attribute.

soend commented 4 years ago

Has there been any changes in the BlazorMobile side what could stop this from working?

Daddoon commented 4 years ago

Are you talking about GeckoView ? Or are you posting in the wrong thread ?

soend commented 4 years ago

Are you talking about GeckoView ? Or are you posting in the wrong thread ?

Talking about GeckoView and renderer used to get permission delegate to work.

Why i am asking is because after updating it seems like my custom permission handler never gets called by geckoview.

Daddoon commented 4 years ago

There is indeed some changes, as BlazorMobile is now implementing a specific PromptDelegate for managing access for file input and else.

See the actual code here: https://github.com/Daddoon/BlazorMobile/blob/master/src/BlazorMobile.Android/Renderer/BlazorGeckoViewRenderer.cs

There is now this line:

 _session.PromptDelegate = new BlazorGeckoViewPromptDelegate(this);

I think the best way to resolve your issue is to:

soend commented 4 years ago

There is indeed some changes, as BlazorMobile is now implementing a specific PromptDelegate for managing access for file input and else.

See the actual code here: https://github.com/Daddoon/BlazorMobile/blob/master/src/BlazorMobile.Android/Renderer/BlazorGeckoViewRenderer.cs

There is now this line:

 _session.PromptDelegate = new BlazorGeckoViewPromptDelegate(this);

I think the best way to resolve your issue is to:

  • Inherit your current class from BlazorGeckoViewPromptDelegate instead
  • Manage to make your own override in CreateNewSession if it's not already the case, without forgetting to call the base implementation, in your renderer.

I think i missing something, how does this affect PermissionDelegate? This looks just like implementation to handle PromptDelegate. I would assume the implementation i showd here should still work https://github.com/Daddoon/BlazorMobile/issues/145#issuecomment-555735684?

Daddoon commented 4 years ago

Sorry, i missread your text !

You are right, i didn't implement a permission delegate.

I know some dynamic permission may be asked while using FileUpload feature, but i'm not relying on a override of the PermissionDelegate, as i don't use it.

But actually...What is not working anymore on your app with Permission delegate ?

Daddoon commented 4 years ago

Hi @soend , did you manage to fix your issue ?

soend commented 4 years ago

Hi @soend , did you manage to fix your issue ?

No, for some reason the PermissionDelegate is just not called by geckoview.

(Im really thinking of just going with pure blazor PWA now since having too many issues)

Daddoon commented 4 years ago

I don't think there is any changes on that part of the code, but i may be wrong. If you have a repro project i can test, feel free to send it.

PWA may be totally fine for your project. BlazorMobile goal is mainly: