/* * Process activity from one of the debugger sockets. This could be a new * connection or a data packet. */ private void processDebuggerActivity(SelectionKey key) { Debugger dbg = (Debugger)key.attachment(); try { if (key.acceptable) { try { acceptNewDebugger(dbg, null); } catch (IOException ioe) { Log.w("ddms", "debugger accept() failed"); Console.WriteLine(ioe.ToString()); Console.Write(ioe.StackTrace); } } else if (key.readable) { processDebuggerData(key); } else { Log.d("ddm-debugger", "key in unknown state"); } } catch (CancelledKeyException) { // key has been cancelled we can ignore that. } }
/* * We have incoming data from the debugger. Forward it to the client. */ private void processDebuggerData(SelectionKey key) { Debugger dbg = (Debugger)key.attachment(); try { /* * Read pending data. */ dbg.read(); /* * See if we have a full packet in the buffer. It's possible we have * more than one packet, so we have to loop. */ JdwpPacket packet = dbg.jdwpPacket; while (packet != null) { Log.v("ddms", "Forwarding dbg req 0x" + packet.id.toHexString() + " to " + dbg.client); dbg.forwardPacketToClient(packet); packet = dbg.jdwpPacket; } } catch (IOException) { /* * Close data connection; automatically un-registers dbg from * selector. The failure could be caused by the debugger going away, * or by the client going away and failing to accept our data. * Either way, the debugger connection does not need to exist any * longer. We also need to recycle the connection to the client, so * that the VM sees the debugger disconnect. For a DDM-aware client * this won't be necessary, and we can just send a "debugger * disconnected" message. */ Log.d("ddms", "Closing connection to debugger " + dbg); dbg.closeData(); Client client = dbg.client; if (client.ddmAware) { // TODO: soft-disconnect DDM-aware clients Log.d("ddms", " (recycling client connection as well)"); // we should drop the client, but also attempt to reopen it. // This is done by the DeviceMonitor. client.deviceImpl.monitor.addClientToDropAndReopen(client, DebugPortManager.DebugPortProvider.NO_STATIC_PORT); } else { Log.d("ddms", " (recycling client connection as well)"); // we should drop the client, but also attempt to reopen it. // This is done by the DeviceMonitor. client.deviceImpl.monitor.addClientToDropAndReopen(client, DebugPortManager.DebugPortProvider.NO_STATIC_PORT); } } }
/* * Something happened. Figure out what. */ private void processClientActivity(SelectionKey key) { Client client = (Client)key.attachment(); try { if (key.readable == false || key.valid == false) { Log.d("ddms", "Invalid key from " + client + ". Dropping client."); dropClient(client, true); // notify return; } client.read(); /* * See if we have a full packet in the buffer. It's possible we have * more than one packet, so we have to loop. */ JdwpPacket packet = client.jdwpPacket; while (packet != null) { if (packet.ddmPacket) { // unsolicited DDM request - hand it off Debug.Assert(!packet.reply); callHandler(client, packet, null); packet.consume(); } else if (packet.reply && client.isResponseToUs(packet.id) != null) { // reply to earlier DDM request ChunkHandler handler = client.isResponseToUs(packet.id); if (packet.error) { client.packetFailed(packet); } else if (packet.empty) { Log.d("ddms", "Got empty reply for 0x" + packet.id.toHexString() + " from " + client); } else { callHandler(client, packet, handler); } packet.consume(); client.removeRequestId(packet.id); } else { Log.v("ddms", "Forwarding client " + (packet.reply ? "reply" : "event") + " 0x" + packet.id.toHexString() + " to " + client.debugger); client.forwardPacketToDebugger(packet); } // find next packet = client.jdwpPacket; } } catch (CancelledKeyException) { // key was canceled probably due to a disconnected client before we could // read stuff coming from the client, so we drop it. dropClient(client, true); // notify } catch (IOException) { // something closed down, no need to print anything. The client is simply dropped. dropClient(client, true); // notify } catch (Exception ex) { Log.e("ddms", ex); /* close the client; automatically un-registers from selector */ dropClient(client, true); // notify if (ex is OverflowException) { Log.w("ddms", "Client data packet exceeded maximum buffer size " + client); } else { // don't know what this is, display it Log.e("ddms", ex); } } }