Skip to content
This repository was archived by the owner on Jul 31, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fastlane/Pluginfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Autogenerated by fastlane
gem 'fastlane-plugin-android_sdk_update'
gem 'fastlane-plugin-android_sdk_update', '>=0.2.0'
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,42 @@
module Fastlane
module Actions
module SharedValues
ANDROID_SDK_DIR = :ANDROID_SDK_DIR
end

class AndroidEmulatorAction < Action
def self.run(params)
sdk_dir = params[:sdk_dir]
Actions::AndroidSdkLocateAction.run(params)
sdk_dir = Actions.lane_context[SharedValues::ANDROID_SDK_DIR]
adb = "#{sdk_dir}/platform-tools/adb"

UI.message("Stopping emulator")
system("#{adb} emu kill > /dev/null 2>&1 &")
sleep(2)

UI.message("Creating new emulator")
FastlaneCore::CommandExecutor.execute(
command: "#{sdk_dir}/tools/bin/avdmanager create avd -n '#{params[:name]}' -f -k '#{params[:package]}' -d 'Nexus 5'",
print_all: true,
print_command: false
)

UI.message("Override configuration")
open("#{Dir.home}/.android/avd/#{params[:name]}.avd/config.ini", 'a') { |f|
f << "hw.gpu.mode=auto\n"
f << "hw.gpu.enabled=yes\n"
f << "skin.dynamic=yes\n"
f << "skin.name=1080x1920\n"
}
system("#{adb} emu kill > /dev/null 2>&1")

avd_available = false
config_file = "#{Dir.home}/.android/avd/#{params[:name]}.avd/config.ini"
if File.exists?(config_file)
avd_image = File.open(config_file).grep(/^image\.sysdir\.1=/).first
avd_available = avd_image.include?(params[:package].gsub(';', '/'))
end

if params[:retain_previous_avd] && avd_available
UI.message("Using existing #{params[:name]} emulator")
else
UI.message("Creating new emulator")
FastlaneCore::CommandExecutor.execute(
command: "#{sdk_dir}/tools/bin/avdmanager create avd -n '#{params[:name]}' -f -k '#{params[:package]}' -d '#{params[:device_definition]}'",
print_all: true,
print_command: false
)

UI.message("Override configuration")
open(config_file, 'a') { |f|
f << "hw.gpu.mode=auto\n"
f << "hw.gpu.enabled=yes\n"
f << "skin.dynamic=yes\n"
f << "skin.name=1080x1920\n"
}
end

# Verify HAXM installed on mac
if FastlaneCore::Helper.mac?
Expand All @@ -40,9 +50,14 @@ def self.run(params)

UI.message("Starting emulator")
system("LC_NUMERIC=C; #{sdk_dir}/tools/emulator @#{params[:name]} > /dev/null 2>&1 &")
sh("#{adb} -e wait-for-device")

until Actions.sh("#{adb} -e shell getprop init.svc.bootanim", log: false).include? "stopped" do
error_callback = proc do |error|
UI.error("Emulator may be having issues... or could have started too quickly!")
end
Actions.sh("#{adb} -e wait-for-device", error_callback: error_callback)

until Actions.sh("#{adb} -e shell getprop init.svc.bootanim", log: false,
error_callback: error_callback).include? "stopped" do
sleep(5)
end

Expand Down Expand Up @@ -88,14 +103,19 @@ def self.available_options
UI.user_error!("No ANDROID_SDK_DIR given, pass using `sdk_dir: 'sdk_dir'`") unless value and !value.empty?
end),
FastlaneCore::ConfigItem.new(key: :package,
env_name: "AVD_PACKAGE",
description: "The selected system image of the emulator",
optional: false),
env_name: "AVD_PACKAGE",
description: "The selected system image of the emulator",
optional: false),
FastlaneCore::ConfigItem.new(key: :name,
env_name: "AVD_NAME",
description: "Name of the AVD",
default_value: "fastlane",
optional: false),
FastlaneCore::ConfigItem.new(key: :device_definition,
env_name: "AVD_DEVICE_DEFINITION",
description: "Device definition for the AVD",
default_value: "Nexus 5",
optional: false),
FastlaneCore::ConfigItem.new(key: :location,
env_name: "AVD_LOCATION",
description: "Set location of the the emulator '<longitude> <latitude>'",
Expand All @@ -104,6 +124,11 @@ def self.available_options
env_name: "AVD_DEMO_MODE",
description: "Set the emulator in demo mode",
is_string: false,
default_value: true),
FastlaneCore::ConfigItem.new(key: :retain_previous_avd,
env_name: "AVD_RETAIN_PREVIOUS",
description: "Retain previously created AVD (use snapshot)",
is_string: false,
default_value: true)
]
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'fastlane/action'
require_relative '../helper/android_emulator_helper'

module Fastlane
module Actions
module SharedValues
end

