diff options
author | Stas Negara <snegara@google.com> | 2015-07-28 15:38:19 -0700 |
---|---|---|
committer | Stas Negara <snegara@google.com> | 2015-07-28 15:38:19 -0700 |
commit | 7f7d4675da8a4f8b42adb085e5589604a543373d (patch) | |
tree | 4b474e4de53ebab353d30ed565fb87b1137920c0 | |
parent | 25352a696d220f3258bf9029ea92d01b2487c2a2 (diff) | |
download | testing-7f7d4675da8a4f8b42adb085e5589604a543373d.tar.gz |
Add intelligent VNC keep alive thread.
The thread will start VNC and will restart it when it crashes.
Also, it will clean up after the user closes the VNC Viewer
manually.
Change-Id: I16e40e92fcfc2ab3e82ea8ef55765d485046261e
-rw-r--r-- | src/com/google/gct/testing/CloudConfigurationProviderImpl.java | 10 | ||||
-rw-r--r-- | src/com/google/gct/testing/vnc/VncKeepAliveThreadImpl.java | 101 |
2 files changed, 106 insertions, 5 deletions
diff --git a/src/com/google/gct/testing/CloudConfigurationProviderImpl.java b/src/com/google/gct/testing/CloudConfigurationProviderImpl.java index 23d7386..f0f04e7 100644 --- a/src/com/google/gct/testing/CloudConfigurationProviderImpl.java +++ b/src/com/google/gct/testing/CloudConfigurationProviderImpl.java @@ -25,7 +25,6 @@ import com.android.tools.idea.run.CloudConfiguration.Kind; import com.android.tools.idea.run.CloudConfigurationProvider; import com.android.tools.idea.sdk.IdeSdks; import com.android.tools.idea.stats.UsageTracker; -import com.glavsoft.viewer.Viewer; import com.google.api.client.util.Maps; import com.google.api.client.util.Sets; import com.google.api.services.storage.Storage; @@ -50,6 +49,7 @@ import com.google.gct.testing.results.GoogleCloudTestingResultParser; import com.google.gct.testing.util.CloudTestingTracking; import com.google.gct.testing.vnc.BlankVncViewer; import com.google.gct.testing.vnc.BlankVncViewerCallback; +import com.google.gct.testing.vnc.VncKeepAliveThreadImpl; import com.intellij.execution.DefaultExecutionResult; import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionResult; @@ -362,7 +362,7 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider { final long INITIAL_TIMEOUT = 10 * 60 * 1000; // 10 minutes long stopTime = System.currentTimeMillis() + INITIAL_TIMEOUT; String sdkPath = IdeSdks.getAndroidSdkPath().getAbsolutePath() + "/platform-tools"; - File dir = new File(sdkPath); + File workingDir = new File(sdkPath); try { while (System.currentTimeMillis() < stopTime) { synchronized (ghostCloudDevices) { @@ -391,7 +391,7 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider { String deviceAddress = ipAddress + ":" + adbPort; System.out.println("Device ready with IP address:port " + deviceAddress); Runtime rt = Runtime.getRuntime(); - Process connect = rt.exec("./adb connect " + deviceAddress, null, dir); + Process connect = rt.exec("./adb connect " + deviceAddress, null, workingDir); connect.waitFor(); serialNumberToConfigurationInstance.put(deviceAddress, configurationInstance); // Do not wait for "finally" to remove the ghost device @@ -401,11 +401,11 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider { } blankVncViewer.closeWindow(); // Make sure the device is unlocked. - Process unlock = rt.exec("./adb -s " + deviceAddress + " wait-for-device shell input keyevent 82" , null, dir); + Process unlock = rt.exec("./adb -s " + deviceAddress + " wait-for-device shell input keyevent 82" , null, workingDir); unlock.waitFor(); // Open the VNC window for the cloud device. String[] viewerArgs = new String[]{"-port=" + vncPort, "-host=" + ipAddress, "-password=" + vncPassword, "-fullScreen=false"}; - Viewer.showViewer(viewerArgs, configurationName); + VncKeepAliveThreadImpl.startVnc(viewerArgs, configurationName, cloudProjectId, deviceId, deviceAddress, workingDir); return; } Thread.sleep(POLLING_INTERVAL); diff --git a/src/com/google/gct/testing/vnc/VncKeepAliveThreadImpl.java b/src/com/google/gct/testing/vnc/VncKeepAliveThreadImpl.java new file mode 100644 index 0000000..8838237 --- /dev/null +++ b/src/com/google/gct/testing/vnc/VncKeepAliveThreadImpl.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gct.testing.vnc; + +import com.glavsoft.viewer.Viewer; +import com.glavsoft.viewer.VncKeepAliveThread; +import com.glavsoft.viewer.cli.Parser; + +import javax.swing.*; +import java.io.File; + +import static com.google.gct.testing.launcher.CloudAuthenticator.getTest; + +public class VncKeepAliveThreadImpl extends VncKeepAliveThread { + private final Parser parser; + private final String configurationName; + private final String cloudProjectId; + private final String cloudDeviceId; + private final String deviceAddress; + private final File workingDir; + private volatile boolean hasCrashed = false; + + + public static void startVnc(String[] args, String configurationName, String cloudProjectId, String cloudDeviceId, String deviceAddress, + File workingDir) { + Parser parser = Viewer.prepareParser(args); + if (parser == null) { + return; + } + new VncKeepAliveThreadImpl(parser, configurationName, cloudProjectId, cloudDeviceId, deviceAddress, workingDir).start(); + } + + public VncKeepAliveThreadImpl(Parser parser, String configurationName, String cloudProjectId, String cloudDeviceId, String deviceAddress, + File workingDir) { + this.parser = parser; + this.configurationName = configurationName; + this.cloudProjectId = cloudProjectId; + this.cloudDeviceId = cloudDeviceId; + this.deviceAddress = deviceAddress; + this.workingDir = workingDir; + } + + @Override + public void run() { + SwingUtilities.invokeLater(new Viewer(this, parser, configurationName)); + + while (!Thread.currentThread().isInterrupted() && deviceIsReady()) { + try { + getTest().projects().devices().keepalive(cloudProjectId, cloudDeviceId).execute(); + } catch (Exception e) { + e.printStackTrace(); + } + // Restart the viewer if it accidentally crashed. + if (hasCrashed) { + hasCrashed = false; + System.out.println("Restarting TightVNC Viewer"); + SwingUtilities.invokeLater(new Viewer(this, parser, configurationName)); + } + try { + Thread.sleep(1 * 1000); // 1 second + } catch (InterruptedException e) { + break; + } + } + try { + // Delete the cloud device after the viewer is closed. + getTest().projects().devices().delete(cloudProjectId, cloudDeviceId).execute(); + // Disconnect adb from the deleted device (otherwise, it will keep showing the stale cloud device). + Runtime.getRuntime().exec("./adb disconnect " + deviceAddress, null, workingDir); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + + private boolean deviceIsReady() { + try { + return getTest().projects().devices().get(cloudProjectId, cloudDeviceId).execute().getState().equals("READY"); + } catch (Exception e) { + return true; // Do not stop the keep alive thread for intermittent connection failures. + } + } + + @Override + public void setCrashed() { + hasCrashed = true; + } + +} |