Esempio n. 1
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");
            }

            Log.I(TAG, "Pulling file '" + localPath + "' from '" + Device + remotePath + "'.");
            byte[] pullResult = new byte[8];

            int timeOut = DdmPreferences.Timeout;

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

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

                // create the full request message
                byte[] msg = CreateFileRequest(StringHelper.GetBytes(RECV), 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);

                // check we have the proper data back
                if (CheckResult(pullResult, StringHelper.GetBytes(DATA)) == false &&
                    CheckResult(pullResult, StringHelper.GetBytes(DONE)) == 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;

            try
            {
                fos = new FileStream(f.FullName, System.IO.FileMode.Create, FileAccess.Write);
            }
            catch (FileNotFoundException e)
            {
                Log.E(TAG, 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 cancelled
                    if (monitor.IsCanceled)
                    {
                        return(new SyncResult(ErrorCodeHelper.RESULT_CANCELED));
                    }

                    // if we're done, we stop the loop
                    if (CheckResult(pullResult, StringHelper.GetBytes(DONE)))
                    {
                        break;
                    }
                    if (CheckResult(pullResult, StringHelper.GetBytes(DATA)) == false)
                    {
                        // hmm there's an error
                        return(new SyncResult(ErrorCodeHelper.RESULT_CONNECTION_ERROR));
                    }
                    int length = ArrayHelper.Swap32bitFromArray(pullResult, 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);

                        // get the header for the next packet.
                        AdbHelper.Instance.Read(Channel, pullResult, -1);
                    }
                    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, data.Length);
                    }
                    catch (IOException e)
                    {
                        Log.E(TAG, 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));
                }

                try
                {
                    fos.Close();
                    fos.Dispose();
                }
                catch (IOException e)
                {
                    Log.E(TAG, e);
                }
            }
            return(new SyncResult(ErrorCodeHelper.RESULT_OK));
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the children.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <param name="useCache">if set to <c>true</c> [use cache].</param>
        /// <param name="receiver">The receiver.</param>
        /// <returns></returns>
        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)
            {
                ThreadState 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)
                {
                    Dictionary <string, FileEntry> map = new Dictionary <string, FileEntry>();

                    foreach (FileEntry child in children)
                    {
                        string path = child.FullPath;
                        map.Add(path, 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
                        });
                    }
                }
            }))
            {
                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);
        }