class DisableAndroidAnimationsAction < Action
def self.run(params)
Actions::AndroidSdkLocateAction.run(params)
sdk_dir = Actions.lane_context[SharedValues::ANDROID_SDK_DIR]
adb = "#{sdk_dir}/platform-tools/adb"
UI.message "Disabling Android animations"
devices = sh("#{adb} devices -l").split("\n")
device = Helper::AndroidEmulatorHelper.select_device(devices, params[:device])
sh("#{adb} -s #{device} shell settings put global window_animation_scale 0.0")
sh("#{adb} -s #{device} shell settings put global transition_animation_scale 0.0")
sh("#{adb} -s #{device} shell settings put global animator_duration_scale 0.0")
end

#####################################################
# @!group Documentation
#####################################################

def self.description
"Disable Android animations"
end

def self.available_options
[
FastlaneCore::ConfigItem.new(key: :sdk_dir,
env_name: "ANDROID_SDK_DIR",
description: "Path to the Android SDK DIR",
default_value: Actions.lane_context[SharedValues::ANDROID_SDK_DIR],
optional: false,
verify_block: proc do |value|
UI.user_error!("No ANDROID_SDK_DIR given, pass using `sdk_dir: 'sdk_dir'`") unless value and !value.empty?
end),
FastlaneCore::ConfigItem.new(key: :device,
env_name: "FL_ANDROID_DEVICE",
optional: true,
description: "Use the device or emulator with the given serial number or qualifier"),
]
end

def self.authors
["Adam Cohen-Rose"]
end

def self.is_supported?(platform)
platform == :android
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'fastlane/action'
require_relative '../helper/android_emulator_helper'

module Fastlane
module Actions
module SharedValues
end

class EnableAndroidAnimationsAction < Action
def self.run(params)
Actions::AndroidSdkLocateAction.run(params)
sdk_dir = Actions.lane_context[SharedValues::ANDROID_SDK_DIR]
adb = "#{sdk_dir}/platform-tools/adb"
UI.message "Re-enabling Android animations"
devices = sh("#{adb} devices -l").split("\n")
device = Helper::AndroidEmulatorHelper.select_device(devices, params[:device])
sh("#{adb} -s #{device} shell settings delete global window_animation_scale")
sh("#{adb} -s #{device} shell settings delete global transition_animation_scale")
sh("#{adb} -s #{device} shell settings delete global animator_duration_scale")
end

#####################################################
# @!group Documentation
#####################################################

def self.description
"Re-enable Android animations"
end

def self.available_options
[
FastlaneCore::ConfigItem.new(key: :sdk_dir,
env_name: "ANDROID_SDK_DIR",
description: "Path to the Android SDK DIR",
default_value: Actions.lane_context[SharedValues::ANDROID_SDK_DIR],
optional: false,
verify_block: proc do |value|
UI.user_error!("No ANDROID_SDK_DIR given, pass using `sdk_dir: 'sdk_dir'`") unless value and !value.empty?
end),
FastlaneCore::ConfigItem.new(key: :device,
env_name: "FL_ANDROID_DEVICE",
optional: true,
description: "Use the device or emulator with the given serial number or qualifier"),
]
end

def self.authors
["Adam Cohen-Rose"]
end

def self.is_supported?(platform)
platform == :android
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,37 @@ module Helper
class AndroidEmulatorHelper
# class methods that you define here become available in your action
# as `Helper::AndroidEmulatorHelper.your_method`
#
def self.show_message
UI.message("Hello from the android_emulator plugin helper!")

# copied from fastlane/screengrab/lib/runner.rb
def self.select_device(devices, specific_device)
# the first output by adb devices is "List of devices attached" so remove that and any adb startup output
devices.reject! do |device|
[
'server is out of date', # The adb server is out of date and must be restarted
'unauthorized', # The device has not yet accepted ADB control
'offline', # The device is offline, skip it
'* daemon', # Messages printed when the daemon is starting up
'List of devices attached', # Header of table for data we want
"doesn't match this client" # Message printed when there is an ADB client/server version mismatch
].any? { |status| device.include?(status) }
end

UI.user_error!('There are no connected and authorized devices or emulators') if devices.empty?

devices.select! { |d| d.include?(specific_device) } if specific_device

UI.user_error!("No connected devices matched your criteria: #{specific_device}") if devices.empty?

if devices.length > 1
UI.important("Multiple connected devices, selecting the first one")
UI.important("To specify which connected device to use, use the specific_device option")
end

# grab the serial number. the lines of output can look like these:
# 00c22d4d84aec525 device usb:2148663295X product:bullhead model:Nexus_5X device:bullhead
# 192.168.1.100:5555 device usb:2148663295X product:bullhead model:Nexus_5X device:genymotion
# emulator-5554 device usb:2148663295X product:bullhead model:Nexus_5X device:emulator
devices[0].match(/^\S+/)[0]
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/fastlane/plugin/android_emulator/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Fastlane
module AndroidEmulator
VERSION = "0.1.1"
VERSION = "0.2.0"
end
end