Skip to content

Commit

Permalink
[JavaCallableWrappers] move MonoRuntimeProvider to xamarin-android (#422
Browse files Browse the repository at this point in the history
)

Context: dotnet/android#2853

Currently, there are two Java source files included as
`@(EmbeddedResource)` files:

  * `MonoRuntimeProvider.Bundled.java`
  * `MonoRuntimeProvider.Shared.java`

One such usage is for `Android.App.Instrumentation` subclasses, which
look for a section of code such as:

	// Mono Runtime Initialization {{{
	mono.MonoPackageManager.LoadApplication (context, context.getApplicationInfo (), new String[]{context.getApplicationInfo ().sourceDir});
	// }}}

It places everything in-between these comments into the Java stub's
`onCreate()` method.

These Java source files should live in xamarin/xamarin-android, and
the desired source code passed in via a new
`JavaCallableWrapperGenerator.MonoRuntimeInitialization` property.

Then Xamarin.Android can make an informed decision about what code
needs to get passed in:

  * Is the shared runtime used?
  * Is it a specific API level?
  * Could we call into some pre-compiled code instead?

I added various test changes to make sure things are working:

  * Added an `ExampleActivity` and `ExampleInstrumentation` to the
    `SupportDeclarations` for `JavaCallableWrapperGeneratorTests`.
  * Updated `TypeNameMapGeneratorTests()` to use these types, too.
  * Added `GenerateActivity()` and `GenerateInstrumentation()` tests
  • Loading branch information
jonathanpeppers authored and jonpryor committed Mar 20, 2019
1 parent 3754536 commit 7c7eae3
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,6 @@
<Name>Xamarin.Android.Cecil</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\MonoRuntimeProvider.Bundled.java">
<LogicalName>MonoRuntimeProvider.Bundled.java</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="Resources\MonoRuntimeProvider.Shared.java">
<LogicalName>MonoRuntimeProvider.Shared.java</LogicalName>
</EmbeddedResource>
</ItemGroup>
<Import Project="..\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems" Label="Shared" Condition="Exists('..\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems')" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,19 @@ public JavaCallableWrapperGenerator (TypeDefinition type, Action<string, object[

public string ApplicationJavaClass { get; set; }

public bool UseSharedRuntime;

public bool GenerateOnCreateOverrides { get; set; }

public bool HasExport { get; private set; }

/// <summary>
/// The Java source code to be included in Instrumentation.onCreate
///
/// Originally came from MonoRuntimeProvider.java delimited by:
/// // Mono Runtime Initialization {{{
/// // }}}
/// </summary>
public string MonoRuntimeInitialization { get; set; }

public string Name {
get { return name; }
}
Expand Down Expand Up @@ -837,21 +844,9 @@ void WriteInstrumentationOnCreate (TextWriter sw, Action<TextWriter> extra)
sw.WriteLine ("\t\tandroid.content.Context context = getContext ();");
sw.WriteLine ();

using (var app = new StreamReader (
Assembly.GetExecutingAssembly ().GetManifestResourceStream (
UseSharedRuntime
? "MonoRuntimeProvider.Shared.java"
: "MonoRuntimeProvider.Bundled.java"))) {
bool copy = false;
string line;
while ((line = app.ReadLine ()) != null) {
if (string.CompareOrdinal ("\t\t// Mono Runtime Initialization {{{", line) == 0)
copy = true;
if (copy)
sw.WriteLine (line);
if (string.CompareOrdinal ("\t\t// }}}", line) == 0)
copy = false;
}
if (!string.IsNullOrEmpty (MonoRuntimeInitialization)) {
sw.WriteLine (MonoRuntimeInitialization);
sw.WriteLine ();
}

extra (sw);
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ public Name ()
mono.MonoPackageManager.setContext (this);
}}
public void onCreate ()
{{
mono.android.Runtime.register (""Xamarin.Android.ToolsTests.ApplicationName, Java.Interop.Tools.JavaCallableWrappers-Tests"", Name.class, __md_methods);
super.onCreate ();
}}
private java.util.ArrayList refList;
public void monodroidAddReference (java.lang.Object obj)
{{
Expand All @@ -74,11 +80,13 @@ public void monodroidClearReferences ()
Assert.AreEqual (expected, actual);
}

static string Generate (Type type, string applicationJavaClass = null)
static string Generate (Type type, string applicationJavaClass = null, string monoRuntimeInit = null)
{
var td = SupportDeclarations.GetTypeDefinition (type);
var g = new JavaCallableWrapperGenerator (td, null) {
ApplicationJavaClass = applicationJavaClass,
GenerateOnCreateOverrides = true,
MonoRuntimeInitialization = monoRuntimeInit,
};
var o = new StringWriter ();
var dir = Path.GetDirectoryName (typeof (JavaCallableWrapperGeneratorTests).Assembly.Location);
Expand Down Expand Up @@ -488,6 +496,92 @@ public void monodroidClearReferences ()
refList.clear ();
}
}
";
Assert.AreEqual (expected, actual);
}

