hyperledger-archives / aries-framework-dotnet

Aries Framework .NET for building multiplatform SSI services
https://wiki.hyperledger.org/display/aries
Apache License 2.0
84 stars 74 forks source link

IOException on Provisioning New Agent #93

Closed james-cohen closed 4 years ago

james-cohen commented 4 years ago

I'm trying to run the Xamarin Forms sample on my Samsung Galaxy S10 (Android 10.0 Q - Android API 29) and it builds fine but I repeatedly get the same issue whenever I press 'Provision New Agent':

04-16 15:06:37.268 D/Mono    ( 8407): DllImport attempting to load: 'indy'.
04-16 15:06:37.269 D/Mono    ( 8407): DllImport error loading library '/storage/emulated/0/Android/data/com.companyname.indytest/files/.__override__/indy': 'dlopen failed: library "libvpsextension.so" not found'.
04-16 15:06:37.270 D/Mono    ( 8407): DllImport error loading library '/storage/emulated/0/Android/data/com.companyname.indytest/files/.__override__/libindy.so': '(null)'.
04-16 15:06:37.271 D/Mono    ( 8407): DllImport error loading library '/storage/emulated/0/Android/data/com.companyname.indytest/files/.__override__/libindy.so': '(null)'.
04-16 15:06:37.271 D/Mono    ( 8407): DllImport error loading library '/system/lib64/indy': '(null)'.
04-16 15:06:37.271 D/Mono    ( 8407): DllImport error loading library '/system/lib64/libindy.so': '(null)'.
04-16 15:06:37.271 D/Mono    ( 8407): DllImport error loading library '/system/lib64/libindy.so': '(null)'.
04-16 15:06:37.272 D/Mono    ( 8407): DllImport error loading library 'indy': 'dlopen failed: library "indy" not found'.
04-16 15:06:37.272 D/Mono    ( 8407): DllImport loaded library 'libindy.so'.
04-16 15:06:37.272 D/Mono    ( 8407): DllImport searching in: 'indy' ('libindy.so').
04-16 15:06:37.272 D/Mono    ( 8407): Searching for 'indy_create_wallet'.
04-16 15:06:37.272 D/Mono    ( 8407): Probing 'indy_create_wallet'.
04-16 15:06:37.272 D/Mono    ( 8407): Found as 'indy_create_wallet'.
[HotReload] (2020-04-16 15:06:34.2): INFO: (IndyTest.Android) HotReload: Initialized Agent.
[HotReload] (2020-04-16 15:06:19.2): INFO: XAML Hot Reload Connected and Ready.
Thread started:  #7
**Hyperledger.Indy.IOException:** 'An IO error occurred.'

