19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.ddm; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.dalvik.ddmc.Chunk; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.dalvik.ddmc.ChunkHandler; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.dalvik.ddmc.DdmServer; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Debug; 24d693dfa75b7a156898890014e7192a792314b757Siva Velusamyimport android.os.UserHandle; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.ByteBuffer; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 297b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * Handle "hello" messages and feature discovery. 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DdmHandleHello extends ChunkHandler { 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int CHUNK_HELO = type("HELO"); 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int CHUNK_WAIT = type("WAIT"); 357b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project public static final int CHUNK_FEAT = type("FEAT"); 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static DdmHandleHello mInstance = new DdmHandleHello(); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* singleton, do not instantiate */ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private DdmHandleHello() {} 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register for the messages we're interested in. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void register() { 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DdmServer.registerHandler(CHUNK_HELO, mInstance); 487b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project DdmServer.registerHandler(CHUNK_FEAT, mInstance); 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the DDM server connects. The handler is allowed to 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * send messages to the server. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void connected() { 5643a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v("ddm-hello", "Connected!"); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 59e577232406649450a513140bf09cb3fc8c3fe046Andy McFadden if (false) { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* test spontaneous transmission */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = new byte[] { 0, 1, 2, 3, 4, -4, -3, -2, -1, 127 }; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Chunk testChunk = 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Chunk(ChunkHandler.type("TEST"), data, 1, data.length-2); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DdmServer.sendChunk(testChunk); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the DDM server disconnects. Can be used to disable 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * periodic transmissions or clean up saved state. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void disconnected() { 7343a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v("ddm-hello", "Disconnected!"); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 787b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * Handle a chunk of data. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Chunk handleChunk(Chunk request) { 8143a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) 827b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project Log.v("ddm-heap", "Handling " + name(request.type) + " chunk"); 837b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project int type = request.type; 847b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 857b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project if (type == CHUNK_HELO) { 867b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project return handleHELO(request); 877b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } else if (type == CHUNK_FEAT) { 887b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project return handleFEAT(request); 897b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } else { 907b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project throw new RuntimeException("Unknown packet " 917b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project + ChunkHandler.name(type)); 927b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 937b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 957b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /* 967b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * Handle introductory packet. 977b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 987b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project private Chunk handleHELO(Chunk request) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (false) 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return createFailChunk(123, "This is a test"); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Process the request. 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteBuffer in = wrapChunk(request); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int serverProtoVers = in.getInt(); 10843a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v("ddm-hello", "Server version is " + serverProtoVers); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a response. 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String vmName = System.getProperty("java.vm.name", "?"); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String vmVersion = System.getProperty("java.vm.version", "?"); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String vmIdent = vmName + " v" + vmVersion; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //String appName = android.app.ActivityThread.currentPackageName(); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //if (appName == null) 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // appName = "unknown"; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String appName = DdmHandleAppName.getAppName(); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 123d693dfa75b7a156898890014e7192a792314b757Siva Velusamy ByteBuffer out = ByteBuffer.allocate(20 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + vmIdent.length()*2 + appName.length()*2); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.order(ChunkHandler.CHUNK_ORDER); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.putInt(DdmServer.CLIENT_PROTOCOL_VERSION); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.putInt(android.os.Process.myPid()); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.putInt(vmIdent.length()); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.putInt(appName.length()); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project putString(out, vmIdent); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project putString(out, appName); 132d693dfa75b7a156898890014e7192a792314b757Siva Velusamy out.putInt(UserHandle.myUserId()); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Chunk reply = new Chunk(CHUNK_HELO, out); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Take the opportunity to inform DDMS if we are waiting for a 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * debugger to attach. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Debug.waitingForDebugger()) 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendWAIT(0); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return reply; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1467b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /* 1477b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * Handle request for list of supported features. 1487b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 1497b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project private Chunk handleFEAT(Chunk request) { 1507b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project // TODO: query the VM to ensure that support for these features 1517b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project // is actually compiled in 152e577232406649450a513140bf09cb3fc8c3fe046Andy McFadden final String[] features = Debug.getVmFeatureList(); 1537b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 15443a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) 15598d493588f0ec55b8b6b3762189b2c02f17005c7Andy McFadden Log.v("ddm-heap", "Got feature list request"); 1567b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 1577b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project int size = 4 + 4 * features.length; 1587b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project for (int i = features.length-1; i >= 0; i--) 1597b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project size += features[i].length() * 2; 1607b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 1617b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project ByteBuffer out = ByteBuffer.allocate(size); 1627b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project out.order(ChunkHandler.CHUNK_ORDER); 1637b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project out.putInt(features.length); 1647b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project for (int i = features.length-1; i >= 0; i--) { 1657b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project out.putInt(features[i].length()); 1667b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project putString(out, features[i]); 1677b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 1687b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 1697b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project return new Chunk(CHUNK_FEAT, out); 1707b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 1717b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Send up a WAIT chunk. The only currently defined value for "reason" 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is zero, which means "waiting for a debugger". 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void sendWAIT(int reason) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = new byte[] { (byte) reason }; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Chunk waitChunk = new Chunk(CHUNK_WAIT, data, 0, 1); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DdmServer.sendChunk(waitChunk); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 183