示例#1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        protected override bool ValidateParameters()
        {
            //
            // This tool should really only expect 'AndroidManifest.xml' input. But people might change the names of these, so we can't rely on that to validate.
            //

            bool validParameters = true;

            if (Sources.Length != 1)
            {
                Log.LogError("Expected single input, got: " + Sources.Length + "'.");

                validParameters = false;
            }

            if (validParameters)
            {
                string sourcePath = Path.GetFullPath(Sources [0].GetMetadata("FullPath"));

                if (string.IsNullOrEmpty(sourcePath) || !File.Exists(sourcePath))
                {
                    Log.LogError("Could locate expected input: '" + sourcePath + "'.");

                    validParameters = false;
                }

                try
                {
                    if (validParameters)
                    {
                        AndroidManifestDocument sourceManifest = new AndroidManifestDocument();

                        sourceManifest.Load(sourcePath);
                    }
                }
                catch (Exception e)
                {
                    Log.LogError("Could not successfully parse '" + sourcePath + "'. Check this is a valid AndroidManifest.xml document. Reason: " + e, MessageImportance.High);

                    Log.LogErrorFromException(e, true);

                    validParameters = false;
                }
            }

            return(validParameters && base.ValidateParameters());
        }
示例#2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        protected override int TrackedExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
        {
            //
            // Use default implementation, but ensure that any generated sources and dependency files get flagged as output appropriately.
            //

            int retCode = -1;

            Dictionary <string, ITaskItem> processedManifestFiles = new Dictionary <string, ITaskItem> ();

            List <ITaskItem> outputApkFileList = new List <ITaskItem> ();

            List <ITaskItem> outputFilesList = new List <ITaskItem> ();

            try
            {
                foreach (ITaskItem source in Sources)
                {
                    string sourcePath = Path.GetFullPath(source.GetMetadata("FullPath"));

                    if (!processedManifestFiles.ContainsKey(sourcePath))
                    {
                        retCode = base.TrackedExecuteTool(pathToTool, responseFileCommands, commandLineCommands);

                        processedManifestFiles.Add(sourcePath, source);

                        if (retCode == 0)
                        {
                            AndroidManifestDocument sourceManifest = new AndroidManifestDocument();

                            sourceManifest.Load(sourcePath);

                            //
                            // Determine if this manifest requested APK generation, add to output list.
                            //

                            if (!string.IsNullOrWhiteSpace(source.GetMetadata("ApkOutputFile")))
                            {
                                string apkOutputFile = source.GetMetadata("ApkOutputFile");

                                if (!File.Exists(apkOutputFile))
                                {
                                    throw new FileNotFoundException("Requested APK output file does not exist. Error during packaging?");
                                }

                                ITaskItem outputApkItem = new TaskItem(Path.GetFullPath(apkOutputFile));

                                outputApkFileList.Add(outputApkItem);

                                outputFilesList.Add(outputApkItem);
                            }


                            if (source.GetMetadata("GenerateDependencies") == "true")
                            {
                                //
                                // Evaluate which resource constant source files have been exported. 'ExtraPackages' lists additional package names that also have resource ids.
                                //

                                List <string> resourceConstantSourceFiles = new List <string> ();

                                string resourcesDirectory = source.GetMetadata("ResourceConstantsOutputDirectory");

                                if (File.Exists(Path.Combine(resourcesDirectory, "R.java")))
                                {
                                    resourceConstantSourceFiles.Add(Path.Combine(resourcesDirectory, "R.java"));
                                }

                                if (File.Exists(Path.Combine(resourcesDirectory, sourceManifest.PackageName.Replace('.', '\\'), "R.java")))
                                {
                                    resourceConstantSourceFiles.Add(Path.Combine(resourcesDirectory, sourceManifest.PackageName.Replace('.', '\\'), "R.java"));
                                }

                                if (!string.IsNullOrWhiteSpace(source.GetMetadata("ExtraPackages")))
                                {
                                    string [] extraPackages = source.GetMetadata("ExtraPackages").Split(':');

                                    foreach (string package in extraPackages)
                                    {
                                        if (File.Exists(Path.Combine(resourcesDirectory, package.Replace('.', '\\'), "R.java")))
                                        {
                                            resourceConstantSourceFiles.Add(Path.Combine(resourcesDirectory, package.Replace('.', '\\'), "R.java"));
                                        }
                                    }
                                }

                                //
                                // When exporting an APK the R.java.d file will not properly list dependencies. Copy from ??.apk.d to solve this.
                                //

                                string dependencyFileSource = Path.Combine(resourcesDirectory, "R.java.d");

                                if (!string.IsNullOrWhiteSpace(source.GetMetadata("ApkOutputFile")))
                                {
                                    string apkDependencyFileSource = source.GetMetadata("ApkOutputFile") + ".d";

                                    GccUtilities.DependencyParser.ConvertJavaDependencyFileToGcc(apkDependencyFileSource);

                                    File.Copy(apkDependencyFileSource, dependencyFileSource, true); // overwrite invalid R.java.d export
                                }

                                //
                                // R.java.d dependency files are not placed alongside its master file if exported using package directories. Fix this.
                                //

                                foreach (string master in resourceConstantSourceFiles)
                                {
                                    string masterDependencyFile = master + ".d";

                                    Directory.CreateDirectory(Path.GetDirectoryName(masterDependencyFile));

                                    if (File.Exists(masterDependencyFile))
                                    {
                                        File.Delete(masterDependencyFile);
                                    }

                                    File.Copy(dependencyFileSource, masterDependencyFile);
                                }

                                //
                                // Finally ensure all resource constant export files are added to the output list.
                                //

                                foreach (string file in resourceConstantSourceFiles)
                                {
                                    ITaskItem outputResourceFileItem = new TaskItem(Path.GetFullPath(file));

                                    outputFilesList.Add(outputResourceFileItem);
                                }
                            }

                            if (retCode != 0)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.LogErrorFromException(e, true);

                retCode = -1;
            }
            finally
            {
                OutputApk = outputApkFileList.ToArray();

                OutputFiles = outputFilesList.ToArray();
            }

            return(retCode);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override bool Execute()
        {
            try
            {
                if (PrimaryManifest.Length == 0)
                {
                    Log.LogError("No 'PrimaryManifest' file(s) specified.");

                    return(false);
                }

                if (PrimaryManifest.Length > 1)
                {
                    Log.LogError("Too many 'PrimaryManifest' files specified. Expected one.");

                    return(false);
                }

                if (ProjectManifests.Length == 0)
                {
                    Log.LogError("No 'ProjectManifests' file(s) specified.");

                    return(false);
                }

                //
                // Identify which is the primary AndroidManifest.xml provided.
                //

                MergedManifest = null;

                string primaryManifestFullPath = PrimaryManifest [0].GetMetadata("FullPath");

                foreach (ITaskItem manifestItem in ProjectManifests)
                {
                    string manifestItemFullPath = manifestItem.GetMetadata("FullPath");

                    if (primaryManifestFullPath.Equals(manifestItemFullPath))
                    {
                        MergedManifest = manifestItem;

                        break;
                    }
                }

                if (MergedManifest == null)
                {
                    Log.LogError("Could not find 'primary' manifest in provided list of project manifests. Expected: " + primaryManifestFullPath);

                    return(false);
                }

                //
                // Sanity check all manifests to ensure that there's not another which defines <application> that's not 'primary'.
                //

                ITaskItem applicationManifest = null;

                foreach (ITaskItem manifestItem in ProjectManifests)
                {
                    AndroidManifestDocument androidManifestDocument = new AndroidManifestDocument();

                    androidManifestDocument.Load(manifestItem.GetMetadata("FullPath"));

                    if (androidManifestDocument.IsApplication)
                    {
                        if (applicationManifest == null)
                        {
                            applicationManifest = manifestItem;

                            break;
                        }
                        else
                        {
                            Log.LogError("Found multiple AndroidManifest files which define an <application> node.");

                            return(false);
                        }
                    }
                }

                if ((applicationManifest != null) && (applicationManifest != MergedManifest))
                {
                    Log.LogError("Specified project manifest does not define an <application> node.");

                    return(false);
                }

                //
                // Process other 'third-party' manifests merging required metadata.
                //

                if (MergedManifest != null)
                {
                    HashSet <string> extraPackages = new HashSet <string> ();

                    HashSet <string> extraResourcePaths = new HashSet <string> ();

                    extraResourcePaths.Add(MergedManifest.GetMetadata("IncludeResourceDirectories"));

                    foreach (ITaskItem item in ProjectManifests)
                    {
                        AndroidManifestDocument androidManifestDocument = new AndroidManifestDocument();

                        androidManifestDocument.Load(item.GetMetadata("FullPath"));

                        if (item == MergedManifest)
                        {
                            PackageName = androidManifestDocument.PackageName;
                        }
                        else
                        {
                            if (!extraPackages.Contains(androidManifestDocument.PackageName))
                            {
                                extraPackages.Add(androidManifestDocument.PackageName);
                            }

                            if (!extraResourcePaths.Contains(item.GetMetadata("IncludeResourceDirectories")))
                            {
                                extraResourcePaths.Add(item.GetMetadata("IncludeResourceDirectories"));
                            }
                        }
                    }

                    MergedManifest.SetMetadata("ExtraPackages", String.Join(":", extraPackages.ToArray()));

                    MergedManifest.SetMetadata("IncludeResourceDirectories", String.Join(";", extraResourcePaths.ToArray()));

                    return(true);
                }
            }
            catch (Exception e)
            {
                Log.LogErrorFromException(e, true);
            }

            return(false);
        }