public void GenerateCode(Interface type) { w.WriteLine ("\tpublic interface " + type.Name + " : global::Android.OS.IInterface"); w.WriteLine ("\t{"); foreach (var m in type.Methods) GenerateCode (m); w.WriteLine ("\t}"); w.WriteLine (@" public abstract class {0}Stub : global::Android.OS.Binder, global::Android.OS.IInterface, {1}{2}{0} {{ const string descriptor = ""{3}{2}{4}""; public {0}Stub () {{ this.AttachInterface (this, descriptor); }} public static {1}{2}{0} 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 {1}{2}{0}) return ({1}{2}{0}) 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;", // end of long formatted output... type.Name, self_ns, unit.Package != null ? "." : String.Empty, unit.Package != null ? unit.Package.ToJavaString () : null, type.JavaName); foreach (var method in type.Methods) { bool isVoidReturn = method.ReturnType.ToString () == "void"; w.WriteLine (@" case Transaction{0}: {{ data.EnforceInterface (descriptor);", method.Name); for (int i = 0; method.Arguments != null && i < method.Arguments.Length; i++) { var a = method.Arguments [i]; w.WriteLine ("\t\t\t\t{0} {1} = default ({0});", ToOutputTypeName (name_cache.ToCSharp (a.Type)), "arg" + i); if (a.Modifier == null || a.Modifier.Contains ("in")) w.WriteLine ("\t\t\t\t{0}", GetCreateStatements (a.Type, "data", "arg" + i)); } string args = String.Join (", ", (from i in Enumerable.Range (0, method.Arguments.Length) select "arg" + i).ToArray ()); if (isVoidReturn) w.WriteLine ("\t\t\t\tthis.{0} ({1});", method.Name, args); else w.WriteLine ("\t\t\t\tvar result = this.{0} ({1});", method.Name, args); if (method.Modifier == null || !method.Modifier.Contains ("oneway")) w.WriteLine ("\t\t\t\treply.WriteNoException ();"); if (!isVoidReturn) w.WriteLine ("\t\t\t\t{0}", GetWriteStatements (method.ReturnType, "reply", "result", "global::Android.OS.ParcelableWriteFlags.ReturnValue")); for (int i = 0; method.Arguments != null && i < method.Arguments.Length; i++) { var a = method.Arguments [i]; if (a.Modifier == null || a.Modifier.Contains ("out")) w.WriteLine ("\t\t\t\t{0}", GetWriteStatements (a.Type, "data", "arg" + i, "global::Android.OS.ParcelableWriteFlags.None")); } w.WriteLine ("\t\t\t\treturn true;"); w.WriteLine ("\t\t\t\t}"); } w.WriteLine (@" }} return base.OnTransact (code, data, reply, flags); }} public class Proxy : Java.Lang.Object, {1}{2}{0} {{ 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; }}", type.Name, self_ns, unit.Package != null ? "." : String.Empty); foreach (var method in type.Methods) { string args = JoinArguments (method); w.WriteLine (@" public {0} {1} ({2}) {{ global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); ", ToOutputTypeName (name_cache.ToCSharp (method.ReturnType)), method.Name, args); bool isOneWay = type.Modifier == "oneway"; bool hasReturn = method.ReturnType.ToString () != "void"; if (!isOneWay) w.WriteLine ("\t\t\t\tglobal::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain ();"); if (hasReturn) w.WriteLine ("{0} __result = default ({0});", ToOutputTypeName (name_cache.ToCSharp (method.ReturnType))); w.WriteLine (@" try { __data.WriteInterfaceToken (descriptor);"); foreach (var arg in method.Arguments) if (arg.Modifier == null || arg.Modifier.Contains ("in")) w.WriteLine ("\t\t\t\t\t" + GetWriteStatements (arg.Type, "__data", SafeCSharpName (arg.Name), "global::Android.OS.ParcelableWriteFlags.None")); w.WriteLine ("\t\t\t\t\tremote.Transact ({1}Stub.Transaction{0}, __data, {2}, 0);", method.Name, type.Name, isOneWay ? "null" : "__reply"); if (!isOneWay) w.WriteLine ("\t\t\t\t\t__reply.ReadException ();"); if (hasReturn) w.WriteLine ("\t\t\t\t\t{0}", GetCreateStatements (method.ReturnType, "__reply", "__result")); foreach (var arg in method.Arguments) if (arg.Modifier != null && arg.Modifier.Contains ("out")) w.WriteLine ("\t\t\t\t\t{0}", GetReadStatements (arg.Type, "__reply", SafeCSharpName (arg.Name))); if (hasReturn) w.WriteLine (@" } finally { __reply.Recycle (); __data.Recycle (); } return __result;"); else w.WriteLine (@" } finally { __data.Recycle (); }"); w.WriteLine (@" } "); } w.WriteLine (@" }"); // end of Proxy for (int i = 0; i < type.Methods.Length; i++) { var method = type.Methods [i]; w.WriteLine (@" internal const int Transaction{0} = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + {1};", method.Name, i); } foreach (var method in type.Methods) w.WriteLine (@" public abstract {0} {1} ({2});", ToOutputTypeName (name_cache.ToCSharp (method.ReturnType)), method.Name, JoinArguments (method)); w.WriteLine (@" }"); // end of Stub }
public void GenerateCode(Interface type) { w.WriteLine("\tpublic interface " + type.Name + " : global::Android.OS.IInterface"); w.WriteLine("\t{"); foreach (var m in type.Methods) { GenerateCode(m); } w.WriteLine("\t}"); w.WriteLine(@" public abstract class {0}Stub : global::Android.OS.Binder, global::Android.OS.IInterface, {1}{2}{0} {{ const string descriptor = ""{3}{2}{4}""; public {0}Stub () {{ this.AttachInterface (this, descriptor); }} public static {1}{2}{0} 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 {1}{2}{0}) return ({1}{2}{0}) 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;" , // end of long formatted output... type.Name, self_ns, unit.Package != null ? "." : String.Empty, unit.Package != null ? unit.Package.ToJavaString() : null, type.JavaName); foreach (var method in type.Methods) { cl_variable = null; bool isVoidReturn = method.ReturnType.ToString() == "void"; w.WriteLine(@" case Transaction{0}: {{ data.EnforceInterface (descriptor);" , method.Name); for (int i = 0; method.Arguments != null && i < method.Arguments.Length; i++) { var a = method.Arguments [i]; w.WriteLine("\t\t\t\t{0} {1} = default ({0});", ToOutputTypeName(name_cache.ToCSharp(a.Type)), "arg" + i); if (a.Modifier == null || a.Modifier.Contains("in")) { w.WriteLine("\t\t\t\t{0}", GetCreateStatements(a.Type, "data", "arg" + i)); } } string args = String.Join(", ", (from i in Enumerable.Range(0, method.Arguments.Length) select "arg" + i).ToArray()); if (isVoidReturn) { w.WriteLine("\t\t\t\tthis.{0} ({1});", method.Name, args); } else { w.WriteLine("\t\t\t\tvar result = this.{0} ({1});", method.Name, args); } if (method.Modifier == null || !method.Modifier.Contains("oneway")) { w.WriteLine("\t\t\t\treply.WriteNoException ();"); } if (!isVoidReturn) { w.WriteLine("\t\t\t\t{0}", GetWriteStatements(method.ReturnType, "reply", "result", "global::Android.OS.ParcelableWriteFlags.ReturnValue")); } for (int i = 0; method.Arguments != null && i < method.Arguments.Length; i++) { var a = method.Arguments [i]; if (a.Modifier == null || a.Modifier.Contains("out")) { w.WriteLine("\t\t\t\t{0}", GetWriteStatements(a.Type, "data", "arg" + i, "global::Android.OS.ParcelableWriteFlags.None")); } } w.WriteLine("\t\t\t\treturn true;"); w.WriteLine("\t\t\t\t}"); } w.WriteLine(@" }} return base.OnTransact (code, data, reply, flags); }} public class Proxy : Java.Lang.Object, {1}{2}{0} {{ 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; }}" , type.Name, self_ns, unit.Package != null ? "." : String.Empty); foreach (var method in type.Methods) { cl_variable = null; string args = JoinArguments(method); w.WriteLine(@" public {0} {1} ({2}) {{ global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain (); ", ToOutputTypeName(name_cache.ToCSharp(method.ReturnType)), method.Name, args); bool isOneWay = type.Modifier == "oneway"; bool hasReturn = method.ReturnType.ToString() != "void"; if (!isOneWay) { w.WriteLine("\t\t\t\tglobal::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain ();"); } if (hasReturn) { w.WriteLine("{0} __result = default ({0});", ToOutputTypeName(name_cache.ToCSharp(method.ReturnType))); } w.WriteLine(@" try { __data.WriteInterfaceToken (descriptor);" ); foreach (var arg in method.Arguments) { if (arg.Modifier == null || arg.Modifier.Contains("in")) { w.WriteLine("\t\t\t\t\t" + GetWriteStatements(arg.Type, "__data", SafeCSharpName(arg.Name), "global::Android.OS.ParcelableWriteFlags.None")); } } w.WriteLine("\t\t\t\t\tremote.Transact ({1}Stub.Transaction{0}, __data, {2}, 0);", method.Name, type.Name, isOneWay ? "null" : "__reply"); if (!isOneWay) { w.WriteLine("\t\t\t\t\t__reply.ReadException ();"); } if (hasReturn) { w.WriteLine("\t\t\t\t\t{0}", GetCreateStatements(method.ReturnType, "__reply", "__result")); } foreach (var arg in method.Arguments) { if (arg.Modifier != null && arg.Modifier.Contains("out")) { w.WriteLine("\t\t\t\t\t{0}", GetReadStatements(arg.Type, "__reply", SafeCSharpName(arg.Name))); } } if (hasReturn) { w.WriteLine(@" } finally { __reply.Recycle (); __data.Recycle (); } return __result;" ); } else { w.WriteLine(@" } finally { __data.Recycle (); }" ); } w.WriteLine(@" } "); } w.WriteLine(@" }" ); // end of Proxy for (int i = 0; i < type.Methods.Length; i++) { var method = type.Methods [i]; w.WriteLine(@" internal const int Transaction{0} = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + {1};" , method.Name, i); } foreach (var method in type.Methods) { w.WriteLine(@" public abstract {0} {1} ({2});" , ToOutputTypeName(name_cache.ToCSharp(method.ReturnType)), method.Name, JoinArguments(method)); } w.WriteLine(@" }" ); // end of Stub }