Exemplo n.º 1
0
        /// <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.d(TAG, "Remote File: {0}", remotePath);
            try {
                byte[] remotePathContent = remotePath.GetBytes(AdbHelper.DEFAULT_ENCODING);

                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(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(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(Channel, msg, -1, timeOut);

                // read the result, in a byte array containing 2 ints
                // (id, size)
                byte[] result = new byte[8];
                AdbHelper.Instance.Read(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(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));
            }

            // files pushed have no permissions...
            // lets check if we can get to the file...
            if (this.Device.FileSystem.Exists(remotePath))
            {
                this.Device.FileSystem.Chmod(remotePath, "0666");
            }
            return(new SyncResult(ErrorCodeHelper.RESULT_OK));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Pulls a remote file
        /// </summary>
        /// <param name="remotePath">the remote file (length max is 1024)</param>
        /// <param name="localPath">the local destination</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="ArgumentNullException">Throws if monitor is null</exception>
        private SyncResult DoPullFile(string remotePath, string localPath, ISyncProgressMonitor monitor)
        {
            if (monitor == null)
            {
                throw new ArgumentNullException("monitor", "Monitor cannot be null");
            }


            byte[] msg        = null;
            byte[] pullResult = new byte[8];

            int timeOut = DdmPreferences.Timeout;

            try {
                byte[] remotePathContent = remotePath.GetBytes(AdbHelper.DEFAULT_ENCODING);

                if (remotePathContent.Length > REMOTE_PATH_MAX_LENGTH)
                {
                    return(new SyncResult(ErrorCodeHelper.RESULT_REMOTE_PATH_LENGTH));
                }

                // create the full request message
                msg = CreateFileRequest(RECV.GetBytes( ), remotePathContent);

                // and send it.
                AdbHelper.Instance.Write(Channel, msg, -1, timeOut);

                // read the result, in a byte array containing 2 ints
                // (id, size)
                AdbHelper.Instance.Read(Channel, pullResult, -1, timeOut);

                // check we have the proper data back
                if (CheckResult(pullResult, DATA.GetBytes( )) == false &&
                    CheckResult(pullResult, DONE.GetBytes( )) == false)
                {
                    return(new SyncResult(ErrorCodeHelper.RESULT_CONNECTION_ERROR));
                }
            } catch (EncoderFallbackException e) {
                Log.e(TAG, e);
                return(new SyncResult(ErrorCodeHelper.RESULT_REMOTE_PATH_ENCODING, e));
            } catch (IOException e) {
                Log.e(TAG, e);
                return(new SyncResult(ErrorCodeHelper.RESULT_CONNECTION_ERROR, e));
            }

            // access the destination file
            FileInfo f = new FileInfo(localPath);

            // create the stream to write in the file. We use a new try/catch block to differentiate
            // between file and network io exceptions.
            FileStream fos = null;

            try {
                fos = new FileStream(f.FullName, System.IO.FileMode.Create, FileAccess.Write);
            } catch (FileNotFoundException e) {
                return(new SyncResult(ErrorCodeHelper.RESULT_FILE_WRITE_ERROR, e));
            }

            // the buffer to read the data
            byte[] data = new byte[SYNC_DATA_MAX];
            using ( fos ) {
                // loop to get data until we're done.
                while (true)
                {
                    // check if we're canceled
                    if (monitor.IsCanceled)
                    {
                        return(new SyncResult(ErrorCodeHelper.RESULT_CANCELED));
                    }

                    // if we're done, we stop the loop
                    if (CheckResult(pullResult, DONE.GetBytes( )))
                    {
                        break;
                    }
                    if (CheckResult(pullResult, DATA.GetBytes( )) == false)
                    {
                        // hmm there's an error
                        return(new SyncResult(ErrorCodeHelper.RESULT_CONNECTION_ERROR));
                    }
                    int length = pullResult.Swap32bitFromArray(4);
                    if (length > SYNC_DATA_MAX)
                    {
                        // buffer overrun!
                        // error and exit
                        return(new SyncResult(ErrorCodeHelper.RESULT_BUFFER_OVERRUN));
                    }

                    try {
                        // now read the length we received
                        AdbHelper.Instance.Read(Channel, data, length, timeOut);

                        // get the header for the next packet.
                        AdbHelper.Instance.Read(Channel, pullResult, -1, timeOut);
                    } catch (IOException e) {
                        Log.e(TAG, e);
                        return(new SyncResult(ErrorCodeHelper.RESULT_CONNECTION_ERROR, e));
                    }
                    // write the content in the file
                    try {
                        fos.Write(data, 0, length);
                    } catch (IOException e) {
                        return(new SyncResult(ErrorCodeHelper.RESULT_FILE_WRITE_ERROR, e));
                    }

                    monitor.Advance(length);
                }

                try {
                    fos.Flush( );
                } catch (IOException e) {
                    Log.e(TAG, e);
                    return(new SyncResult(ErrorCodeHelper.RESULT_FILE_WRITE_ERROR, e));
                }
            }
            return(new SyncResult(ErrorCodeHelper.RESULT_OK));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Get the stderr/stdout outputs of a process and return when the process is done.
        /// Both <b>must</b> be read or the process will block on windows.
        /// </summary>
        /// <param name="process">The process to get the ouput from</param>
        /// <param name="errorOutput">The array to store the stderr output. cannot be null.</param>
        /// <param name="stdOutput">The array to store the stdout output. cannot be null.</param>
        /// <param name="waitforReaders">if true, this will wait for the reader threads.</param>
        /// <returns>the process return code.</returns>
        private int GrabProcessOutput(Process process, List <String> errorOutput, List <String> stdOutput, bool waitforReaders)
        {
            if (errorOutput == null)
            {
                throw new ArgumentNullException("errorOutput");
            }
            if (stdOutput == null)
            {
                throw new ArgumentNullException("stdOutput");
            }
            // read the lines as they come. if null is returned, it's
            // because the process finished
            Thread t1 = new Thread(new ThreadStart(delegate {
                // create a buffer to read the stdoutput
                try {
                    using (StreamReader sr = process.StandardError) {
                        while (!sr.EndOfStream)
                        {
                            String line = sr.ReadLine( );
                            if (!String.IsNullOrEmpty(line))
                            {
                                Log.e(ADB, line);
                                errorOutput.Add(line);
                            }
                        }
                    }
                } catch (Exception) {
                    // do nothing.
                }
            }));

            Thread t2 = new Thread(new ThreadStart(delegate {
                // create a buffer to read the std output
                try {
                    using (StreamReader sr = process.StandardOutput) {
                        while (!sr.EndOfStream)
                        {
                            String line = sr.ReadLine( );
                            if (!String.IsNullOrEmpty(line))
                            {
                                stdOutput.Add(line);
                            }
                        }
                    }
                } catch (Exception) {
                    // do nothing.
                }
            }));

            t1.Start( );
            t2.Start( );

            // it looks like on windows process#waitFor() can return
            // before the thread have filled the arrays, so we wait for both threads and the
            // process itself.
            if (waitforReaders)
            {
                try {
                    t1.Join( );
                } catch (ThreadInterruptedException) {
                }
                try {
                    t2.Join( );
                } catch (ThreadInterruptedException) {
                }
            }

            // get the return code from the process
            process.WaitForExit( );
            return(process.ExitCode);
        }
Exemplo n.º 4
0
 public void RunCatLog(IPEndPoint address, IDevice device, string filePath, LogReceiver receiver)
 {
     if (device.IsOnline && (receiver != null))
     {
         int    num    = 0x1400;
         Action action = null;
         Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
         try
         {
             socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, 0));
             socket.ReceiveTimeout    = -1;
             socket.ReceiveBufferSize = num + 1;
             socket.Blocking          = true;
             socket.Connect(AndroidDebugBridge.SocketAddress);
             if (action == null)
             {
                 action = delegate
                 {
                     if (socket != null)
                     {
                         socket.Close();
                     }
                 };
             }
             receiver.CancelAction = action;
             this.SetDevice(socket, device);
             //byte[] data = Instance.FormAdbRequest(string.Format("shell:cat {0}", filePath));
             byte[] data = Instance.FormAdbRequest(string.Format("log:{0}", filePath));
             if (!this.Write(socket, data))
             {
                 throw new AdbException("failed submitting shell command");
             }
             AdbResponse response = Instance.ReadAdbResponse(socket, false);
             if (!response.IOSuccess || !response.Okay)
             {
                 throw new AdbException("sad result from adb: " + response.Message);
             }
             byte[] buffer = new byte[num + 1];
             byte   num2   = 0;
             while ((device.IsOnline && (receiver != null)) && !receiver.IsCancelled)
             {
                 int num3 = socket.Receive(buffer);
                 if (num3 > 0)
                 {
                     using (MemoryStream stream = new MemoryStream())
                     {
                         for (int i = 0; i < num3; i++)
                         {
                             if ((((num3 > (i + 1)) && (buffer[i] == 13)) && (buffer[i + 1] == 10)) || ((num2 == 13) && (buffer[i] == 10)))
                             {
                                 stream.WriteByte(10);
                                 i++;
                             }
                             else
                             {
                                 stream.WriteByte(buffer[i]);
                             }
                             if (i == (num3 - 1))
                             {
                                 num2 = buffer[i];
                             }
                         }
                         receiver.ParseNewData(stream.ToArray(), 0, (int)stream.Length);
                         //continue;
                     }
                 }
             }
         }
         catch (SocketException exception)
         {
             if (exception.SocketErrorCode != SocketError.ConnectionAborted)
             {
                 Log.e("Socket error while receiving response", exception);
             }
         }
         finally
         {
             if (socket != null)
             {
                 socket.Dispose();
             }
         }
     }
 }
Exemplo n.º 5
0
        /// <include file='.\FileListingService.xml' path='/FileListingService/GetChildren/*'/>
        public FileEntry[] GetChildren(FileEntry entry, bool useCache, IListingReceiver receiver)
        {
            // first thing we do is check the cache, and if we already have a recent
            // enough children list, we just return that.
            if (useCache && !entry.NeedFetch)
            {
                return(entry.Children.ToArray( ));
            }

            // if there's no receiver, then this is a synchronous call, and we
            // return the result of ls
            if (receiver == null)
            {
                DoLS(entry);
                return(entry.Children.ToArray( ));
            }

            // this is a asynchronous call.
            // we launch a thread that will do ls and give the listing
            // to the receiver
            Thread t = new Thread(new ParameterizedThreadStart(delegate(object stateData) {
                var state = stateData as ThreadState;

                DoLS(entry);

                receiver.SetChildren(state.Entry, state.Entry.Children.ToArray( ));

                FileEntry[] children = state.Entry.Children.ToArray( );
                if (children.Length > 0 && children[0].IsApplicationPackage)
                {
                    var map = new Dictionary <String, FileEntry> ( );

                    children.ForEach(child => {
                        map.Add(child.FullPath, child);
                    });

                    // call pm.
                    String command = PM_FULL_LISTING;
                    try {
                        this.Device.ExecuteShellCommand(command, new PackageManagerListingReceiver(map, receiver));
                    } catch (IOException e) {
                        // adb failed somehow, we do nothing.
                        Log.e("FileListingService", e);
                    }
                }


                // if another thread is pending, launch it
                lock ( Threads ) {
                    // first remove ourselves from the list
                    Threads.Remove(state.Thread);

                    // then launch the next one if applicable.
                    if (Threads.Count > 0)
                    {
                        Thread ct = Threads[0];
                        ct.Start(new ThreadState {
                            Thread = ct, Entry = entry
                        });
                    }
                }
            }));

            t.Name = "ls " + entry.FullPath;

            // we don't want to run multiple ls on the device at the same time, so we
            // store the thread in a list and launch it only if there's no other thread running.
            // the thread will launch the next one once it's done.
            lock ( Threads ) {
                // add to the list
                Threads.Add(t);

                // if it's the only one, launch it.
                if (Threads.Count == 1)
                {
                    t.Start(new ThreadState {
                        Thread = t
                    });
                }
            }

            // and we return null.
            return(null);
        }
Exemplo n.º 6
0
        private void UpdateDevices(List <Device> list)
        {
            // because we are going to call mServer.deviceDisconnected which will acquire this lock
            // we lock it first, so that the AndroidDebugBridge lock is always locked first.
            lock (AndroidDebugBridge.GetLock( )) {
                lock ( Devices ) {
                    // For each device in the current list, we look for a matching the new list.
                    // * if we find it, we update the current object with whatever new information
                    //   there is
                    //   (mostly state change, if the device becomes ready, we query for build info).
                    //   We also remove the device from the new list to mark it as "processed"
                    // * if we do not find it, we remove it from the current list.
                    // Once this is done, the new list contains device we aren't monitoring yet, so we
                    // add them to the list, and start monitoring them.

                    for (int d = 0; d < Devices.Count;)
                    {
                        Device device = Devices[d];

                        // look for a similar device in the new list.
                        int  count      = list.Count;
                        bool foundMatch = false;
                        for (int dd = 0; dd < count; dd++)
                        {
                            Device newDevice = list[dd];
                            // see if it matches in id and serial number.
                            if (String.Compare(newDevice.SerialNumber, device.SerialNumber, true) == 0)
                            {
                                foundMatch = true;

                                // update the state if needed.
                                if (device.State != newDevice.State)
                                {
                                    device.State = newDevice.State;
                                    device.OnStateChanged(EventArgs.Empty);

                                    // if the device just got ready/online, we need to start
                                    // monitoring it.
                                    if (device.IsOnline)
                                    {
                                        if (AndroidDebugBridge.ClientSupport)
                                        {
                                            if (StartMonitoringDevice(device) == false)
                                            {
                                                Log.e(TAG, "Failed to start monitoring {0}", device.SerialNumber);
                                            }
                                        }

                                        if (device.Properties.Count == 0)
                                        {
                                            QueryNewDeviceForInfo(device);
                                        }
                                    }
                                }

                                // remove the new device from the list since it's been used
                                list.RemoveAt(dd);
                                break;
                            }
                        }

                        if (foundMatch == false)
                        {
                            // the device is gone, we need to remove it, and keep current index
                            // to process the next one.
                            RemoveDevice(device);
                            device.State = DeviceState.Offline;
                            device.OnStateChanged(EventArgs.Empty);
                            Server.OnDeviceDisconnected(new DeviceEventArgs(device));
                        }
                        else
                        {
                            // process the next one
                            d++;
                        }
                    }

                    // at this point we should still have some new devices in newList, so we
                    // process them.
                    foreach (Device newDevice in list)
                    {
                        // add them to the list
                        Devices.Add(newDevice);
                        if (Server != null)
                        {
                            newDevice.State = DeviceState.Online;
                            newDevice.OnStateChanged(EventArgs.Empty);
                            Server.OnDeviceConnected(new DeviceEventArgs(newDevice));
                        }

                        // start monitoring them.
                        if (AndroidDebugBridge.ClientSupport)
                        {
                            if (newDevice.IsOnline)
                            {
                                StartMonitoringDevice(newDevice);
                            }
                        }

                        // look for their build info.
                        if (newDevice.IsOnline)
                        {
                            QueryNewDeviceForInfo(newDevice);
                        }
                    }
                }
            }
            list.Clear( );
        }
Exemplo n.º 7
0
        /// <summary>
        /// Monitors the devices. This connects to the Debug Bridge
        /// </summary>
        private void DeviceMonitorLoop( )
        {
            IsRunning = true;
            do
            {
                try {
                    if (MainAdbConnection == null)
                    {
                        Log.d(TAG, "Opening adb connection");
                        MainAdbConnection = OpenAdbConnection( );

                        if (MainAdbConnection == null)
                        {
                            ConnectionAttemptCount++;
                            Log.e(TAG, "Connection attempts: {0}", ConnectionAttemptCount);

                            if (ConnectionAttemptCount > 10)
                            {
                                if (Server.Start( ) == false)
                                {
                                    RestartAttemptCount++;
                                    Log.e(TAG, "adb restart attempts: {0}", RestartAttemptCount);
                                }
                                else
                                {
                                    RestartAttemptCount = 0;
                                }
                            }
                            WaitBeforeContinue( );
                        }
                        else
                        {
                            Log.d(TAG, "Connected to adb for device monitoring");
                            ConnectionAttemptCount = 0;
                        }
                    }
                    if (MainAdbConnection != null && !IsMonitoring && MainAdbConnection.Connected)
                    {
                        IsMonitoring = SendDeviceListMonitoringRequest( );
                    }

                    if (IsMonitoring)
                    {
                        // read the length of the incoming message
                        int length = ReadLength(MainAdbConnection, LengthBuffer);

                        if (length >= 0)
                        {
                            // read the incoming message
                            ProcessIncomingDeviceData(length);

                            // flag the fact that we have build the list at least once.
                            HasInitialDeviceList = true;
                        }
                    }
                } catch (IOException ioe) {
                    if (!IsRunning)
                    {
                        Log.e(TAG, "Adb connection Error: ", ioe);
                        IsMonitoring = false;
                        if (MainAdbConnection != null)
                        {
                            try {
                                MainAdbConnection.Close( );
                            } catch (IOException) {
                                // we can safely ignore that one.
                            }
                            MainAdbConnection = null;
                        }
                    }
                } catch (Exception ex) {
                    Log.e(TAG, ex);
                }
            } while (IsRunning);
        }