From e31b906b5c995c0c8fb9e32fe400786a11924973 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 22:33:01 +0000 Subject: [PATCH 1/3] Initial plan From a3702b32702f17099a45c30857188208b2a6b74b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 22:55:53 +0000 Subject: [PATCH 2/3] Add CSharpCodeGenerator unit tests covering parcelable, multi-interface, oneway, IBinder, CharSequence Agent-Logs-Url: https://github.com/dotnet/android/sessions/324cdc7a-1571-4d01-9842-9dd4c7a8ba2b Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com> --- .../AidlCompilerTestBase.cs | 4 +- .../CSharpCodeGeneratorTests.cs | 56 +++++ .../TestData/CharSequenceType.txt | 151 +++++++++++++ .../TestData/IBinderTypes.txt | 151 +++++++++++++ .../TestData/MultipleInterfaces.txt | 211 ++++++++++++++++++ .../TestData/OnewayMethods.txt | 144 ++++++++++++ .../TestData/ParcelableIgnore.txt | 114 ++++++++++ .../TestData/ParcelableStub.txt | 41 ++++ 8 files changed, 870 insertions(+), 2 deletions(-) create mode 100644 tests/Xamarin.Android.Tools.Aidl-Tests/CSharpCodeGeneratorTests.cs create mode 100644 tests/Xamarin.Android.Tools.Aidl-Tests/TestData/CharSequenceType.txt create mode 100644 tests/Xamarin.Android.Tools.Aidl-Tests/TestData/IBinderTypes.txt create mode 100644 tests/Xamarin.Android.Tools.Aidl-Tests/TestData/MultipleInterfaces.txt create mode 100644 tests/Xamarin.Android.Tools.Aidl-Tests/TestData/OnewayMethods.txt create mode 100644 tests/Xamarin.Android.Tools.Aidl-Tests/TestData/ParcelableIgnore.txt create mode 100644 tests/Xamarin.Android.Tools.Aidl-Tests/TestData/ParcelableStub.txt diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/AidlCompilerTestBase.cs b/tests/Xamarin.Android.Tools.Aidl-Tests/AidlCompilerTestBase.cs index 60afecbdf09..afb0d1e2cc2 100644 --- a/tests/Xamarin.Android.Tools.Aidl-Tests/AidlCompilerTestBase.cs +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/AidlCompilerTestBase.cs @@ -13,7 +13,7 @@ namespace Xamarin.Android.Tools.Aidl_Tests { public class AidlCompilerTestBase { - protected void RunTest (string name) + protected void RunTest (string name, ParcelableHandling parcelableHandling = ParcelableHandling.Ignore) { var root = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location); var file = Path.Combine (root, "TestData", name + ".txt"); @@ -22,7 +22,7 @@ protected void RunTest (string name) (var input, var expected_output) = SplitTestFile (text); var compiler = new AidlCompiler (); - var results = compiler.Run (input, out var output); + var results = compiler.Run (input, out var output, parcelableHandling: parcelableHandling); Assert.False (results.LogMessages.Any ()); diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/CSharpCodeGeneratorTests.cs b/tests/Xamarin.Android.Tools.Aidl-Tests/CSharpCodeGeneratorTests.cs new file mode 100644 index 00000000000..421a49b5313 --- /dev/null +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/CSharpCodeGeneratorTests.cs @@ -0,0 +1,56 @@ +using System; +using System.IO; +using System.Linq; +using NUnit.Framework; +using Xamarin.Android.Tools.Aidl; + +namespace Xamarin.Android.Tools.Aidl_Tests +{ + // Tests targeting specific code paths of Xamarin.Android.Tools.Aidl.CSharpCodeGenerator. + // These exist so we don't need to go through the MSBuild integration tests in AidlTest.cs + // to validate generator behavior. See https://github.com/dotnet/android/issues/... + [TestFixture] + public class CSharpCodeGeneratorTests : AidlCompilerTestBase + { + [Test] + public void ParcelableIgnore () => RunTest (nameof (ParcelableIgnore), ParcelableHandling.Ignore); + + [Test] + public void ParcelableStub () => RunTest (nameof (ParcelableStub), ParcelableHandling.Stub); + + [Test] + public void ParcelableError () + { + const string input = @"package com.xamarin.test; +parcelable MyData; +"; + var compiler = new AidlCompiler (); + Assert.Throws (() => + compiler.Run (input, out _, parcelableHandling: ParcelableHandling.Error)); + } + + [Test] + public void MultipleInterfaces () => RunTest (nameof (MultipleInterfaces)); + + [Test] + public void OnewayMethods () => RunTest (nameof (OnewayMethods)); + + [Test] + public void IBinderTypes () => RunTest (nameof (IBinderTypes)); + + [Test] + public void CharSequenceType () => RunTest (nameof (CharSequenceType)); + + [Test] + public void ParseErrorIsReported () + { + const string input = "this is not valid aidl @@@"; + + var compiler = new AidlCompiler (); + var results = compiler.Run (input, out var output); + + Assert.IsNull (output, "Output should be null when the input fails to parse."); + Assert.IsTrue (results.LogMessages.Any (), "Parser error messages should be reported."); + } + } +} diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/CharSequenceType.txt b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/CharSequenceType.txt new file mode 100644 index 00000000000..e335a20fb57 --- /dev/null +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/CharSequenceType.txt @@ -0,0 +1,151 @@ +package com.xamarin.test; + +import java.lang; + +interface ITest { + CharSequence getLabel (); + void setLabel (in CharSequence label); +} + +#### + +// This file is automatically generated and not supposed to be modified. +using System; +using Boolean = System.Boolean; +using String = System.String; +using List = Android.Runtime.JavaList; +using Map = Android.Runtime.JavaDictionary; +using Java; + +namespace Com.Xamarin.Test +{ + public interface ITest : global::Android.OS.IInterface + { + Java.Lang.ICharSequence GetLabel (); + void SetLabel (Java.Lang.ICharSequence label); + } + + public abstract class ITestStub : global::Android.OS.Binder, global::Android.OS.IInterface, Com.Xamarin.Test.ITest + { + const string descriptor = "com.xamarin.test.ITest"; + public ITestStub () + { + this.AttachInterface (this, descriptor); + } + + public static Com.Xamarin.Test.ITest AsInterface (global::Android.OS.IBinder obj) + { + if (obj == null) + return null; + var iin = (global::Android.OS.IInterface) obj.QueryLocalInterface (descriptor); + if (iin != null && iin is Com.Xamarin.Test.ITest) + return (Com.Xamarin.Test.ITest) iin; + return new Proxy (obj); + } + + public global::Android.OS.IBinder AsBinder () + { + return this; + } + + protected override bool OnTransact (int code, global::Android.OS.Parcel data, global::Android.OS.Parcel reply, int flags) + { + switch (code) { + case global::Android.OS.BinderConsts.InterfaceTransaction: + reply.WriteString (descriptor); + return true; + + case TransactionGetLabel: { + data.EnforceInterface (descriptor); + var result = this.GetLabel (); + reply.WriteNoException (); + if (result != null) { reply.WriteInt (1); global::Android.Text.TextUtils.WriteToParcel (result, reply, global::Android.OS.ParcelableWriteFlags.ReturnValue); } else reply.WriteInt (0); + return true; + } + + case TransactionSetLabel: { + data.EnforceInterface (descriptor); + Java.Lang.ICharSequence arg0 = default (Java.Lang.ICharSequence); + arg0 = data.ReadInt () != 0 ? (global::Java.Lang.ICharSequence) global::Android.Text.TextUtils.CharSequenceCreator.CreateFromParcel (data) : null; + this.SetLabel (arg0); + reply.WriteNoException (); + return true; + } + + } + return base.OnTransact (code, data, reply, flags); + } + + public class Proxy : Java.Lang.Object, Com.Xamarin.Test.ITest + { + global::Android.OS.IBinder remote; + + public Proxy (global::Android.OS.IBinder remote) + { + this.remote = remote; + } + + public global::Android.OS.IBinder AsBinder () + { + return remote; + } + + public string GetInterfaceDescriptor () + { + return descriptor; + } + + public Java.Lang.ICharSequence GetLabel () + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + Java.Lang.ICharSequence __result = default (Java.Lang.ICharSequence); + + try { + __data.WriteInterfaceToken (descriptor); + remote.Transact (ITestStub.TransactionGetLabel, __data, __reply, 0); + __reply.ReadException (); + __result = __reply.ReadInt () != 0 ? (global::Java.Lang.ICharSequence) global::Android.Text.TextUtils.CharSequenceCreator.CreateFromParcel (__reply) : null; + + } finally { + __reply.Recycle (); + __data.Recycle (); + } + return __result; + + } + + + public void SetLabel (Java.Lang.ICharSequence label) + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + + try { + __data.WriteInterfaceToken (descriptor); + if (label != null) { __data.WriteInt (1); global::Android.Text.TextUtils.WriteToParcel (label, __data, global::Android.OS.ParcelableWriteFlags.None); } else __data.WriteInt (0); + remote.Transact (ITestStub.TransactionSetLabel, __data, __reply, 0); + __reply.ReadException (); + + } finally { + __data.Recycle (); + } + + } + + + } + + internal const int TransactionGetLabel = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 0; + + internal const int TransactionSetLabel = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 1; + + public abstract Java.Lang.ICharSequence GetLabel (); + + public abstract void SetLabel (Java.Lang.ICharSequence label); + + } +} + diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/IBinderTypes.txt b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/IBinderTypes.txt new file mode 100644 index 00000000000..473ad88a7dd --- /dev/null +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/IBinderTypes.txt @@ -0,0 +1,151 @@ +package com.xamarin.test; + +import android.os; + +interface ITest { + IBinder getBinder (); + void setBinder (in IBinder binder); +} + +#### + +// This file is automatically generated and not supposed to be modified. +using System; +using Boolean = System.Boolean; +using String = System.String; +using List = Android.Runtime.JavaList; +using Map = Android.Runtime.JavaDictionary; +using Android; + +namespace Com.Xamarin.Test +{ + public interface ITest : global::Android.OS.IInterface + { + Android.OS.IBinder GetBinder (); + void SetBinder (Android.OS.IBinder binder); + } + + public abstract class ITestStub : global::Android.OS.Binder, global::Android.OS.IInterface, Com.Xamarin.Test.ITest + { + const string descriptor = "com.xamarin.test.ITest"; + public ITestStub () + { + this.AttachInterface (this, descriptor); + } + + public static Com.Xamarin.Test.ITest AsInterface (global::Android.OS.IBinder obj) + { + if (obj == null) + return null; + var iin = (global::Android.OS.IInterface) obj.QueryLocalInterface (descriptor); + if (iin != null && iin is Com.Xamarin.Test.ITest) + return (Com.Xamarin.Test.ITest) iin; + return new Proxy (obj); + } + + public global::Android.OS.IBinder AsBinder () + { + return this; + } + + protected override bool OnTransact (int code, global::Android.OS.Parcel data, global::Android.OS.Parcel reply, int flags) + { + switch (code) { + case global::Android.OS.BinderConsts.InterfaceTransaction: + reply.WriteString (descriptor); + return true; + + case TransactionGetBinder: { + data.EnforceInterface (descriptor); + var result = this.GetBinder (); + reply.WriteNoException (); + reply.WriteStrongBinder (result); + return true; + } + + case TransactionSetBinder: { + data.EnforceInterface (descriptor); + Android.OS.IBinder arg0 = default (Android.OS.IBinder); + arg0 = data.ReadStrongBinder (); + this.SetBinder (arg0); + reply.WriteNoException (); + return true; + } + + } + return base.OnTransact (code, data, reply, flags); + } + + public class Proxy : Java.Lang.Object, Com.Xamarin.Test.ITest + { + global::Android.OS.IBinder remote; + + public Proxy (global::Android.OS.IBinder remote) + { + this.remote = remote; + } + + public global::Android.OS.IBinder AsBinder () + { + return remote; + } + + public string GetInterfaceDescriptor () + { + return descriptor; + } + + public Android.OS.IBinder GetBinder () + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + Android.OS.IBinder __result = default (Android.OS.IBinder); + + try { + __data.WriteInterfaceToken (descriptor); + remote.Transact (ITestStub.TransactionGetBinder, __data, __reply, 0); + __reply.ReadException (); + __result = __reply.ReadStrongBinder (); + + } finally { + __reply.Recycle (); + __data.Recycle (); + } + return __result; + + } + + + public void SetBinder (Android.OS.IBinder binder) + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + + try { + __data.WriteInterfaceToken (descriptor); + __data.WriteStrongBinder (binder); + remote.Transact (ITestStub.TransactionSetBinder, __data, __reply, 0); + __reply.ReadException (); + + } finally { + __data.Recycle (); + } + + } + + + } + + internal const int TransactionGetBinder = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 0; + + internal const int TransactionSetBinder = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 1; + + public abstract Android.OS.IBinder GetBinder (); + + public abstract void SetBinder (Android.OS.IBinder binder); + + } +} + diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/MultipleInterfaces.txt b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/MultipleInterfaces.txt new file mode 100644 index 00000000000..b312278d61c --- /dev/null +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/MultipleInterfaces.txt @@ -0,0 +1,211 @@ +package com.xamarin.test; + +interface IFirst { + void doFirst (); +} + +interface ISecond { + int doSecond (int x); +} + +#### + +// This file is automatically generated and not supposed to be modified. +using System; +using Boolean = System.Boolean; +using String = System.String; +using List = Android.Runtime.JavaList; +using Map = Android.Runtime.JavaDictionary; + +namespace Com.Xamarin.Test +{ + public interface IFirst : global::Android.OS.IInterface + { + void DoFirst (); + } + + public abstract class IFirstStub : global::Android.OS.Binder, global::Android.OS.IInterface, Com.Xamarin.Test.IFirst + { + const string descriptor = "com.xamarin.test.IFirst"; + public IFirstStub () + { + this.AttachInterface (this, descriptor); + } + + public static Com.Xamarin.Test.IFirst AsInterface (global::Android.OS.IBinder obj) + { + if (obj == null) + return null; + var iin = (global::Android.OS.IInterface) obj.QueryLocalInterface (descriptor); + if (iin != null && iin is Com.Xamarin.Test.IFirst) + return (Com.Xamarin.Test.IFirst) iin; + return new Proxy (obj); + } + + public global::Android.OS.IBinder AsBinder () + { + return this; + } + + protected override bool OnTransact (int code, global::Android.OS.Parcel data, global::Android.OS.Parcel reply, int flags) + { + switch (code) { + case global::Android.OS.BinderConsts.InterfaceTransaction: + reply.WriteString (descriptor); + return true; + + case TransactionDoFirst: { + data.EnforceInterface (descriptor); + this.DoFirst (); + reply.WriteNoException (); + return true; + } + + } + return base.OnTransact (code, data, reply, flags); + } + + public class Proxy : Java.Lang.Object, Com.Xamarin.Test.IFirst + { + global::Android.OS.IBinder remote; + + public Proxy (global::Android.OS.IBinder remote) + { + this.remote = remote; + } + + public global::Android.OS.IBinder AsBinder () + { + return remote; + } + + public string GetInterfaceDescriptor () + { + return descriptor; + } + + public void DoFirst () + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + + try { + __data.WriteInterfaceToken (descriptor); + remote.Transact (IFirstStub.TransactionDoFirst, __data, __reply, 0); + __reply.ReadException (); + + } finally { + __data.Recycle (); + } + + } + + + } + + internal const int TransactionDoFirst = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 0; + + public abstract void DoFirst (); + + } + public interface ISecond : global::Android.OS.IInterface + { + int DoSecond (int x); + } + + public abstract class ISecondStub : global::Android.OS.Binder, global::Android.OS.IInterface, Com.Xamarin.Test.ISecond + { + const string descriptor = "com.xamarin.test.ISecond"; + public ISecondStub () + { + this.AttachInterface (this, descriptor); + } + + public static Com.Xamarin.Test.ISecond AsInterface (global::Android.OS.IBinder obj) + { + if (obj == null) + return null; + var iin = (global::Android.OS.IInterface) obj.QueryLocalInterface (descriptor); + if (iin != null && iin is Com.Xamarin.Test.ISecond) + return (Com.Xamarin.Test.ISecond) iin; + return new Proxy (obj); + } + + public global::Android.OS.IBinder AsBinder () + { + return this; + } + + protected override bool OnTransact (int code, global::Android.OS.Parcel data, global::Android.OS.Parcel reply, int flags) + { + switch (code) { + case global::Android.OS.BinderConsts.InterfaceTransaction: + reply.WriteString (descriptor); + return true; + + case TransactionDoSecond: { + data.EnforceInterface (descriptor); + int arg0 = default (int); + arg0 = data.ReadInt (); + var result = this.DoSecond (arg0); + reply.WriteNoException (); + reply.WriteInt (result); + return true; + } + + } + return base.OnTransact (code, data, reply, flags); + } + + public class Proxy : Java.Lang.Object, Com.Xamarin.Test.ISecond + { + global::Android.OS.IBinder remote; + + public Proxy (global::Android.OS.IBinder remote) + { + this.remote = remote; + } + + public global::Android.OS.IBinder AsBinder () + { + return remote; + } + + public string GetInterfaceDescriptor () + { + return descriptor; + } + + public int DoSecond (int x) + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + int __result = default (int); + + try { + __data.WriteInterfaceToken (descriptor); + __data.WriteInt (x); + remote.Transact (ISecondStub.TransactionDoSecond, __data, __reply, 0); + __reply.ReadException (); + __result = __reply.ReadInt (); + + } finally { + __reply.Recycle (); + __data.Recycle (); + } + return __result; + + } + + + } + + internal const int TransactionDoSecond = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 0; + + public abstract int DoSecond (int x); + + } +} + diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/OnewayMethods.txt b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/OnewayMethods.txt new file mode 100644 index 00000000000..58b9e5680ce --- /dev/null +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/OnewayMethods.txt @@ -0,0 +1,144 @@ +package com.xamarin.test; + +interface ITest { + oneway void fireAndForget (int code); + oneway void notify (in String message); +} + +#### + +// This file is automatically generated and not supposed to be modified. +using System; +using Boolean = System.Boolean; +using String = System.String; +using List = Android.Runtime.JavaList; +using Map = Android.Runtime.JavaDictionary; + +namespace Com.Xamarin.Test +{ + public interface ITest : global::Android.OS.IInterface + { + void FireAndForget (int code); + void Notify (String message); + } + + public abstract class ITestStub : global::Android.OS.Binder, global::Android.OS.IInterface, Com.Xamarin.Test.ITest + { + const string descriptor = "com.xamarin.test.ITest"; + public ITestStub () + { + this.AttachInterface (this, descriptor); + } + + public static Com.Xamarin.Test.ITest AsInterface (global::Android.OS.IBinder obj) + { + if (obj == null) + return null; + var iin = (global::Android.OS.IInterface) obj.QueryLocalInterface (descriptor); + if (iin != null && iin is Com.Xamarin.Test.ITest) + return (Com.Xamarin.Test.ITest) iin; + return new Proxy (obj); + } + + public global::Android.OS.IBinder AsBinder () + { + return this; + } + + protected override bool OnTransact (int code, global::Android.OS.Parcel data, global::Android.OS.Parcel reply, int flags) + { + switch (code) { + case global::Android.OS.BinderConsts.InterfaceTransaction: + reply.WriteString (descriptor); + return true; + + case TransactionFireAndForget: { + data.EnforceInterface (descriptor); + int arg0 = default (int); + arg0 = data.ReadInt (); + this.FireAndForget (arg0); + return true; + } + + case TransactionNotify: { + data.EnforceInterface (descriptor); + String arg0 = default (String); + arg0 = data.ReadString (); + this.Notify (arg0); + return true; + } + + } + return base.OnTransact (code, data, reply, flags); + } + + public class Proxy : Java.Lang.Object, Com.Xamarin.Test.ITest + { + global::Android.OS.IBinder remote; + + public Proxy (global::Android.OS.IBinder remote) + { + this.remote = remote; + } + + public global::Android.OS.IBinder AsBinder () + { + return remote; + } + + public string GetInterfaceDescriptor () + { + return descriptor; + } + + public void FireAndForget (int code) + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + + try { + __data.WriteInterfaceToken (descriptor); + __data.WriteInt (code); + remote.Transact (ITestStub.TransactionFireAndForget, __data, __reply, 0); + __reply.ReadException (); + + } finally { + __data.Recycle (); + } + + } + + + public void Notify (String message) + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + + try { + __data.WriteInterfaceToken (descriptor); + __data.WriteString (message); + remote.Transact (ITestStub.TransactionNotify, __data, __reply, 0); + __reply.ReadException (); + + } finally { + __data.Recycle (); + } + + } + + + } + + internal const int TransactionFireAndForget = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 0; + + internal const int TransactionNotify = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 1; + + public abstract void FireAndForget (int code); + + public abstract void Notify (String message); + + } +} + diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/ParcelableIgnore.txt b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/ParcelableIgnore.txt new file mode 100644 index 00000000000..e8776a17460 --- /dev/null +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/ParcelableIgnore.txt @@ -0,0 +1,114 @@ +package com.xamarin.test; + +parcelable MyData; + +interface ITest { + void send (in MyData data); +} + +#### + +// This file is automatically generated and not supposed to be modified. +using System; +using Boolean = System.Boolean; +using String = System.String; +using List = Android.Runtime.JavaList; +using Map = Android.Runtime.JavaDictionary; + +namespace Com.Xamarin.Test +{ + public interface ITest : global::Android.OS.IInterface + { + void Send (global::Com.Xamarin.Test.MyData data); + } + + public abstract class ITestStub : global::Android.OS.Binder, global::Android.OS.IInterface, Com.Xamarin.Test.ITest + { + const string descriptor = "com.xamarin.test.ITest"; + public ITestStub () + { + this.AttachInterface (this, descriptor); + } + + public static Com.Xamarin.Test.ITest AsInterface (global::Android.OS.IBinder obj) + { + if (obj == null) + return null; + var iin = (global::Android.OS.IInterface) obj.QueryLocalInterface (descriptor); + if (iin != null && iin is Com.Xamarin.Test.ITest) + return (Com.Xamarin.Test.ITest) iin; + return new Proxy (obj); + } + + public global::Android.OS.IBinder AsBinder () + { + return this; + } + + protected override bool OnTransact (int code, global::Android.OS.Parcel data, global::Android.OS.Parcel reply, int flags) + { + switch (code) { + case global::Android.OS.BinderConsts.InterfaceTransaction: + reply.WriteString (descriptor); + return true; + + case TransactionSend: { + data.EnforceInterface (descriptor); + global::Com.Xamarin.Test.MyData arg0 = default (global::Com.Xamarin.Test.MyData); + arg0 = data.ReadInt () != 0 ? (global::Com.Xamarin.Test.MyData) global::Android.OS.Bundle.Creator.CreateFromParcel (data) : null; + this.Send (arg0); + reply.WriteNoException (); + return true; + } + + } + return base.OnTransact (code, data, reply, flags); + } + + public class Proxy : Java.Lang.Object, Com.Xamarin.Test.ITest + { + global::Android.OS.IBinder remote; + + public Proxy (global::Android.OS.IBinder remote) + { + this.remote = remote; + } + + public global::Android.OS.IBinder AsBinder () + { + return remote; + } + + public string GetInterfaceDescriptor () + { + return descriptor; + } + + public void Send (global::Com.Xamarin.Test.MyData data) + { + global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); + + global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain (); + + try { + __data.WriteInterfaceToken (descriptor); + if (data != null) { __data.WriteInt (1); data.WriteToParcel (__data, global::Android.OS.ParcelableWriteFlags.None); } else __data.WriteInt (0); + remote.Transact (ITestStub.TransactionSend, __data, __reply, 0); + __reply.ReadException (); + + } finally { + __data.Recycle (); + } + + } + + + } + + internal const int TransactionSend = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 0; + + public abstract void Send (global::Com.Xamarin.Test.MyData data); + + } +} + diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/ParcelableStub.txt b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/ParcelableStub.txt new file mode 100644 index 00000000000..ff086b3670c --- /dev/null +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/TestData/ParcelableStub.txt @@ -0,0 +1,41 @@ +package com.xamarin.test; + +parcelable MyData; + +#### + +// This file is automatically generated and not supposed to be modified. +using System; +using Boolean = System.Boolean; +using String = System.String; +using List = Android.Runtime.JavaList; +using Map = Android.Runtime.JavaDictionary; + +namespace Com.Xamarin.Test +{ + + public class MyData : global::Java.Lang.Object, global::Android.OS.IParcelable + { + public static global::Android.OS.IParcelableCreator Creator; // FIXME: implement + + public virtual int DescribeContents () + { + throw new NotImplementedException (); + } + + // LAMESPEC: Android IParcelable interface is bogus by design. It does not expose + // this method, while aidl tool explicitly expects this method and generates such + // code that invokes it(!) + // Seealso: http://code.google.com/p/android/issues/detail?id=21777 + public virtual void ReadFromParcel (global::Android.OS.Parcel parcel) + { + throw new NotImplementedException (); + } + + public virtual void WriteToParcel (global::Android.OS.Parcel parcel, global::Android.OS.ParcelableWriteFlags flags) + { + throw new NotImplementedException (); + } + } +} + From 9cc05f165ce7811125a302bc579be14af9727de2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 22:56:26 +0000 Subject: [PATCH 3/3] Remove incomplete issue URL placeholder from test comment Agent-Logs-Url: https://github.com/dotnet/android/sessions/324cdc7a-1571-4d01-9842-9dd4c7a8ba2b Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com> --- .../CSharpCodeGeneratorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Xamarin.Android.Tools.Aidl-Tests/CSharpCodeGeneratorTests.cs b/tests/Xamarin.Android.Tools.Aidl-Tests/CSharpCodeGeneratorTests.cs index 421a49b5313..b1732fe6fcb 100644 --- a/tests/Xamarin.Android.Tools.Aidl-Tests/CSharpCodeGeneratorTests.cs +++ b/tests/Xamarin.Android.Tools.Aidl-Tests/CSharpCodeGeneratorTests.cs @@ -8,7 +8,7 @@ namespace Xamarin.Android.Tools.Aidl_Tests { // Tests targeting specific code paths of Xamarin.Android.Tools.Aidl.CSharpCodeGenerator. // These exist so we don't need to go through the MSBuild integration tests in AidlTest.cs - // to validate generator behavior. See https://github.com/dotnet/android/issues/... + // to validate generator behavior. [TestFixture] public class CSharpCodeGeneratorTests : AidlCompilerTestBase {