private SourceFile(IApkFile apk, JarFile jar, ISpySettings settings, MapFileLookup mapFile, string singleFilePath = null) { this.apk = apk; this.jar = jar; this.settings = settings; this.mapFile = mapFile; this.singleFilePath = singleFilePath; #if DEBUG || ENABLE_SHOW_AST classLoader = new AssemblyClassLoader(module.OnClassLoaded); var modParams = new ModuleParameters { AssemblyResolver = new AssemblyResolver(new[] { Frameworks.Instance.FirstOrDefault().Folder }, classLoader, module.OnAssemblyLoaded), Kind = ModuleKind.Dll }; assembly = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition("spy", Version.Parse("1.0.0.0")), "main", modParams); classLoader.LoadAssembly(assembly); var dot42Assembly = modParams.AssemblyResolver.Resolve("dot42"); // Force loading of classes if (jar != null) { foreach (var fileName in jar.ClassFileNames) { OpenClass(fileName); } } #endif }
/// <summary> /// Create wrapper for given jar file /// </summary> private void CreateAssembly(JarFile jf, string folder) { // Create java type wrappers var module = new NetModule(jf.Scope); var classTypeBuilders = jf.ClassNames.SelectMany(n => StandardTypeBuilder.Create(jf.LoadClass(n), target)); var typeBuilders = classTypeBuilders.OrderBy(x => x.Priority).ToList(); typeBuilders.ForEach(x => x.CreateType(null, module, target)); // Implement and finalize types Implement(typeBuilders, target); var assemblyAttributes = new List<NetCustomAttribute>(); if (!importAsStubs) { // Import code var attrType = new NetTypeDefinition(ClassFile.Empty, target, AttributeConstants.Dot42Scope) { Name = AttributeConstants.JavaCodeAttributeName, Namespace = AttributeConstants.Dot42AttributeNamespace }; var hash = JarReferenceHash.ComputeJarReferenceHash(jarFilePath); var attr = new NetCustomAttribute(attrType, hash); assemblyAttributes.Add(attr); } // Save CodeGenerator.Generate(folder, module.Types, assemblyAttributes, target, this, target); }
/// <summary> /// Perform the import from jar to cs source. /// </summary> public void Import() { using (var jf = new JarFile(File.OpenRead(jarFilePath), jarFilePath, target.TypeNameMap)) { // Create output folder var folder = Path.GetFullPath(sourceOutputPath); Directory.CreateDirectory(folder); // Create mscorlib CreateAssembly(jf, folder); } }
/// <summary> /// Try loading the jar file to see if we have a stub jar. /// </summary> private void jarLoader_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { importCode = true; libName = string.Empty; var jarPath = (string) e.Argument; try { var hasJarPath = !string.IsNullOrEmpty(jarPath) && File.Exists(jarPath); if (hasJarPath) { var jf = new JarFile(File.OpenRead(jarPath), jarPath, null); ClassFile result; if (jf.TryLoadClass("com/google/android/maps/MapActivity", out result)) { importCode = false; libName = "com.google.android.maps"; } } } catch (Exception) { // Ignore } }
public override void FillTypemapXml(JarFile jf, XElement parent) { var element = new XElement("type"); element.Add(new XAttribute("fullname", TypeDefinition.FullName)); element.Add(new XAttribute("classname", TypeDefinition.OriginalJavaClassName)); parent.Add(element); }
/// <summary> /// Add this type to the layout.xml file if needed. /// </summary> public override void FillLayoutXml(JarFile jf, XElement parent) { var baseName = GetLayoutBaseClassName(cf); if (baseName == null) return; string elementName; switch (baseName) { case SdkConstants.ViewClass: elementName = "view"; break; case SdkConstants.ViewGroupClass: elementName = "viewgroup"; break; default: return; } var shortName = GetShortName(cf.ClassName); var element = new XElement(elementName, new XAttribute("name", shortName)); if (cf.IsAbstract) element.Add(new XAttribute("abstract", "true")); ClassFile superClass ; if (cf.TryGetSuperClass(out superClass)) { if ((superClass != null) && (GetLayoutBaseClassName(superClass) != null)) element.Add(new XAttribute("super", GetShortName(superClass.ClassName))); } parent.Add(element); }
/// <summary> /// Entry point /// </summary> internal static int Main(string[] args) { try { #if DEBUG if (args.Length == 0) { var assemblyFolder = Path.GetDirectoryName(typeof (Program).Assembly.Location); var folder = Path.GetFullPath(Path.Combine(assemblyFolder, @"..\..\..\..\Sources\Framework\Generated")); var sdkRoot = Path.GetFullPath(Path.Combine(assemblyFolder, @"..\..\..\..\Binaries")); var xmlFolder = Path.GetFullPath(Path.Combine(assemblyFolder, @"..\..\..\Android\Docs\xml")); var forwardAssembliesFolder = Path.GetFullPath(Path.Combine(assemblyFolder, @"..\..\..\..\Sources\Framework\ForwardAssemblies")); //var sdkRoot = Environment.GetEnvironmentVariable("ANDROID_SDK_ROOT"); if (string.IsNullOrEmpty(sdkRoot)) throw new ArgumentException("Set ANDROID_SDK_ROOT environment variable"); var platformFolder = Path.Combine(sdkRoot, @"platforms\android-15"); args = new[] { ToolOptions.InputJar.CreateArg(Path.Combine(platformFolder, "Android.jar")), ToolOptions.InputAttrsXml.CreateArg(Path.Combine(platformFolder, @"data\res\values\attrs.xml")), ToolOptions.InputSourceProperties.CreateArg(Path.Combine(platformFolder, "source.properties")), ToolOptions.OutputFolder.CreateArg(folder), //ToolOptions.DoxygenXmlFolder.CreateArg(xmlFolder), //ToolOptions.PublicKeyToken.CreateArg("0a72796057571e65"), ToolOptions.ForwardAssembliesFolder.CreateArg(forwardAssembliesFolder) }; } #endif var options = new CommandLineOptions(args); if (options.ShowHelp) { options.Usage(); return 2; } if (!File.Exists(options.FrameworkJar)) { throw new ArgumentException(string.Format("Framework jar ({0}) not found.", options.FrameworkJar)); } if (!File.Exists(options.SourceProperties)) { throw new ArgumentException(string.Format("Source.properties ({0}) not found.", options.SourceProperties)); } var sdkPropertiesPath = Path.Combine(Path.GetDirectoryName(options.SourceProperties), "sdk.properties"); if (!File.Exists(sdkPropertiesPath)) { throw new ArgumentException(string.Format("sdk.properties ({0}) not found.", sdkPropertiesPath)); } // Load source.properties var sourceProperties = new SourceProperties(options.SourceProperties); using (var jf = new JarFile(File.Open(options.FrameworkJar, FileMode.Open, FileAccess.Read), AttributeConstants.Dot42Scope, null)) { // Create output folder var folder = Path.Combine(options.OutputFolder, sourceProperties.PlatformVersion); Directory.CreateDirectory(folder); if (!options.VersionOnly) { // Load Doxygen model var xmlModel = new DocModel(); using (Profiler.Profile(x => Console.WriteLine("Load XML took {0}ms", x.TotalMilliseconds))) { xmlModel.Load(options.DoxygenXmlFolder); } // Create mscorlib CreateFrameworkAssembly(jf, xmlModel, sourceProperties, folder); // Copy AndroidManifest.xml into the assembly. var manifestStream = jf.GetResource("AndroidManifest.xml"); // Copy resources.arsc into the assembly. var resourcesStream = jf.GetResource("resources.arsc"); // Load attrs.xml into memory var attrsXml = File.ReadAllBytes(options.AttrsXml); // Load layout.xml into memory var layoutXml = File.ReadAllBytes(Path.Combine(folder, "layout.xml")); // Create base package var basePackagePath = Path.Combine(folder, "base.apk"); using (var fileStream = new FileStream(basePackagePath, FileMode.Create, FileAccess.Write)) { using (var zipStream = new ZipOutputStream(fileStream) {UseZip64 = UseZip64.Off}) { zipStream.SetLevel(9); zipStream.PutNextEntry(new ZipEntry("AndroidManifest.xml") {CompressionMethod = CompressionMethod.Deflated}); zipStream.Write(manifestStream, 0, manifestStream.Length); zipStream.CloseEntry(); zipStream.PutNextEntry(new ZipEntry("resources.arsc") {CompressionMethod = CompressionMethod.Deflated}); zipStream.Write(resourcesStream, 0, resourcesStream.Length); zipStream.CloseEntry(); zipStream.PutNextEntry(new ZipEntry(@"attrs.xml") {CompressionMethod = CompressionMethod.Deflated}); zipStream.Write(attrsXml, 0, attrsXml.Length); zipStream.CloseEntry(); zipStream.PutNextEntry(new ZipEntry(@"layout.xml") {CompressionMethod = CompressionMethod.Deflated}); zipStream.Write(layoutXml, 0, layoutXml.Length); zipStream.CloseEntry(); } } // Create output folder file if (!string.IsNullOrEmpty(options.OutputFolderFile)) { File.WriteAllText(options.OutputFolderFile, folder); } } // Create output version file var version = string.Format(File.ReadAllText(Path.Combine(folder, "..", "..", "Header.txt")), "Version.cs") + Environment.NewLine + string.Format("[assembly: System.Reflection.AssemblyVersion(\"{0}\")]", sourceProperties.AssemblyVersion) + Environment.NewLine + string.Format("[assembly: System.Reflection.AssemblyFileVersion(\"{0}\")]", sourceProperties.AssemblyFileVersion) + Environment.NewLine + string.Format("[assembly: System.Reflection.AssemblyInformationalVersion(\"{0}\")]", sourceProperties.AssemblyInformationalVersion) + Environment.NewLine + "#if !BASELIB" + Environment.NewLine + string.Format("[assembly: System.Runtime.Versioning.TargetFramework(\"Dot42,Version={0}\", FrameworkDisplayName = \"Dot42\")]", sourceProperties.PlatformVersion) + Environment.NewLine + "#endif" + Environment.NewLine; File.WriteAllText(Path.Combine(folder, "Version.cs"), version); if (!options.VersionOnly) { // Load sdk.properties var sdkProperties = new SdkProperties(sdkPropertiesPath); // Create framework ini var frameworkIni = new FrameworkIni(folder); Initialize(frameworkIni, sourceProperties, sdkProperties); frameworkIni.Save(); // Create FrameworkList.xml FrameworkListBuilder.Build(folder, options.ForwardAssembliesFolder, null, sourceProperties.AssemblyVersion, sourceProperties.PlatformVersion); } } return 0; } catch (Exception ex) { Console.WriteLine(ex.Message); #if DEBUG Console.WriteLine(ex.StackTrace); #endif return 1; } }
/// <summary> /// Create Dot42.dll /// </summary> private static void CreateFrameworkAssembly(JarFile jf, DocModel xmlModel, SourceProperties sourceProperties, string folder) { // Initialize all MappedTypeBuilder.Initialize(CompositionContainer); // Create java type wrappers var module = new NetModule(AttributeConstants.Dot42Scope); var classLoader = new AssemblyClassLoader(null); var target = new TargetFramework(null, classLoader, xmlModel, LogMissingParamNamesType, true, false, Enumerable.Empty<string>()); List<TypeBuilder> typeBuilders; using (Profiler.Profile(x => Console.WriteLine("Create took {0}ms", x.TotalMilliseconds))) { var classTypeBuilders = jf.ClassNames.SelectMany(n => StandardTypeBuilder.Create(jf.LoadClass(n), target)); var customTypeBuilder = CompositionContainer.GetExportedValues<ICustomTypeBuilder>().OrderBy(x => x.CustomTypeName).Select(x => x.AsTypeBuilder()); typeBuilders = classTypeBuilders.Concat(customTypeBuilder).OrderBy(x => x.Priority).ToList(); typeBuilders.ForEach(x => x.CreateType(null, module, target)); } // Create JavaRef attribute //JavaRefAttributeBuilder.Build(asm.MainModule); // Implement and finalize types using (Profiler.Profile(x => Console.WriteLine("Implement took {0}ms", x.TotalMilliseconds))) { JarImporter.Implement(typeBuilders, target); } // Save using (Profiler.Profile(x => Console.WriteLine("Generate took {0}ms", x.TotalMilliseconds))) { CodeGenerator.Generate(folder, module.Types, new List<NetCustomAttribute>(), target, new FrameworkCodeGeneratorContext(), target); } // Create layout.xml var doc = new XDocument(new XElement("layout")); typeBuilders.ForEach(x => x.FillLayoutXml(jf, doc.Root)); doc.Save(Path.Combine(folder, "layout.xml")); }
/// <summary> /// Add this type to the layout.xml file if needed. /// </summary> public override void FillLayoutXml(JarFile jf, XElement parent) { // Do nothing }
/// <summary> /// Gets the loaded jar file. /// </summary> public JarFile Resolve(IClassLoader nextClassLoader) { return resolved ?? (resolved = new JarFile(new MemoryStream(Data), FileName, nextClassLoader)); }
public override void FillTypemapXml(JarFile jf, XElement parent) { }
/// <summary> /// Gets the loaded jar file. /// </summary> public JarFile Resolve(IClassLoader nextClassLoader) { return resolved ?? (resolved = new JarFile(new MemoryStream(resource.GetResourceData()), "javacode-" + resource.Name, nextClassLoader)); }