Example #1
0
        public void VersionCodeTests(bool seperateApk, string abis, string versionCode, string versionCodePattern, string versionCodeProperties, bool shouldBuild, string expectedVersionCode)
        {
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            proj.SetProperty("Foo", "1");
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, seperateApk);
            if (!string.IsNullOrEmpty(abis))
            {
                proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidSupportedAbis, abis);
            }
            if (!string.IsNullOrEmpty(versionCodePattern))
            {
                proj.SetProperty(proj.ReleaseProperties, "AndroidVersionCodePattern", versionCodePattern);
            }
            else
            {
                proj.RemoveProperty(proj.ReleaseProperties, "AndroidVersionCodePattern");
            }
            if (!string.IsNullOrEmpty(versionCodeProperties))
            {
                proj.SetProperty(proj.ReleaseProperties, "AndroidVersionCodeProperties", versionCodeProperties);
            }
            else
            {
                proj.RemoveProperty(proj.ReleaseProperties, "AndroidVersionCodeProperties");
            }
            proj.AndroidManifest = proj.AndroidManifest.Replace("android:versionCode=\"1\"", $"android:versionCode=\"{versionCode}\"");
            using (var builder = CreateApkBuilder(Path.Combine("temp", "VersionCodeTests"), false, false)) {
                builder.ThrowOnBuildFailure = false;
                Assert.AreEqual(shouldBuild, builder.Build(proj), shouldBuild ? "Build should have succeeded." : "Build should have failed.");
                if (!shouldBuild)
                {
                    return;
                }
                var        abiItems      = seperateApk ? abis.Split(';') : new string[1];
                var        expectedItems = expectedVersionCode.Split(';');
                XNamespace aNS           = "http://schemas.android.com/apk/res/android";
                Assert.AreEqual(abiItems.Length, expectedItems.Length, "abis parameter should have matching elements for expected");
                for (int i = 0; i < abiItems.Length; i++)
                {
                    var path       = seperateApk ? Path.Combine("android", abiItems[i], "AndroidManifest.xml") : Path.Combine("android", "manifest", "AndroidManifest.xml");
                    var manifest   = builder.Output.GetIntermediaryAsText(Root, path);
                    var doc        = XDocument.Parse(manifest);
                    var nsResolver = new XmlNamespaceManager(new NameTable());
                    nsResolver.AddNamespace("android", "http://schemas.android.com/apk/res/android");
                    var m = doc.XPathSelectElement("/manifest") as XElement;
                    Assert.IsNotNull(m, "no manifest element found");
                    var vc = m.Attribute(aNS + "versionCode");
                    Assert.IsNotNull(vc, "no versionCode attribute found");
                    StringAssert.AreEqualIgnoringCase(expectedItems[i], vc.Value,
                                                      $"Version Code is incorrect. Found {vc.Value} expect {expectedItems[i]}");
                }
            }
        }
Example #2
0
        public void CheckSignApk([Values(true, false)] bool useApkSigner, [Values(true, false)] bool perAbiApk)
        {
            string ext            = Environment.OSVersion.Platform != PlatformID.Unix ? ".bat" : "";
            var    foundApkSigner = Directory.EnumerateDirectories(Path.Combine(AndroidSdkPath, "build-tools")).Any(dir => Directory.EnumerateFiles(dir, "apksigner" + ext).Any());

            if (useApkSigner && !foundApkSigner)
            {
                Assert.Ignore("Skipping test. Required build-tools verison which contains apksigner is not installed.");
            }
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            if (useApkSigner)
            {
                proj.SetProperty("AndroidUseApkSigner", "true");
            }
            else
            {
                proj.RemoveProperty("AndroidUseApkSigner");
            }
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, perAbiApk);
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidSupportedAbis, "armeabi-v7a;x86");
            using (var b = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                b.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Diagnostic;
                Assert.IsTrue(b.Build(proj), "build failed");
                proj.AndroidResources.First().Timestamp = null;
                Assert.IsTrue(b.Build(proj), "Second build failed");
            }
        }
