/// <summary> /// Push a single file /// </summary> /// <param name="local">the local file to push</param> /// <param name="remotePath">the remote file (length max is 1024)</param> /// <param name="monitor">the monitor. The monitor must be started already.</param> /// <returns> /// a SyncResult object with a code and an optional message. /// </returns> /// <exception cref="System.ArgumentNullException">monitor;Monitor cannot be null</exception> /// <exception cref="ArgumentNullException">Throws if monitor is null</exception> private SyncResult DoPushFile(string local, string remotePath, ISyncProgressMonitor monitor) { if (monitor == null) { throw new ArgumentNullException("monitor", "Monitor cannot be null"); } FileStream fs = null; byte[] msg; int timeOut = DdmPreferences.Timeout; Log.i(TAG, "Remote File: {0}", remotePath); try { byte[] remotePathContent = remotePath.GetBytes(AdbHelper.DefaultEncoding); if (remotePathContent.Length > REMOTE_PATH_MAX_LENGTH) { return(new SyncResult(ErrorCodeHelper.RESULT_REMOTE_PATH_LENGTH)); } // this shouldn't happen but still... if (!File.Exists(local)) { return(new SyncResult(ErrorCodeHelper.RESULT_NO_LOCAL_FILE)); } // create the stream to read the file fs = new FileStream(local, System.IO.FileMode.Open, FileAccess.Read); // create the header for the action msg = CreateSendFileRequest(SEND.GetBytes(), remotePathContent, (FileMode)0644); } catch (EncoderFallbackException e) { return(new SyncResult(ErrorCodeHelper.RESULT_REMOTE_PATH_ENCODING, e)); } catch (FileNotFoundException e) { return(new SyncResult(ErrorCodeHelper.RESULT_FILE_READ_ERROR, e)); } // and send it. We use a custom try/catch block to make the difference between // file and network IO exceptions. try { AdbHelper.Instance.Write(this.Channel, msg, -1, timeOut); } catch (IOException e) { return(new SyncResult(ErrorCodeHelper.RESULT_CONNECTION_ERROR, e)); } // create the buffer used to read. // we read max SYNC_DATA_MAX, but we need 2 4 bytes at the beginning. if (DataBuffer == null) { DataBuffer = new byte[SYNC_DATA_MAX + 8]; } byte[] bDATA = DATA.GetBytes(); Array.Copy(bDATA, 0, DataBuffer, 0, bDATA.Length); // look while there is something to read while (true) { // check if we're canceled if (monitor.IsCanceled) { return(new SyncResult(ErrorCodeHelper.RESULT_CANCELED)); } // read up to SYNC_DATA_MAX int readCount = 0; try { readCount = fs.Read(DataBuffer, 8, SYNC_DATA_MAX); } catch (IOException e) { return(new SyncResult(ErrorCodeHelper.RESULT_FILE_READ_ERROR, e)); } if (readCount == 0) { // we reached the end of the file break; } // now send the data to the device // first write the amount read readCount.Swap32bitsToArray(DataBuffer, 4); // now write it try { AdbHelper.Instance.Write(this.Channel, DataBuffer, readCount + 8, timeOut); } catch (IOException e) { return(new SyncResult(ErrorCodeHelper.RESULT_CONNECTION_ERROR, e)); } // and advance the monitor monitor.Advance(readCount); } // close the local file try { fs.Close(); } catch (IOException e) { return(new SyncResult(ErrorCodeHelper.RESULT_FILE_READ_ERROR, e)); } try { // create the DONE message long time = DateTime.Now.CurrentTimeMillis() / 1000; msg = CreateRequest(DONE, (int)time); // and send it. AdbHelper.Instance.Write(this.Channel, msg, -1, timeOut); // read the result, in a byte array containing 2 ints // (id, size) byte[] result = new byte[8]; AdbHelper.Instance.Read(this.Channel, result, -1 /* full length */, timeOut); if (!CheckResult(result, OKAY.GetBytes())) { if (CheckResult(result, FAIL.GetBytes())) { // read some error message... int len = result.Swap32bitFromArray(4); AdbHelper.Instance.Read(this.Channel, DataBuffer, len, timeOut); // output the result? string message = DataBuffer.GetString(0, len); Log.e("ddms", "transfer error: " + message); return(new SyncResult(ErrorCodeHelper.RESULT_UNKNOWN_ERROR, message)); } return(new SyncResult(ErrorCodeHelper.RESULT_UNKNOWN_ERROR)); } } catch (IOException e) { return(new SyncResult(ErrorCodeHelper.RESULT_CONNECTION_ERROR, e)); } return(new SyncResult(ErrorCodeHelper.RESULT_OK)); }
/// <summary> /// Monitors the devices. This connects to the Debug Bridge /// </summary> private void DeviceMonitorLoop() { this.IsRunning = true; do { try { if (this.MainAdbConnection == null) { Log.d(TAG, "Opening adb connection"); this.MainAdbConnection = this.OpenAdbConnection(); if (this.MainAdbConnection == null) { this.ConnectionAttemptCount++; Log.i(TAG, "Connection attempts: {0}", this.ConnectionAttemptCount); if (this.ConnectionAttemptCount > 10) { if (this.Server.Start() == false) { this.RestartAttemptCount++; Log.e(TAG, "adb restart attempts: {0}", this.RestartAttemptCount); } else { this.RestartAttemptCount = 0; } } this.WaitBeforeContinue(); } else { Log.d(TAG, "Connected to adb for device monitoring"); this.ConnectionAttemptCount = 0; } } if (this.MainAdbConnection != null && !this.IsMonitoring && this.MainAdbConnection.Connected) { this.IsMonitoring = this.SendDeviceListMonitoringRequest(); } if (this.IsMonitoring) { // read the length of the incoming message int length = this.ReadLength(this.MainAdbConnection, this.LengthBuffer); if (length >= 0) { // read the incoming message this.ProcessIncomingDeviceData(length); // flag the fact that we have build the list at least once. this.HasInitialDeviceList = true; } } } catch (IOException ioe) { if (!this.IsRunning) { Log.e(TAG, "Adb connection Error: ", ioe); this.IsMonitoring = false; if (this.MainAdbConnection != null) { try { this.MainAdbConnection.Close(); } catch (IOException) { // we can safely ignore that one. } this.MainAdbConnection = null; } } } catch (Exception ex) { Log.w(TAG, ex); } }while (this.IsRunning); }