From 7a23efd37f8319d280bbd0c804ae65381816b5a7 Mon Sep 17 00:00:00 2001 From: Volker Leck Date: Thu, 5 Nov 2015 17:24:39 +0100 Subject: [PATCH] move launchabelActivity detection to Run task, add memoization for deviceId detection --- .../com/novoda/gradle/command/AdbTask.groovy | 66 +++---------------- .../AndroidCommandPluginExtension.groovy | 3 + .../com/novoda/gradle/command/Run.groovy | 51 ++++++++++++++ 3 files changed, 64 insertions(+), 56 deletions(-) diff --git a/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/AdbTask.groovy b/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/AdbTask.groovy index 64f1464..d6ac2aa 100644 --- a/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/AdbTask.groovy +++ b/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/AdbTask.groovy @@ -1,5 +1,7 @@ package com.novoda.gradle.command +import groovy.transform.Memoized + public class AdbTask extends org.gradle.api.DefaultTask { @@ -13,6 +15,7 @@ public class AdbTask extends org.gradle.api.DefaultTask { def deviceId + @Memoized def getDeviceId() { if (deviceId instanceof Closure) deviceId = deviceId.call() @@ -31,55 +34,6 @@ public class AdbTask extends org.gradle.api.DefaultTask { } } - def getLaunchableActivity() { - def output = readApkProperty('launchable-activity') - if (output) { - def matcher = output.readLines()[0] =~ /name='(.*?)'/ - if (matcher) { - matcher[0][1] - } - } else { - // Fall back to manually parsing aapt's pseudo-XML output to support activity aliases, see - // https://code.google.com/p/android/issues/detail?id=157150 - logger.info 'no launchable-activity found, falling back to parsing the manifest' - - output = [pluginEx.aapt, 'dump', 'xmltree', apkPath, 'AndroidManifest.xml'].execute().text - - def it = output.readLines().iterator() - def nextLine = null - - // Look for activity alias definitions. - while (it.hasNext()) { - def line = nextLine ?: it.next() - nextLine = null - - def matcher = line =~ /(\s+)(E: activity-alias)(.*)/ - if (matcher) { - def intentation = matcher[0][1] + ' ' - def name = null, main = false, launcher = false, disabled = false - - // Parse the indented block for the current activity alias. - while (it.hasNext() && (nextLine = it.next()).startsWith(intentation)) { - matcher = nextLine =~ /A: android:name.*="([^"]+)"/ - if (matcher && !name) { - name = matcher[0][1] - } - main = main || nextLine.contains('android.intent.action.MAIN') - launcher = launcher || nextLine.contains('android.intent.category.LAUNCHER') - - // Exclude disabled entries. - disabled = disabled || nextLine ==~ /^(\s+)A: android:enabled.*=.*0x0$/ - } - - if (name && main && launcher && !disabled) { - // Return the first enabled activity-alias launcher. - return name - } - } - } - } - } - protected handleCommandOutput(def text) { logger.info text } @@ -95,8 +49,7 @@ public class AdbTask extends org.gradle.api.DefaultTask { handleCommandOutput(command.execute().text) } - private void printDeviceInfo() { - Device device = pluginEx.devices().find { device -> device.id == getDeviceId() } + private printDeviceInfo(device) { println '==========================' println device.toString() println '==========================' @@ -104,13 +57,14 @@ public class AdbTask extends org.gradle.api.DefaultTask { protected void assertDeviceConnected() { def id = getDeviceId() - if (!pluginEx.deviceIds().contains(id)) - throw new IllegalStateException("Device with ID $id not found") - printDeviceInfo() + Device device = pluginEx.devices().find { device -> device.id == id } + if (!device) + throw new IllegalStateException("No device with ID $id found.") + printDeviceInfo(device) } - private String readApkProperty(String propertyKey) { - if (apkPath == null) { + protected final readApkProperty(String propertyKey) { + if (!apkPath) { throw new IllegalStateException("No APK found for the '$name' task") } String output = [pluginEx.aapt, 'dump', 'badging', apkPath].execute().text.readLines().find { diff --git a/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/AndroidCommandPluginExtension.groovy b/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/AndroidCommandPluginExtension.groovy index 42845e6..5b08fce 100644 --- a/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/AndroidCommandPluginExtension.groovy +++ b/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/AndroidCommandPluginExtension.groovy @@ -1,4 +1,6 @@ package com.novoda.gradle.command + +import groovy.transform.Memoized import org.gradle.api.Project public class AndroidCommandPluginExtension { @@ -57,6 +59,7 @@ public class AndroidCommandPluginExtension { } // prefer system property over direct setting to enable commandline arguments + @Memoized def getDeviceId() { if (System.properties['deviceId']) return System.properties['deviceId'] diff --git a/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/Run.groovy b/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/Run.groovy index 2633da0..de4fd18 100644 --- a/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/Run.groovy +++ b/gradle-android-command-plugin/src/main/groovy/com/novoda/gradle/command/Run.groovy @@ -9,4 +9,55 @@ class Run extends AdbTask { def line = ['shell', 'am', 'start', '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.LAUNCHER', "$packageName/$launchableActivity"] assertDeviceAndRunCommand(line) } + + def getLaunchableActivity() { + def output = readApkProperty('launchable-activity') + if (output) { + def matcher = output.readLines()[0] =~ /name='(.*?)'/ + if (matcher) { + matcher[0][1] + } + } else { + // Fall back to manually parsing aapt's pseudo-XML output to support activity aliases, see + // https://code.google.com/p/android/issues/detail?id=157150 + logger.info 'no launchable-activity found, falling back to parsing the manifest' + + output = [pluginEx.aapt, 'dump', 'xmltree', apkPath, 'AndroidManifest.xml'].execute().text + + def it = output.readLines().iterator() + def nextLine = null + + // Look for activity alias definitions. + while (it.hasNext()) { + def line = nextLine ?: it.next() + nextLine = null + + def matcher = line =~ /(\s+)(E: activity-alias)(.*)/ + if (matcher) { + def intentation = matcher[0][1] + ' ' + def name = null, main = false, launcher = false, disabled = false + + // Parse the indented block for the current activity alias. + while (it.hasNext() && (nextLine = it.next()).startsWith(intentation)) { + matcher = nextLine =~ /A: android:name.*="([^"]+)"/ + if (matcher && !name) { + name = matcher[0][1] + } + main = main || nextLine.contains('android.intent.action.MAIN') + launcher = launcher || nextLine.contains('android.intent.category.LAUNCHER') + + // Exclude disabled entries. + disabled = disabled || nextLine ==~ /^(\s+)A: android:enabled.*=.*0x0$/ + } + + if (name && main && launcher && !disabled) { + // Return the first enabled activity-alias launcher. + return name + } + } + } + } + } + + }