Esempio n. 3
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="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");
            }

            Log.I(TAG, "Pushing file '" + local + "' to '" + Device + remotePath + "'.");
            byte[] msg;

            int timeOut = DdmPreferences.Timeout;

            FileStream fs;

            try
            {
                byte[] remotePathContent = StringHelper.GetBytes(remotePath, 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(StringHelper.GetBytes(SEND), remotePathContent, (FileMode)0644);
            }
            catch (EncoderFallbackException e)
            {
                Log.E(TAG, e);
                return(new SyncResult(ErrorCodeHelper.RESULT_REMOTE_PATH_ENCODING, e));
            }
            catch (FileNotFoundException e)
            {
                Log.E(TAG, 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)
            {
                Log.E(TAG, 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 = StringHelper.GetBytes(DATA);
            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;
                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
                ArrayHelper.Swap32bitsToArray(readCount, 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();
                fs.Dispose();
            }
            catch (IOException e)
            {
                Log.E(TAG, e);
            }

            try
            {
                // create the DONE message
                long time = DateTimeHelper.CurrentTimeMillis(DateTime.Now) / 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 */);

                if (!CheckResult(result, StringHelper.GetBytes(OKAY)))
                {
                    if (CheckResult(result, StringHelper.GetBytes(FAIL)))
                    {
                        // read some error message...
                        int len = ArrayHelper.Swap32bitFromArray(result, 4);

                        AdbHelper.Instance.Read(Channel, DataBuffer, len);

                        // output the result?
                        string message = StringHelper.GetString(DataBuffer, 0, len);
                        Log.E(TAG, "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...
            this.Device.FileSystem.Chmod(remotePath, "0666");

            return(new SyncResult(ErrorCodeHelper.RESULT_OK));
        }
Esempio n. 4
0
        /// <summary>
        /// Gets the frame buffer from the specified end point.
        /// </summary>
        /// <param name="adbSockAddr">The adb sock addr.</param>
        /// <param name="device">The device.</param>
        /// <returns></returns>
        public RawImage GetFrameBuffer(IPEndPoint adbSockAddr, IDevice device)
        {
            RawImage imageParams = new RawImage();

            byte[] request = FormAdbRequest("framebuffer:");             //$NON-NLS-1$
            byte[] nudge   =
            {
                0
            };
            byte[] reply;

            Socket adbChan = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                adbChan.ReceiveTimeout = SOCKET_TIMEOUT;
                adbChan.SendTimeout    = SOCKET_TIMEOUT;
                adbChan.Connect(adbSockAddr);
                adbChan.Blocking = true;

                // if the device is not -1, then we first tell adb we're looking to talk
                // to a specific device
                SetDevice(adbChan, device);
                if (!Write(adbChan, request))
                {
                    throw new AdbException("failed asking for frame buffer");
                }

                AdbResponse resp = ReadAdbResponse(adbChan, false /* readDiagstring */);
                if (!resp.IOSuccess || !resp.Okay)
                {
                    Log.E(TAG, "Got timeout or unhappy response from ADB fb req: " + resp.Message);
                    adbChan.Close();
                    return(null);
                }

                // first the protocol version.
                reply = new byte[4];
                if (!Read(adbChan, reply))
                {
                    Log.E(TAG, "got partial reply from ADB fb:");

                    adbChan.Close();
                    return(null);
                }
                BinaryReader buf;
                int          version = 0;
                using (MemoryStream ms = new MemoryStream(reply))
                {
                    buf = new BinaryReader(ms);

                    version = buf.ReadInt32();
                }

                // get the header size (this is a count of int)
                int headerSize = RawImage.GetHeaderSize(version);
                // read the header
                reply = new byte[headerSize * 4];
                if (!Read(adbChan, reply))
                {
                    Log.W(TAG, "got partial reply from ADB fb:");

                    adbChan.Close();
                    return(null);
                }
                using (MemoryStream ms = new MemoryStream(reply))
                {
                    buf = new BinaryReader(ms);

                    // fill the RawImage with the header
                    if (imageParams.ReadHeader(version, buf) == false)
                    {
                        Log.W(TAG, "Unsupported protocol: " + version);
                        return(null);
                    }
                }

                Log.D(TAG, "image params: bpp=" + imageParams.Bpp + ", size="
                      + imageParams.Size + ", width=" + imageParams.Width
                      + ", height=" + imageParams.Height);

                if (!Write(adbChan, nudge))
                {
                    throw new AdbException("failed nudging");
                }

                adbChan.ReceiveTimeout = SOCKET_TIMEOUT_FRAMEBUFFER;

                reply = new byte[imageParams.Size];
                if (!Read(adbChan, reply))
                {
                    Log.W(TAG, "got truncated reply from ADB fb data");
                    adbChan.Close();
                    return(null);
                }

                imageParams.Data = reply;
            }
            finally
            {
                if (adbChan != null)
                {
                    adbChan.Close();
                }
            }

            return(imageParams);
        }
Esempio n. 5
0
        /// <summary>
        /// Reads the adb response.
        /// </summary>
        /// <param name="socket">The socket.</param>
        /// <param name="readDiagstring">if set to <c>true</c> [read diag string].</param>
        /// <returns></returns>
        public AdbResponse ReadAdbResponse(Socket socket, bool readDiagstring)
        {
            AdbResponse resp = new AdbResponse();

            byte[] reply = new byte[4];
            if (!Read(socket, reply))
            {
                return(resp);
            }
            resp.IOSuccess = true;

            if (IsOkay(reply))
            {
                resp.Okay = true;
            }
            else
            {
                readDiagstring = true;                 // look for a reason after the FAIL
                resp.Okay      = false;
            }

            // not a loop -- use "while" so we can use "break"
            while (readDiagstring)
            {
                // length string is in next 4 bytes
                byte[] lenBuf = new byte[4];
                if (!Read(socket, lenBuf))
                {
                    Log.D(TAG, "Expected diagnostic string not found");
                    break;
                }

                string lenStr = ReplyTostring(lenBuf);

                int len;
                try
                {
                    len = int.Parse(lenStr, System.Globalization.NumberStyles.HexNumber);
                }
                catch (FormatException)
                {
                    Log.E(TAG, "Expected digits, got '{0}' : {1} {2} {3} {4}", lenBuf[0], lenBuf[1], lenBuf[2], lenBuf[3]);
                    Log.E(TAG, "reply was {0}", ReplyTostring(reply));
                    break;
                }

                byte[] msg = new byte[len];
                if (!Read(socket, msg))
                {
                    Log.E(TAG, "Failed reading diagnostic string, len={0}", len);
                    break;
                }

                resp.Message = ReplyTostring(msg);
                Log.E(TAG, "Got reply '{0}', diag='{1}'", ReplyTostring(reply), resp.Message);

                break;
            }

            return(resp);
        }
Esempio 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;

                                    // 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)
                                        {
                                            device.RetrieveDeviceInfo();
                                        }
                                    }

                                    device.OnStateChanged(EventArgs.Empty);
                                }

                                // 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.RetrieveDeviceInfo(false);
                            newDevice.OnStateChanged(EventArgs.Empty);
                            Server.OnDeviceConnected(new DeviceEventArgs(newDevice));
                        }

                        // start monitoring them.
                        if (AndroidDebugBridge.ClientSupport)
                        {
                            if (newDevice.IsOnline)
                            {
                                StartMonitoringDevice(newDevice);
                            }
                        }
                    }
                }
            }
            list.Clear();
        }
Esempio 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.Restart() == 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;
                        }
                    }
                    //break;
                    if (MainAdbConnection != null && !IsMonitoring)
                    {
                        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)
                {
                    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*/)
                {
                    //Console.WriteLine ( ex );
                }
            } while (IsRunning);
        }