/// <summary> /// Create app widget provider xml file. /// </summary> private void CreateAppWidgetProviderFile(string tempFolder, int index, CustomAttribute attr) { var resourceName = AppWidgetProviderResource.GetResourceName(index); var path = Path.Combine(Path.Combine(tempFolder, @"res\xml"), resourceName + ".xml"); var doc = new XDocument(); var root = new XElement("appwidget-provider"); doc.Add(root); root.AddAttrIfNotEmpty("minWidth", Namespace, attr.GetValue <string>("MinWidth")); root.AddAttrIfNotEmpty("minHeight", Namespace, attr.GetValue <string>("MinHeight")); root.AddAttrIfNotDefault("updatePeriodMillis", Namespace, attr.GetValue <long>("UpdatePeriod"), 0L); root.AddAttrIfNotEmpty("previewImage", Namespace, attr.GetValue <string>("PreviewImage"), FormatDrawable); root.AddAttrIfNotEmpty("initialLayout", Namespace, attr.GetValue <string>("InitialLayout"), FormatLayout); var configureActivityType = attr.GetValue <TypeReference>("ConfigureActivity"); if (configureActivityType != null) { var configureActivityTypeDef = configureActivityType.Resolve(); if (configureActivityTypeDef == null) { throw new ArgumentException("Cannot resolve " + configureActivityType.FullName); } root.AddAttr("configure", Namespace, FormatClassName(XBuilder.AsTypeDefinition(module, configureActivityTypeDef))); } root.AddAttrIfNotDefault("resizeMode", Namespace, attr.GetValue <int>("ResizeMode"), 0, widgetResizeModesOptions.Format); root.AddAttrIfNotDefault("widgetCategory", Namespace, attr.GetValue <int>("Category"), 0, widgetCategoriesOptions.Format); root.AddAttrIfNotEmpty("initialKeyguardLayout", Namespace, attr.GetValue <string>("InitialKeyguardLayout"), FormatLayout); Directory.CreateDirectory(Path.GetDirectoryName(path)); doc.Save(path); }
/// <summary> /// Create the supports-screens element /// </summary> private void CreateSupportsScreens(XElement manifest) { // Find supports-screens attribute var ssAttributes = assembly.GetAttributes(SupportsScreensAttribute).ToList(); if (ssAttributes.Count == 0) { return; } if (ssAttributes.Count > 1) { throw new ArgumentException("Multiple SupportsScreens attributes found"); } var attr = ssAttributes[0]; // Create supports-screens var supportsScreens = new XElement("supports-screens"); manifest.Add(supportsScreens); supportsScreens.AddAttrIfFound("smallScreens", Namespace, attr, "SmallScreens"); supportsScreens.AddAttrIfFound("normalScreens", Namespace, attr, "NormalScreens"); supportsScreens.AddAttrIfFound("largeScreens", Namespace, attr, "LargeScreens"); supportsScreens.AddAttrIfFound("xlargeScreens", Namespace, attr, "XLargeScreens"); supportsScreens.AddAttrIfNotDefault("requiresSmallestWidthDp", Namespace, attr.GetValue <int>("RequiresSmallestWidthDp"), 0, x => x.ToString()); supportsScreens.AddAttrIfNotDefault("compatibleWidthLimitDp", Namespace, attr.GetValue <int>("CompatibleWidthLimitDp"), 0, x => x.ToString()); supportsScreens.AddAttrIfNotDefault("largestWidthLimitDp", Namespace, attr.GetValue <int>("LargestWidthLimitDp"), 0, x => x.ToString()); }
/// <summary> /// Create the application element /// </summary> private void CreateApplication(Targets target, XElement manifest, string outputFolder) { // Find application attribute var appTuple = FindApplication(); var attr = appTuple.Item2; var label = attr.GetValue <string>(0, "Label"); if (string.IsNullOrEmpty(label)) { throw new ArgumentException(string.Format("No Label set in {0}", attr)); } var icon = attr.GetValue <string>("Icon"); if (string.IsNullOrEmpty(icon)) { // Select icon from activity var activityIcons = FindActivities().Select(x => x.Item2.GetValue <string>("Icon")).Where(x => !string.IsNullOrEmpty(x)); icon = activityIcons.FirstOrDefault(); } // Create application var application = new XElement("application"); manifest.Add(application); application.AddAttr("label", Namespace, FormatStringOrLiteral(label)); if (appTuple.Item1 != null) { var xType = XBuilder.AsTypeDefinition(module, appTuple.Item1); application.AddAttr("name", Namespace, FormatClassName(xType)); } application.AddAttrIfNotEmpty("icon", Namespace, icon, FormatDrawable); application.AddAttrIfNotEmpty("theme", Namespace, attr.GetValue <string>("Theme"), FormatStyle); application.AddAttrIfNotEmpty("description", Namespace, attr.GetValue <string>("Description")); application.AddAttrIfNotEmpty("logo", Namespace, attr.GetValue <string>("Logo"), FormatDrawable); application.AddAttrIfNotDefault("debuggable", Namespace, attr.GetValue <bool>("Debuggable", debuggable), false); application.AddAttrIfFound("enabled", Namespace, attr, "Enabled"); application.AddAttrIfNotDefault("persistent", Namespace, attr.GetValue <bool>("Persistent"), false); application.AddAttrIfFound("allowTaskReparenting", Namespace, attr, "AllowTaskReparenting"); application.AddAttrIfNotEmpty("backupAgent", Namespace, attr.GetValue <Type>("BackupAgent"), nsConverter.GetConvertedFullName); application.AddAttrIfFound("hardwareAccelerated", Namespace, attr, "HardwareAccelerated"); application.AddAttrIfFound("killAfterRestore", Namespace, attr, "KillAfterRestore"); application.AddAttrIfFound("largeHeap", Namespace, attr, "LargeHeap"); application.AddAttrIfNotEmpty("manageSpaceActivity", Namespace, attr.GetValue <Type>("ManageSpaceActivity"), nsConverter.GetConvertedFullName); application.AddAttrIfNotEmpty("process", Namespace, attr.GetValue <string>("Process")); application.AddAttrIfFound("restoreAnyVersion", Namespace, attr, "RestoreAnyVersion"); application.AddAttrIfNotEmpty("taskAffinity", Namespace, attr.GetValue <string>("TaskAffinity")); application.AddAttrIfNotDefault("uiOptions", Namespace, attr.GetValue <int>("UIOptions"), 0, uiOptions.Format); // Create child elements CreateActivity(application); CreateService(application); CreateReceiver(application); CreateAppWidgetProvider(application, outputFolder); CreateUsesLibrary(application); CreateProvider(application); CreateMetaData(application, assembly); // Must be last }
/// <summary> /// Create all activity elements /// </summary> private void CreateActivity(XElement application) { bool isFirst = true; // Create activities foreach (var tuple in FindActivities()) { var type = tuple.Item1; var xType = XBuilder.AsTypeDefinition(module, type); var attr = tuple.Item2; var activity = new XElement("activity"); application.Add(activity); activity.AddAttr("name", Namespace, FormatClassName(xType)); activity.AddAttrIfNotEmpty("label", Namespace, attr.GetValue <string>("Label"), FormatStringOrLiteral); activity.AddAttrIfNotEmpty("icon", Namespace, attr.GetValue <string>("Icon"), FormatDrawable); activity.AddAttrIfFound("allowTaskReparenting", Namespace, attr, "AllowTaskReparenting"); activity.AddAttrIfFound("alwaysRetainTaskState", Namespace, attr, "AlwaysRetainTaskState"); activity.AddAttrIfFound("clearTaskOnLaunch", Namespace, attr, "ClearTaskOnLaunch"); activity.AddAttrIfNotDefault("configChanges", Namespace, attr.GetValue <int>("ConfigChanges"), 0, configChangesOptions.Format); activity.AddAttrIfFound("enabled", Namespace, attr, "Enabled"); activity.AddAttrIfFound("excludeFromRecents", Namespace, attr, "ExcludeFromRecents"); activity.AddAttrIfFound("exported", Namespace, attr, "Exported"); activity.AddAttrIfFound("finishOnTaskLaunch", Namespace, attr, "FinishOnTaskLaunch"); activity.AddAttrIfFound("hardwareAccelerated", Namespace, attr, "HardwareAccelerated"); activity.AddAttrIfNotDefault("launchMode", Namespace, attr.GetValue <int>("LaunchMode"), 0, launchModesOptions.Format); activity.AddAttrIfFound("multiprocess", Namespace, attr, "MultiProcess"); activity.AddAttrIfFound("noHistory", Namespace, attr, "NoHistory"); activity.AddAttrIfNotEmpty("parentActivityName", Namespace, attr.GetValue <Type>("ParentActivity"), nsConverter.GetConvertedFullName); activity.AddAttrIfNotEmpty("permission", Namespace, attr.GetValue <string>("Permission")); activity.AddAttrIfNotEmpty("process", Namespace, attr.GetValue <string>("Process")); activity.AddAttrIfNotDefault("screenOrientation", Namespace, attr.GetValue <int>("ScreenOrientation"), 0, screenOrientationsOptions.Format); activity.AddAttrIfFound("stateNotNeeded", Namespace, attr, "StateNotNeeded"); activity.AddAttrIfNotEmpty("taskAffinity", Namespace, attr.GetValue <string>("TaskAffinity")); activity.AddAttrIfNotEmpty("theme", Namespace, attr.GetValue <string>("Theme"), FormatStyle); activity.AddAttrIfNotDefault("uiOptions", Namespace, attr.GetValue <int>("UIOptions"), 0, uiOptions.Format); activity.AddAttrIfNotDefault("windowSoftInputMode", Namespace, attr.GetValue <int>("WindowSoftInputMode"), 0, windowSoftInputModeOptions.Format); var visibleInLauncher = isFirst || attr.GetValue("VisibleInLauncher", false) || attr.GetValue("MainLauncher", false); CreateIntentFilter(activity, type, visibleInLauncher, false); CreateMetaData(activity, type); isFirst = false; } }
/// <summary> /// Create all uses-library elements /// </summary> private void CreateUsesLibrary(XElement application) { // Collect all attributes var libraries = new Dictionary <string, bool>(); foreach (var attr in assembly.GetAttributesFromAllAssemblies(UsesLibraryAttribute)) { var name = attr.GetValue <string>(0, "Name"); var required = attr.GetValue(1, "Required", true); if (!libraries.ContainsKey(name) || required) { libraries[name] = required; } } // Create XML foreach (var entry in libraries) { var name = entry.Key; var required = entry.Value; var element = new XElement("uses-library"); element.AddAttr("name", Namespace, name); element.AddAttrIfNotDefault("required", Namespace, required, true); application.Add(element); } }
/// <summary> /// Create all instrumentation elements /// </summary> private void CreateInstrumentation(XElement manifest) { foreach (var attr in assembly.GetAttributes(InstrumentationAttribute)) { var name = attr.GetValue(-1, "Name", "android.test.InstrumentationTestRunner"); var functionalTest = attr.GetValue(-1, "FunctionalTest", false); var handleProfiling = attr.GetValue(-1, "HandleProfiling", false); var label = attr.GetValue <string>(-1, "Label"); var targetPackage = attr.GetValue(-1, "TargetPackage", packageName); var element = new XElement("instrumentation"); element.Add(new XAttribute(XName.Get("name", Namespace), name)); element.AddAttrIfNotDefault("functionalTest", Namespace, functionalTest, false); element.AddAttrIfNotDefault("handleProfiling", Namespace, handleProfiling, false); element.AddAttrIfNotEmpty("label", Namespace, label); element.AddAttrIfNotEmpty("targetPackage", Namespace, targetPackage); manifest.Add(element); } }
/// <summary> /// Compile the given XML file to a binary XML file in the given output folder. /// </summary> private void CreateManifest(Targets target, string outputFolder) { #if DEBUG //Debugger.Launch(); #endif var pkgAttributes = assembly.GetAttributes(PackageAttribute).ToList(); if (pkgAttributes.Count > 1) { throw new ArgumentException("Multiple Package attributes found"); } var pkgAttr = pkgAttributes.FirstOrDefault(); // Create xml root var doc = new XDocument(); var manifest = new XElement("manifest"); manifest.Add(new XAttribute(XNamespace.Xmlns + "android", XNamespace.Get(Namespace))); doc.Add(manifest); // Create uses-sdk CreateUsesSdk(manifest, pkgAttr); // Set attributes manifest.Add(new XAttribute(XName.Get("package"), packageName)); var version = assembly.Name.Version; var versionCode = (pkgAttr != null) ? pkgAttr.GetValue("VersionCode", version.Major) : version.Major; manifest.Add(new XAttribute(XName.Get("versionCode", Namespace), versionCode)); var versionName = (pkgAttr != null) ? pkgAttr.GetValue("VersionName", version.ToString()) : version.ToString(); manifest.Add(new XAttribute(XName.Get("versionName", Namespace), versionName)); // Set additional attributes if (pkgAttr != null) { manifest.AddAttrIfNotEmpty("sharedUserId", Namespace, pkgAttr.GetValue <string>("SharedUserId")); manifest.AddAttrIfNotEmpty("sharedUserLabel", Namespace, pkgAttr.GetValue <string>("SharedUserLabel"), FormatString); manifest.AddAttrIfNotDefault("installLocation", Namespace, pkgAttr.GetValue <int>("InstallLocation"), 0, installLocationsOptions.Format); } // Create child elements CreateApplication(target, manifest, outputFolder); CreateInstrumentation(manifest); CreatePermission(manifest); CreatePermissionGroup(manifest); CreateSupportsScreens(manifest); CreateUsesFeature(manifest); CreateUsesPermission(manifest); // Save if (!Directory.Exists(outputFolder)) { Directory.CreateDirectory(outputFolder); } doc.Save(Path.Combine(outputFolder, "AndroidManifest.xml")); }
/// <summary> /// Create all uses-feature elements /// </summary> private void CreateUsesFeature(XElement manifest) { // Collect all attributes var features = new Dictionary <string, bool>(); foreach (var attr in assembly.GetAttributesFromAllAssemblies(UsesFeatureAttribute)) { var name = attr.GetValue <string>(0, "Name"); var required = attr.GetValue(1, "Required", true); if (!features.ContainsKey(name) || required) { features[name] = required; } } // Generate uses-feature elements foreach (var entry in features) { var name = entry.Key; var required = entry.Value; var element = new XElement("uses-feature"); element.AddAttr("name", Namespace, name); element.AddAttrIfNotDefault("required", Namespace, required, true); manifest.Add(element); } // Collect opengl version var maxVersion = -1; var hasVersion = false; foreach (var attr in assembly.GetAttributesFromAllAssemblies(UsesOpenGLAttribute)) { var version = attr.GetValue <int>(0, "Version"); maxVersion = Math.Max(maxVersion, version); hasVersion = true; } // Generate uses-feature element if (hasVersion) { var element = new XElement("uses-feature"); element.AddAttr("glEsVersion", Namespace, maxVersion.ToString()); manifest.Add(element); } }
/// <summary> /// Create all permission elements /// </summary> private void CreatePermission(XElement manifest) { // Create services foreach (var attr in assembly.GetAttributes(PermissionAttribute)) { var permission = new XElement("permission"); manifest.Add(permission); permission.AddAttr("name", Namespace, attr.GetValue <string>(0, "Name")); permission.AddAttrIfNotEmpty("label", Namespace, attr.GetValue <string>("Label"), FormatStringOrLiteral); permission.AddAttrIfNotEmpty("description", Namespace, attr.GetValue <string>("Description"), FormatString); permission.AddAttrIfNotEmpty("icon", Namespace, attr.GetValue <string>("Icon"), FormatDrawable); permission.AddAttrIfNotEmpty("permissionGroup", Namespace, attr.GetValue <string>("PermissionGroup")); permission.AddAttrIfNotDefault("protectionLevel", Namespace, attr.GetValue <int>("ProtectionLevel"), 0, protectionLevelsOptions.Format); } }