Example #3
0
        public void CheckSignApk([Values(true, false)] bool useApkSigner)
        {
            string ext = Environment.OSVersion.Platform != PlatformID.Unix ? ".exe" : "";

            if (useApkSigner && !File.Exists(Path.Combine(AndroidSdkPath, "build-tools", "26.0.1", "apksigner" + ext)))
            {
                Assert.Ignore("Skipping test. Required build-tools verison 26.0.1 is not installed.");
            }
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            if (useApkSigner)
            {
                proj.SetProperty("AndroidUseApkSigner", "true");
                proj.SetProperty("AndroidSdkBuildToolsVersion", "26.0.1");
            }
            else
            {
                proj.RemoveProperty("AndroidUseApkSigner");
            }
            using (var b = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                b.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Diagnostic;
                Assert.IsTrue(b.Build(proj), "build failed");
            }
        }
        public void CheckSignApk([Values(true, false)] bool useApkSigner, [Values(true, false)] bool perAbiApk)
        {
            string ext            = Environment.OSVersion.Platform != PlatformID.Unix ? ".bat" : "";
            var    foundApkSigner = Directory.EnumerateDirectories(Path.Combine(AndroidSdkPath, "build-tools")).Any(dir => Directory.EnumerateFiles(dir, "apksigner" + ext).Any());

            if (useApkSigner && !foundApkSigner)
            {
                Assert.Ignore("Skipping test. Required build-tools verison which contains apksigner is not installed.");
            }
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            if (useApkSigner)
            {
                proj.SetProperty("AndroidUseApkSigner", "true");
            }
            else
            {
                proj.RemoveProperty("AndroidUseApkSigner");
            }
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, perAbiApk);
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidSupportedAbis, "armeabi-v7a;x86");
            using (var b = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                var bin = Path.Combine(Root, b.ProjectDirectory, proj.OutputPath);
                Assert.IsTrue(b.Build(proj), "First build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"),
                              "First build should not contain warnings!  Contains\n" +
                              string.Join("\n", b.LastBuildOutput.Where(line => line.Contains("warning"))));

                //Make sure the APKs are signed
                foreach (var apk in Directory.GetFiles(bin, "*-Signed.apk"))
                {
                    using (var zip = ZipHelper.OpenZip(apk)) {
                        Assert.IsTrue(zip.Any(e => e.FullName == "META-INF/MANIFEST.MF"), $"APK file `{apk}` is not signed! It is missing `META-INF/MANIFEST.MF`.");
                    }
                }

                var item = proj.AndroidResources.First(x => x.Include() == "Resources\\values\\Strings.xml");
                item.TextContent = () => proj.StringsXml.Replace("${PROJECT_NAME}", "Foo");
                item.Timestamp   = null;
                Assert.IsTrue(b.Build(proj), "Second build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"),
                              "Second build should not contain warnings!  Contains\n" +
                              string.Join("\n", b.LastBuildOutput.Where(line => line.Contains("warning"))));

                //Make sure the APKs are signed
                foreach (var apk in Directory.GetFiles(bin, "*-Signed.apk"))
                {
                    using (var zip = ZipHelper.OpenZip(apk)) {
                        Assert.IsTrue(zip.Any(e => e.FullName == "META-INF/MANIFEST.MF"), $"APK file `{apk}` is not signed! It is missing `META-INF/MANIFEST.MF`.");
                    }
                }
            }
        }
        public void InstallWithoutSharedRuntime()
        {
            AssertCommercialBuild();
            AssertHasDevices();

            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            proj.SetProperty(proj.ReleaseProperties, "Optimize", false);
            proj.SetProperty(proj.ReleaseProperties, "DebugType", "none");
            if (Builder.UseDotNet)
            {
                // NOTE: in .NET 6, EmbedAssembliesIntoApk=true by default for Release builds
                proj.SetProperty(proj.ReleaseProperties, "EmbedAssembliesIntoApk", "false");
            }
            else
            {
                proj.RemoveProperty(proj.ReleaseProperties, "EmbedAssembliesIntoApk");
            }
            var abis = new [] { "armeabi-v7a", "x86" };

            proj.SetAndroidSupportedAbis(abis);
            using (var builder = CreateApkBuilder()) {
                if (RunAdbCommand("shell pm list packages Mono.Android.DebugRuntime").Trim().Length != 0)
                {
                    RunAdbCommand("uninstall Mono.Android.DebugRuntime");
                }
                Assert.IsTrue(builder.Install(proj));
                var runtimeInfo = builder.GetSupportedRuntimes();
                var apkPath     = Path.Combine(Root, builder.ProjectDirectory,
                                               proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
                using (var apk = ZipHelper.OpenZip(apkPath)) {
                    foreach (var abi in abis)
                    {
                        var runtime = runtimeInfo.FirstOrDefault(x => x.Abi == abi && x.Runtime == "debug");
                        Assert.IsNotNull(runtime, "Could not find the expected runtime.");
                        var inApk        = ZipHelper.ReadFileFromZip(apk, String.Format("lib/{0}/{1}", abi, runtime.Name));
                        var inApkRuntime = runtimeInfo.FirstOrDefault(x => x.Abi == abi && x.Size == inApk.Length);
                        Assert.IsNotNull(inApkRuntime, "Could not find the actual runtime used.");
                        Assert.AreEqual(runtime.Size, inApkRuntime.Size, "expected {0} got {1}", "debug", inApkRuntime.Runtime);
                    }
                }
                //FIXME: https://github.com/xamarin/androidtools/issues/141
                //Assert.AreEqual (0, RunAdbCommand ("shell pm list packages Mono.Android.DebugRuntime").Trim ().Length,
                //	"The Shared Runtime should not have been installed.");
                var directorylist = GetContentFromAllOverrideDirectories(proj.PackageName);
                StringAssert.Contains($"{proj.ProjectName}.dll", directorylist, $"{proj.ProjectName}.dll should exist in the .__override__ directory.");
                StringAssert.Contains($"System.dll", directorylist, $"System.dll should exist in the .__override__ directory.");
                StringAssert.Contains($"Mono.Android.dll", directorylist, $"Mono.Android.dll should exist in the .__override__ directory.");
                Assert.IsTrue(builder.Uninstall(proj), "unnstall should have succeeded.");
            }
        }
Example #6
0
        public void InstallWithoutSharedRuntime()
        {
            AssertCommercialBuild();
            AssertHasDevices();

            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            proj.SetProperty(proj.ReleaseProperties, "Optimize", false);
            proj.SetProperty(proj.ReleaseProperties, "DebugType", "none");
            proj.SetProperty(proj.ReleaseProperties, "AndroidUseSharedRuntime", false);
            proj.RemoveProperty(proj.ReleaseProperties, "EmbedAssembliesIntoApk");
            var abis = new [] { "armeabi-v7a", "x86" };

            proj.SetAndroidSupportedAbis(abis);
            using (var builder = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name), false, false)) {
                builder.Verbosity = LoggerVerbosity.Diagnostic;
                if (RunAdbCommand("shell pm list packages Mono.Android.DebugRuntime").Trim().Length != 0)
                {
                    RunAdbCommand("uninstall Mono.Android.DebugRuntime");
                }
                Assert.IsTrue(builder.Install(proj));
                var runtimeInfo = builder.GetSupportedRuntimes();
                var apkPath     = Path.Combine(Root, builder.ProjectDirectory,
                                               proj.IntermediateOutputPath, "android", "bin", "UnnamedProject.UnnamedProject.apk");
                using (var apk = ZipHelper.OpenZip(apkPath)) {
                    foreach (var abi in abis)
                    {
                        var runtime = runtimeInfo.FirstOrDefault(x => x.Abi == abi && x.Runtime == "debug");
                        Assert.IsNotNull(runtime, "Could not find the expected runtime.");
                        var inApk        = ZipHelper.ReadFileFromZip(apk, String.Format("lib/{0}/{1}", abi, runtime.Name));
                        var inApkRuntime = runtimeInfo.FirstOrDefault(x => x.Abi == abi && x.Size == inApk.Length);
                        Assert.IsNotNull(inApkRuntime, "Could not find the actual runtime used.");
                        Assert.AreEqual(runtime.Size, inApkRuntime.Size, "expected {0} got {1}", "debug", inApkRuntime.Runtime);
                    }
                }
                //FIXME: https://github.com/xamarin/androidtools/issues/141
                //Assert.AreEqual (0, RunAdbCommand ("shell pm list packages Mono.Android.DebugRuntime").Trim ().Length,
                //	"The Shared Runtime should not have been installed.");
                var overrideDirs = new string [] {
                    $"/data/data/{proj.PackageName}/files/.__override__",
                    $"/storage/emulated/0/Android/data/{proj.PackageName}/files/.__override__",
                    $"/mnt/shell/emulated/0/Android/data/{proj.PackageName}/files/.__override__",
                    $"/storage/sdcard/Android/data/{proj.PackageName}/files/.__override__",
                };
                var directorylist = string.Empty;
                foreach (var dir in overrideDirs)
                {
                    var listing = RunAdbCommand($"shell ls {dir}");
                    if (!listing.Contains("No such file or directory"))
                    {
                        directorylist += listing;
                    }
                }
                StringAssert.Contains($"{proj.ProjectName}.dll", directorylist, $"{proj.ProjectName}.dll should exist in the .__override__ directory.");
                StringAssert.Contains($"System.dll", directorylist, $"System.dll should exist in the .__override__ directory.");
                StringAssert.Contains($"Mono.Android.dll", directorylist, $"Mono.Android.dll should exist in the .__override__ directory.");
            }
        }
        public void CheckSignApk([Values(true, false)] bool useApkSigner, [Values(true, false)] bool perAbiApk)
        {
            string ext            = Environment.OSVersion.Platform != PlatformID.Unix ? ".bat" : "";
            var    foundApkSigner = Directory.EnumerateDirectories(Path.Combine(AndroidSdkPath, "build-tools")).Any(dir => Directory.EnumerateFiles(dir, "apksigner" + ext).Any());

            if (useApkSigner && !foundApkSigner)
            {
                Assert.Ignore("Skipping test. Required build-tools verison which contains apksigner is not installed.");
            }
            string keyfile = Path.Combine(Root, "temp", TestName, "release.keystore");

            if (File.Exists(keyfile))
            {
                File.Delete(keyfile);
            }
            var androidSdk     = new AndroidSdkInfo((level, message) => {
            }, AndroidSdkPath, AndroidNdkPath);
            string keyToolPath = Path.Combine(androidSdk.JavaSdkPath, "bin");
            var    engine      = new MockBuildEngine(Console.Out);
            string pass        = "******";
            var    task        = new AndroidCreateDebugKey {
                BuildEngine  = engine,
                KeyStore     = keyfile,
                StorePass    = pass,
                KeyAlias     = "releasestore",
                KeyPass      = pass,
                KeyAlgorithm = "RSA",
                Validity     = 30,
                StoreType    = "pkcs12",
                Command      = "-genkeypair",
                ToolPath     = keyToolPath,
            };

            Assert.IsTrue(task.Execute(), "Task should have succeeded.");
            var proj = new XamarinAndroidApplicationProject()
            {
                IsRelease = true,
            };

            if (useApkSigner)
            {
                proj.SetProperty("AndroidUseApkSigner", "true");
            }
            else
            {
                proj.RemoveProperty("AndroidUseApkSigner");
            }
            proj.SetProperty(proj.ReleaseProperties, "AndroidKeyStore", "True");
            proj.SetProperty(proj.ReleaseProperties, "AndroidSigningKeyStore", keyfile);
            proj.SetProperty(proj.ReleaseProperties, "AndroidSigningKeyAlias", "releasestore");
            proj.SetProperty(proj.ReleaseProperties, "AndroidSigningKeyPass", pass);
            proj.SetProperty(proj.ReleaseProperties, "AndroidSigningStorePass", pass);
            proj.SetProperty(proj.ReleaseProperties, KnownProperties.AndroidCreatePackagePerAbi, perAbiApk);
            proj.SetAndroidSupportedAbis("armeabi-v7a", "x86");
            using (var b = CreateApkBuilder(Path.Combine("temp", TestContext.CurrentContext.Test.Name))) {
                var bin = Path.Combine(Root, b.ProjectDirectory, proj.OutputPath);
                Assert.IsTrue(b.Build(proj), "First build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"),
                              "First build should not contain warnings!  Contains\n" +
                              string.Join("\n", b.LastBuildOutput.Where(line => line.Contains("warning"))));

                //Make sure the APKs are signed
                foreach (var apk in Directory.GetFiles(bin, "*-Signed.apk"))
                {
                    using (var zip = ZipHelper.OpenZip(apk)) {
                        Assert.IsTrue(zip.Any(e => e.FullName == "META-INF/MANIFEST.MF"), $"APK file `{apk}` is not signed! It is missing `META-INF/MANIFEST.MF`.");
                    }
                }

                var item = proj.AndroidResources.First(x => x.Include() == "Resources\\values\\Strings.xml");
                item.TextContent = () => proj.StringsXml.Replace("${PROJECT_NAME}", "Foo");
                item.Timestamp   = null;
                Assert.IsTrue(b.Build(proj), "Second build failed");
                Assert.IsTrue(StringAssertEx.ContainsText(b.LastBuildOutput, " 0 Warning(s)"),
                              "Second build should not contain warnings!  Contains\n" +
                              string.Join("\n", b.LastBuildOutput.Where(line => line.Contains("warning"))));

                //Make sure the APKs are signed
                foreach (var apk in Directory.GetFiles(bin, "*-Signed.apk"))
                {
                    using (var zip = ZipHelper.OpenZip(apk)) {
                        Assert.IsTrue(zip.Any(e => e.FullName == "META-INF/MANIFEST.MF"), $"APK file `{apk}` is not signed! It is missing `META-INF/MANIFEST.MF`.");
                    }
                }
            }
        }