Browse Source

Building, deploying, running from editor on Android

Josh Engebretson 10 years ago
parent
commit
75b8126ff1

+ 190 - 2
Source/ToolCore/Build/BuildAndroid.cpp

@@ -5,11 +5,14 @@
 #include <Atomic/Core/StringUtils.h>
 #include <Atomic/IO/FileSystem.h>
 #include <Atomic/IO/File.h>
+#include <Atomic/IO/MemoryBuffer.h>
 
 #include "../ToolSystem.h"
 #include "../ToolEnvironment.h"
 #include "../Subprocess/SubprocessSystem.h"
 #include "../Project/Project.h"
+#include "../Project/ProjectBuildSettings.h"
+#include "../Platform/PlatformAndroid.h"
 
 #include "AndroidProjectGenerator.h"
 
@@ -22,6 +25,9 @@ namespace ToolCore
 
 BuildAndroid::BuildAndroid(Context* context, Project* project) : BuildBase(context, project)
 {
+    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
+    // this cast isn't great
+    platformAndroid_ = (PlatformAndroid*) toolSystem->GetPlatformByID(PLATFORMID_ANDROID);
 
 }
 
@@ -40,6 +46,189 @@ void BuildAndroid::SendBuildFailure(const String& message)
 
 }
 
+void BuildAndroid::HandleADBStartActivityComplete(StringHash eventType, VariantMap& eventData)
+{
+
+}
+
+
+// adb shell am start -n com.package.name/com.package.name.ActivityName
+
+void BuildAndroid::RunADBStartActivity()
+{
+
+    SubprocessSystem* subs = GetSubsystem<SubprocessSystem>();
+    String adbCommand = platformAndroid_->GetADBCommand();
+
+    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
+    Project* project = toolSystem->GetProject();
+    AndroidBuildSettings* settings = project->GetBuildSettings()->GetAndroidBuildSettings();
+
+    String stringArgs;
+    const char* cpackage = settings->GetPackageName().CString();
+    stringArgs.AppendWithFormat("shell am start -n %s/%s.AtomicGameEngine",cpackage, cpackage);
+
+    Vector<String> args = stringArgs.Split(' ');
+
+    currentBuildPhase_ = ADBStartActivity;
+    Subprocess* subprocess = subs->Launch(adbCommand, args, buildPath_);
+    if (!subprocess)
+    {
+        SendBuildFailure("BuildFailed::RunStartActivity");
+        return;
+    }
+
+    VariantMap buildOutput;
+    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Starting Android Activity</color>\n\n";
+    SendEvent(E_BUILDOUTPUT, buildOutput);
+
+    SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildAndroid, HandleADBStartActivityComplete));
+    SubscribeToEvent(subprocess, E_SUBPROCESSOUTPUT, HANDLER(BuildBase, HandleSubprocessOutputEvent));
+
+}
+
+
+void BuildAndroid::HandleRunADBInstallComplete(StringHash eventType, VariantMap& eventData)
+{
+    int code = eventData[SubprocessComplete::P_RETCODE].GetInt();
+
+    if (!code)
+    {
+        RunADBStartActivity();
+    }
+    else
+    {
+        BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
+        buildSystem->BuildComplete(PLATFORMID_ANDROID, buildPath_, false);
+    }
+
+}
+
+void BuildAndroid::RunADBInstall()
+{
+
+    SubprocessSystem* subs = GetSubsystem<SubprocessSystem>();
+    String adbCommand = platformAndroid_->GetADBCommand();
+
+    Vector<String> args = String("install -r ./bin/Atomic-debug-unaligned.apk").Split(' ');
+
+    currentBuildPhase_ = ADBInstall;
+    Subprocess* subprocess = subs->Launch(adbCommand, args, buildPath_);
+
+    if (!subprocess)
+    {
+        SendBuildFailure("BuildFailed::RunADBInstall");
+        return;
+    }
+
+    VariantMap buildOutput;
+    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Installing on Android Device</color>\n\n";
+    SendEvent(E_BUILDOUTPUT, buildOutput);
+
+    SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildAndroid, HandleRunADBInstallComplete));
+    SubscribeToEvent(subprocess, E_SUBPROCESSOUTPUT, HANDLER(BuildBase, HandleSubprocessOutputEvent));
+
+}
+
+void BuildAndroid::HandleADBListDevicesComplete(StringHash eventType, VariantMap& eventData)
+{
+    BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
+
+    int code = eventData[SubprocessComplete::P_RETCODE].GetInt();
+
+    if (!code)
+    {
+        // check if we have any devices attached, otherwise adb install
+        // will hang looking for devices
+        bool noDevices = true;
+        if (deviceListText_.Length())
+        {
+            MemoryBuffer reader(deviceListText_.CString(), deviceListText_.Length() + 1);
+            while (!reader.IsEof())
+            {
+                String line = reader.ReadLine();
+                if (line.Length() && line[0] >= '0' && line[0] <= '9')
+                {
+                    noDevices = false;
+                    break;
+                }
+            }
+        }
+
+        if (!noDevices)
+            RunADBInstall();
+        else
+        {
+            // can't proceed, though success
+            buildSystem->BuildComplete(PLATFORMID_ANDROID, buildPath_);
+        }
+
+    }
+    else
+    {
+        buildSystem->BuildComplete(PLATFORMID_ANDROID, buildPath_, false);
+    }
+
+}
+
+void BuildAndroid::HandleADBListDevicesOutputEvent(StringHash eventType, VariantMap& eventData)
+{
+    // E_SUBPROCESSOUTPUT
+    const String& text = eventData[SubprocessOutput::P_TEXT].GetString();
+
+    deviceListText_ += text;
+
+    // convert to a build output event and forward to subscribers
+    VariantMap buildOutputData;
+    buildOutputData[BuildOutput::P_TEXT] = text;
+    SendEvent(E_BUILDOUTPUT, buildOutputData);
+
+}
+
+void BuildAndroid::RunADBListDevices()
+{
+    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
+    SubprocessSystem* subs = GetSubsystem<SubprocessSystem>();
+
+    String adbCommand = platformAndroid_->GetADBCommand();
+
+    deviceListText_.Clear();
+
+    Vector<String> args = String("devices").Split(' ');
+
+    currentBuildPhase_ = ADBListDevices;
+    Subprocess* subprocess = subs->Launch(adbCommand, args, "");
+
+    if (!subprocess)
+    {
+        SendBuildFailure("BuildFailed::RunADBListDevices");
+        return;
+    }
+
+    VariantMap buildOutput;
+    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Listing Android Devices</color>\n\n";
+    SendEvent(E_BUILDOUTPUT, buildOutput);
+
+    SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildAndroid, HandleADBListDevicesComplete));
+    SubscribeToEvent(subprocess, E_SUBPROCESSOUTPUT, HANDLER(BuildAndroid, HandleADBListDevicesOutputEvent));
+
+}
+
+void BuildAndroid::HandleAntDebugComplete(StringHash eventType, VariantMap& eventData)
+{
+    int code = eventData[SubprocessComplete::P_RETCODE].GetInt();
+
+    if (!code)
+    {
+        RunADBListDevices();
+    }
+    else
+    {
+        BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
+        buildSystem->BuildComplete(PLATFORMID_ANDROID, buildPath_, false);
+    }
+}
+
 void BuildAndroid::RunAntDebug()
 {
     ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
@@ -77,7 +266,7 @@ void BuildAndroid::RunAntDebug()
     buildOutput[BuildOutput::P_TEXT] = "<color #D4FB79>Starting Android Deployment</color>\n\n";
     SendEvent(E_BUILDOUTPUT, buildOutput);
 
-    //SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildAndroid, HandleEvent));
+    SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildAndroid, HandleAntDebugComplete));
     SubscribeToEvent(subprocess, E_SUBPROCESSOUTPUT, HANDLER(BuildBase, HandleSubprocessOutputEvent));
 
 }
