예제 #1
0
        private async Task HandleData(Encoding encoding, CancellationToken ct)
        {
            try
            {
                using (StreamReader reader = new StreamReader(_sock.GetShellStream(), encoding))
                {
                    // Previously, we would loop while reader.Peek() >= 0. Turns out that this would
                    // break too soon in certain cases (about every 10 loops, so it appears to be a timing
                    // issue). Checking for reader.ReadLine() to return null appears to be much more robust
                    // -- one of the integration test fetches output 1000 times and found no truncations.
                    while (!ct.IsCancellationRequested)
                    {
                        var line = await reader.ReadLineAsync().ConfigureAwait(false);

                        if (line == null)
                        {
                            break;
                        }
                        _outputBlock.Post(encoding.GetBytes(line));
                    }
                }
            }
            catch (Exception e)
            {
                // If a cancellation was requested, this main loop is interrupted with an exception
                // because the socket is closed. In that case, we don't need to throw a ShellCommandUnresponsiveException.
                // In all other cases, something went wrong, and we want to report it to the user.
                if (!ct.IsCancellationRequested)
                {
                    throw new ShellCommandUnresponsiveException(e);
                }
            }
        }
예제 #2
0
        /// <inheritdoc/>
        public async Task RunLogServiceAsync(DeviceData device, Action <LogEntry> messageSink, CancellationToken cancellationToken, params LogId[] logNames)
        {
            if (messageSink == null)
            {
                throw new ArgumentException(nameof(messageSink));
            }

            this.EnsureDevice(device);

            // The 'log' service has been deprecated, see
            // https://android.googlesource.com/platform/system/core/+/7aa39a7b199bb9803d3fd47246ee9530b4a96177
            using (IAdbSocket socket = this.adbSocketFactory(this.EndPoint))
            {
                this.SetDevice(socket, device);

                StringBuilder request = new StringBuilder();
                request.Append("shell:logcat -B");

                foreach (var logName in logNames)
                {
                    request.Append($" -b {logName.ToString().ToLowerInvariant()}");
                }

                socket.SendAdbRequest(request.ToString());
                var response = socket.ReadAdbResponse();

                using (Stream stream = socket.GetShellStream())
                {
                    LogReader reader = new LogReader(stream);

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        LogEntry entry = null;

                        try
                        {
                            entry = await reader.ReadEntry(cancellationToken).ConfigureAwait(false);
                        }
                        catch (EndOfStreamException)
                        {
                            // This indicates the end of the stream; the entry will remain null.
                        }

                        if (entry != null)
                        {
                            messageSink(entry);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <inheritdoc/>
        public async Task ExecuteRemoteCommandAsync(string command, DeviceData device, IShellOutputReceiver receiver, CancellationToken cancellationToken, int maxTimeToOutputResponse)
        {
            this.EnsureDevice(device);

            using (IAdbSocket socket = this.adbSocketFactory(this.EndPoint))
            {
                cancellationToken.Register(() => socket.Dispose());

                this.SetDevice(socket, device);
                socket.SendAdbRequest($"shell:{command}");
                var response = socket.ReadAdbResponse();

                try
                {
                    using (StreamReader reader = new StreamReader(socket.GetShellStream(), Encoding))
                    {
                        // Previously, we would loop while reader.Peek() >= 0. Turns out that this would
                        // break too soon in certain cases (about every 10 loops, so it appears to be a timing
                        // issue). Checking for reader.ReadLine() to return null appears to be much more robust
                        // -- one of the integration test fetches output 1000 times and found no truncations.
                        while (!cancellationToken.IsCancellationRequested)
                        {
                            var line = await reader.ReadLineAsync().ConfigureAwait(false);

                            if (line == null)
                            {
                                break;
                            }

                            if (receiver != null)
                            {
                                receiver.AddOutput(line);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    // If a cancellation was requested, this main loop is interrupted with an exception
                    // because the socket is closed. In that case, we don't need to throw a ShellCommandUnresponsiveException.
                    // In all other cases, something went wrong, and we want to report it to the user.
                    if (!cancellationToken.IsCancellationRequested)
                    {
                        throw new ShellCommandUnresponsiveException(e);
                    }
                }
                finally
                {
                    if (receiver != null)
                    {
                        receiver.Flush();
                    }
                }
            }
        }
예제 #4
0
파일: AdbClient.cs 프로젝트: sp0x/ApkLoader
 public async Task <IPropagatorBlock <byte[], byte[]> > ExecuteRemoteCommandAsyncBlock(string cmd, DeviceData d, CancellationToken ct, int maxTimeToOutputResponse, Encoding encoding)
 {
     this.EnsureDevice(d);
     using (IAdbSocket sock = this.GetSocket())
     {
         this.SetDevice(sock, d);
         uint streamId = 1;
         sock.SendAdbRequest($"shell:{cmd}");
         var ss     = sock.GetShellStream();
         var stream = new AdbLocalStream(sock, streamId, encoding, ct);
         //OpenStreams.Add(streamId, stream);
         return(stream.Block);
     }
 }
예제 #5
0
        /// <inheritdoc/>
        public IEnumerable <LogEntry> RunLogService(DeviceData device, params LogId[] logNames)
        {
            this.EnsureDevice(device);

            // The 'log' service has been deprecated, see
            // https://android.googlesource.com/platform/system/core/+/7aa39a7b199bb9803d3fd47246ee9530b4a96177
            using (IAdbSocket socket = Factories.AdbSocketFactory(this.EndPoint))
            {
                this.SetDevice(socket, device);

                StringBuilder request = new StringBuilder();
                request.Append("shell:logcat -B");

                foreach (var logName in logNames)
                {
                    request.Append($" -b {logName.ToString().ToLower()}");
                }

                socket.SendAdbRequest(request.ToString());
                var response = socket.ReadAdbResponse();

                using (Stream stream = socket.GetShellStream())
                    using (LogReader reader = new LogReader(stream))
                    {
                        while (true)
                        {
                            LogEntry entry = null;

                            try
                            {
                                entry = reader.ReadEntry();
                            }
                            catch (EndOfStreamException)
                            {
                                // This indicates the end of the stream; the entry will remain null.
                            }

                            if (entry != null)
                            {
                                yield return(entry);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
            }
        }
예제 #6
0
        public AdbLocalStream(IAdbSocket sock, uint localId, Encoding encoding, CancellationToken ct)
        {
            _sock        = sock;
            _oStream     = sock.GetShellStream();
            _outputBlock = new BufferBlock <byte[]>();
            _inputBlock  = new ActionBlock <byte[]>(bytes =>
            {
                var buff = Command.CreateWriteCommand(LocalId, RemoteId, bytes);
                OnWriting?.Invoke(this, EventArgs.Empty);
                if (RemoteId == 0)
                {
                    throw new Exception("Remote stream not established yet!");
                }
                _sock.Send(buff, buff.Length);
            });
            Block = DataflowBlock.Encapsulate(_inputBlock, _outputBlock);

            HandleData(encoding, ct).ConfigureAwait(false);
        }