/// <summary> /// Get a screenshot, either via wifi or via bluetooth /// </summary> public async void Screenshot() { if (HasWifi) { // wifi connection is enabled, try getting a screenshot via wifi first. Task <byte[]> task = wifi.GetScreenshot(); CancellationTokenSource CancelDelay = new CancellationTokenSource(); CancellationTokenSource CancelFetch = new CancellationTokenSource(); // Wait maximum 1.5s for the screenshot over wifi if (await Task.WhenAny(task, Task.Delay(1500, CancelDelay.Token)) == task) { // GetScreenshot() returned before the timeout, let's check the result byte[] picbuf = await task; CancelDelay.Cancel(); // Cancel the timeout delay, it's no longer needed if (picbuf == null) { // Wifi failed somehow, fallback to bluetooth and disable the wifi client handler.UpdateStatus("Connected (wifi errors)"); HasWifi = false; wifi = null; bt.Send("sc"); } else { // Successfully got a screenshot over wifi Bitmap bitmap = BitmapFactory.DecodeByteArray(picbuf, 0, picbuf.Length); Console.WriteLine("Bitmap (from wifi) ready, sending over to main thread"); handler.ObtainMessage((int)UIUpdateHandler.MessageType.BITMAP, bitmap).SendToTarget(); } } else { // Timeout from wifi... fallback to bluetooth WifiTimeoutCount++; bt.Send("sc"); if (bt.state == BluetoothClient.State.CONNECTED) { handler.UpdateStatus("Connected (flakey wifi?)"); } if (WifiTimeoutCount > 2) { // WiFi timed-out three times, and therefor is not to be trusted. HasWifi = false; wifi = null; if (bt.state == BluetoothClient.State.CONNECTED) { handler.UpdateStatus("Connected (wifi disabled)"); } } } } else { // No wifi, just ask for a screenshot over Bluetooth bt.Send("sc"); } }
void Recieve() { while (true) { try { if (paused) { continue; } if (state != State.CONNECTED) { StateChangedEvent.WaitOne(); continue; } byte[] buf = new byte[4]; // 4 bytes for "pic:" or "pong" int expected_size = 0; if (_recieve_state == RecieveState.PINGPONG) { lock (InStream) { InStream.Read(buf, 0, buf.Length); } last_ping = DateTime.UtcNow; String command = Encoding.ASCII.GetString(buf).Trim(); if (command.StartsWith("pic")) { buf = new byte[8]; // 8 bytes for image size InStream.Read(buf, 0, buf.Length); expected_size = Int32.Parse(Encoding.ASCII.GetString(buf).Trim()); Console.WriteLine("Expecting a picture, {0} bytes", expected_size); _recieve_state = RecieveState.PICTURE; } else if (command.StartsWith("wifi")) { Console.WriteLine(command); buf = new byte[4]; // 4 bytes for recieved handshake json length InStream.Read(buf, 0, buf.Length); Console.WriteLine(Encoding.ASCII.GetString(buf)); expected_size = Int32.Parse(Encoding.ASCII.GetString(buf).Trim()); buf = Common.ReadAll(InStream, expected_size); WifiCallback(buf); } else if (command != "pong") { // Unexpected data in buffer... // Recover by reconnecting? Console.WriteLine("junk on the buffer :( '" + command + "'"); Disconnect(); Connect(this.device); } } // This is a regular if, not an else if! if (_recieve_state == RecieveState.PICTURE) { byte[] picbuf = Common.ReadAll(InStream, expected_size, 8192 * 2); Console.WriteLine("Recieved picture? {0} bytes", picbuf.Length); Bitmap bitmap = BitmapFactory.DecodeByteArray(picbuf, 0, picbuf.Length); Console.WriteLine("Bitmap (hopefully) ready, sending over to main thread"); handler.ObtainMessage(0, bitmap).SendToTarget(); _recieve_state = RecieveState.PINGPONG; } } catch (Java.IO.IOException e) { Console.WriteLine("Recieving failed, connection might be lost"); Console.WriteLine(e); SetState(State.NOT_CONNECTED); Connect(device); } } }