@@ -151,7 +340,6 @@ void BuildAndroid::Build(const String& buildPath)
     mfile->WriteString(manifest);
     mfile->Close();
 
-
     AndroidProjectGenerator gen(context_);
     gen.SetBuildPath(buildPath_);
 

+ 16 - 0
Source/ToolCore/Build/BuildAndroid.h

@@ -11,6 +11,8 @@ namespace ToolCore
 
 class Project;
 
+class PlatformAndroid;
+
 class BuildAndroid : public BuildBase
 {
     OBJECT(BuildAndroid);
@@ -36,6 +38,17 @@ protected:
     };
 
     void RunAntDebug();
+    void HandleAntDebugComplete(StringHash eventType, VariantMap& eventData);
+
+    void RunADBListDevices();
+    void HandleADBListDevicesOutputEvent(StringHash eventType, VariantMap& eventData);
+    void HandleADBListDevicesComplete(StringHash eventType, VariantMap& eventData);
+
+    void RunADBInstall();
+    void HandleRunADBInstallComplete(StringHash eventType, VariantMap& eventData);
+
+    void RunADBStartActivity();
+    void HandleADBStartActivityComplete(StringHash eventType, VariantMap& eventData);
 
     void SendBuildFailure(const String& message);
 
@@ -43,6 +56,9 @@ protected:
 
     void Initialize();
 
+    PlatformAndroid* platformAndroid_;
+    String deviceListText_;
+
 };
 
 }

+ 16 - 0
Source/ToolCore/Platform/PlatformAndroid.cpp

@@ -99,6 +99,22 @@ void PlatformAndroid::RefreshAndroidTargets()
 
 }
 
+String PlatformAndroid::GetADBCommand() const
+{
+    ToolPrefs* prefs = GetSubsystem<ToolEnvironment>()->GetToolPrefs();
+
+    String adbCommand = prefs->GetAndroidSDKPath();
+
+#ifdef ATOMIC_PLATFORM_OSX
+    adbCommand += "/platform-tools/adb";
+#else
+    adbCommand += "/platform-tools/adb.exe";
+#endif
+
+    return adbCommand;
+
+}
+
 String PlatformAndroid::GetAndroidCommand() const
 {
     ToolPrefs* prefs = GetSubsystem<ToolEnvironment>()->GetToolPrefs();

+ 1 - 0
Source/ToolCore/Platform/PlatformAndroid.h

@@ -30,6 +30,7 @@ public:
     PlatformID GetPlatformID() { return PLATFORMID_ANDROID; }
 
     String GetAndroidCommand() const;
+    String GetADBCommand() const;
 
     void RefreshAndroidTargets();
     const Vector<String>& GetAndroidTargets() { return androidTargets_; }