[Test]
public void GenerateActivity ()
{
var actual = Generate (typeof (ExampleActivity));
var expected = @"package my;
public class ExampleActivity
extends android.app.Activity
implements
mono.android.IGCUserPeer
{
/** @hide */
public static final String __md_methods;
static {
__md_methods =
"""";
mono.android.Runtime.register (""Xamarin.Android.ToolsTests.ExampleActivity, Java.Interop.Tools.JavaCallableWrappers-Tests"", ExampleActivity.class, __md_methods);
}
private java.util.ArrayList refList;
public void monodroidAddReference (java.lang.Object obj)
{
if (refList == null)
refList = new java.util.ArrayList ();
refList.add (obj);
}
public void monodroidClearReferences ()
{
if (refList != null)
refList.clear ();
}
}
";
Assert.AreEqual (expected, actual);
}

[Test]
public void GenerateInstrumentation ()
{
var init = "mono.MonoPackageManager.LoadApplication (context, context.getApplicationInfo (), new String[]{context.getApplicationInfo ().sourceDir});";
var actual = Generate (typeof (ExampleInstrumentation), monoRuntimeInit: init);
var expected = $@"package my;
public class ExampleInstrumentation
extends android.app.Instrumentation
implements
mono.android.IGCUserPeer
{{
/** @hide */
public static final String __md_methods;
static {{
__md_methods =
"""";
}}
public void onCreate (android.os.Bundle arguments)
{{
android.content.Context context = getContext ();
{init}
mono.android.Runtime.register (""Xamarin.Android.ToolsTests.ExampleInstrumentation, Java.Interop.Tools.JavaCallableWrappers-Tests"", ExampleInstrumentation.class, __md_methods);
super.onCreate (arguments);
}}
private java.util.ArrayList refList;
public void monodroidAddReference (java.lang.Object obj)
{{
if (refList == null)
refList = new java.util.ArrayList ();
refList.add (obj);
}}
public void monodroidClearReferences ()
{{
if (refList != null)
refList.clear ();
}}
}}
";
Assert.AreEqual (expected, actual);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ protected virtual void OnCreate ()
{
}
}

[Register ("android/app/Activity", DoNotGenerateAcw = true)]
class Activity : Java.Lang.Object
{
[Register ("onCreate", "(Ljava/lang/Object;)V", "Activity.OnCreate")]
public virtual void OnCreate (Java.Lang.Object savedInstanceState)
{
}
}

[Register ("android/app/Instrumentation", DoNotGenerateAcw = true)]
class Instrumentation : Java.Lang.Object
{
[Register ("onCreate", "(Ljava/lang/Object;)V", "Instrumentation.OnCreate")]
public virtual void OnCreate (Java.Lang.Object arguments)
{
}
}
}

namespace Android.Runtime {
Expand Down Expand Up @@ -58,6 +76,8 @@ static class SupportDeclarations
typeof (DefaultName.A),
typeof (DefaultName.A.B),
typeof (DefaultName.C.D),
typeof (ExampleActivity),
typeof (ExampleInstrumentation),
typeof (ExampleOuterClass),
typeof (ExampleOuterClass.ExampleInnerClass),
typeof (InstrumentationName),
Expand Down Expand Up @@ -179,6 +199,16 @@ public ExampleInnerClass (ExampleOuterClass outer)
}
}

[Activity (Name = "my.ExampleActivity")]
class ExampleActivity : Activity
{
}

[Instrumentation (Name = "my.ExampleInstrumentation")]
class ExampleInstrumentation : Instrumentation
{
}

[BroadcastReceiver (Name = "receiver.Name")]
class ReceiverName : Java.Lang.Object
{
Expand Down
Loading

0 comments on commit 7c7eae3

Please sign in to comment.