04-16 15:06:47.721 D/Mono    ( 8407): DllImport attempting to load: '/system/lib64/liblog.so'.
04-16 15:06:47.722 D/Mono    ( 8407): DllImport loaded library '/system/lib64/liblog.so'.
04-16 15:06:47.722 D/Mono    ( 8407): DllImport searching in: '/system/lib64/liblog.so' ('/system/lib64/liblog.so').
04-16 15:06:47.722 D/Mono    ( 8407): Searching for '__android_log_print'.
04-16 15:06:47.722 D/Mono    ( 8407): Probing '__android_log_print'.
04-16 15:06:47.722 D/Mono    ( 8407): Found as '__android_log_print'.
04-16 15:06:47.723 I/MonoDroid( 8407): UNHANDLED EXCEPTION:
04-16 15:06:47.724 I/MonoDroid( 8407): Hyperledger.Indy.IOException: An IO error occurred.
04-16 15:06:47.724 I/MonoDroid( 8407):   at Hyperledger.Aries.Storage.DefaultWalletService.CreateWalletAsync (Hyperledger.Aries.Storage.WalletConfiguration configuration, Hyperledger.Aries.Storage.WalletCredentials credentials) [0x0002b] in D:\a\1\s\src\Hyperledger.Aries\Storage\DefaultWalletService.cs:53 
04-16 15:06:47.724 I/MonoDroid( 8407):   at Hyperledger.Aries.Configuration.DefaultProvisioningService.ProvisionAgentAsync (Hyperledger.Aries.Configuration.AgentOptions agentOptions) [0x0006b] in D:\a\1\s\src\Hyperledger.Aries\Configuration\DefaultProvisioningService.cs:103 
04-16 15:06:47.724 I/MonoDroid( 8407):   at IndyTest.MainPage.OnProvision (System.Object sender, System.EventArgs e) [0x000a8] in C:\Users\wex165\source\repos\IndyTest\IndyTest\MainPage.xaml.cs:47 
04-16 15:06:47.724 I/MonoDroid( 8407):   at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021 
04-16 15:06:47.724 I/MonoDroid( 8407):   at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <4ccdb3137d974856b786e1aeebbfbab6>:0 
04-16 15:06:47.724 I/MonoDroid( 8407):   at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <4ccdb3137d974856b786e1aeebbfbab6>:0 
04-16 15:06:47.724 I/MonoDroid( 8407):   at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] in <4ccdb3137d974856b786e1aeebbfbab6>:0 
04-16 15:06:47.724 I/MonoDroid( 8407):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.50(intptr,intptr)
04-16 15:06:47.728 W/nyname.indytes( 8407): JNI RegisterNativeMethods: attempt to register 0 native methods for android.runtime.JavaProxyThrowable
04-16 15:06:47.729 D/Mono    ( 8407): DllImport searching in: '__Internal' ('(null)').
04-16 15:06:47.729 D/Mono    ( 8407): Searching for 'java_interop_jnienv_throw'.
04-16 15:06:47.729 D/Mono    ( 8407): Probing 'java_interop_jnienv_throw'.
04-16 15:06:47.729 D/Mono    ( 8407): Found as 'java_interop_jnienv_throw'.
**Hyperledger.Indy.IOException:** 'An IO error occurred.'

I have copied the code pretty much word for word (apart from the namespaces) and have installed libindy as per the instructions. The only thing I have changed is the EndpointURI in the AgentOptions setup to direct to the endpoint of the Dockerized .Net Agent demo running on my PC:

        async void OnProvision(object sender, EventArgs e)
        {
            IsBusy = true;

            try
            {
                var configuration = new AgentOptions
                {
                    WalletCredentials = _creds,
                    WalletConfiguration = _config,
                    EndpointUri = "http://10.0.0.11:7000",
                };

                await _provisioningService.ProvisionAgentAsync(configuration);

However, the issue is replicated regardless of what URI is inserted.

This is using the most up to date versions of all required NuGet packages in Visual Studio 2019 on Windows 10.

tmarkovski commented 4 years ago

@james-cohen There's a nuanced step in Android that needs to happen before you can provision wallet. You need to grant External Storage write permissions on the android app. Here's how OSMA has it done.

https://github.com/hyperledger/aries-mobileagent-xamarin/blob/8d32309d98d1466e27ec967d6bc151d5db028115/src/Osma.Mobile.App.Android/MainActivity.cs#L55

Alternatively, you can try modifying where default wallet path is stored

new WalletConfiguration.WalletStorageConfiguration
                                {
                                    Path = Path.Combine(
                                        path1: FileSystem.AppDataDirectory,
                                        path2: ".indy_client",
                                        path3: "wallets")
                                }
james-cohen commented 4 years ago

@tmarkovski That works now! Thank you.

Before this I was using the following code included in my Android MainActivity.cs as per the Indy Xamarin setup instructions:

    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            JavaSystem.LoadLibrary("c++_shared");
            JavaSystem.LoadLibrary("indy");

            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());

            if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
            {
                RequestPermissions(new[] { Manifest.Permission.ReadExternalStorage }, 10);
                RequestPermissions(new[] { Manifest.Permission.WriteExternalStorage }, 10);
                RequestPermissions(new[] { Manifest.Permission.Internet }, 10);
            }
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

This still gives me a popup to grant permission to Data Storage upon first opening the app but then didn't work. Should it be updated to the method you just provided?

tmarkovski commented 4 years ago

Yes, that documentation is somewhat outdated