1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.harmony.dalvik.ddmc; 18 19 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; 20 21 import android.annotation.SystemApi; 22 import android.compat.annotation.UnsupportedAppUsage; 23 import java.nio.ByteBuffer; 24 import java.nio.ByteOrder; 25 26 /** 27 * Handle a chunk of data sent from a DDM server. 28 * 29 * To handle a chunk type, sub-class {@link ChunkHandler} and register your class 30 * with {@link DdmServer}. 31 * 32 * @hide 33 */ 34 @SystemApi(client = MODULE_LIBRARIES) 35 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 36 public abstract class ChunkHandler { 37 38 /** 39 * Byte order of the data in the chunk. 40 * 41 * @hide 42 */ 43 @UnsupportedAppUsage 44 @SystemApi(client = MODULE_LIBRARIES) 45 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 46 public static final ByteOrder CHUNK_ORDER = ByteOrder.BIG_ENDIAN; 47 48 /** 49 * @hide 50 */ 51 public static final int CHUNK_FAIL = type("FAIL"); 52 53 /** 54 * Constructs chunk handler. 55 * 56 * @hide 57 */ 58 @SystemApi(client = MODULE_LIBRARIES) 59 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) ChunkHandler()60 public ChunkHandler() {} 61 62 /** 63 * Called when the DDM server connects. The handler is allowed to 64 * send messages to the server. 65 * 66 * @hide 67 */ 68 @SystemApi(client = MODULE_LIBRARIES) 69 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) onConnected()70 public abstract void onConnected(); 71 72 /** 73 * Called when the DDM server disconnects. Can be used to disable 74 * periodic transmissions or clean up saved state. 75 * 76 * @hide 77 */ 78 @SystemApi(client = MODULE_LIBRARIES) 79 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) onDisconnected()80 public abstract void onDisconnected(); 81 82 /** 83 * Handle a single chunk of data. {@code request} includes the type and 84 * the chunk payload. 85 * 86 * Returns a response in a {@link Chunk}. 87 * 88 * @param request chunk type and payload 89 * @return {@link Chunk} with response 90 * 91 * @hide 92 */ 93 @SystemApi(client = MODULE_LIBRARIES) 94 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) handleChunk(Chunk request)95 public abstract Chunk handleChunk(Chunk request); 96 97 /** 98 * Create a FAIL chunk. The {@link #handleChunk(Chunk)} methods can use this to 99 * return an error message when they are not able to process a chunk. 100 * 101 * @param errorCode arbitrary number to distinguish error 102 * @param msg error message 103 * @return {@link Chunk} with response 104 * 105 * @hide 106 */ 107 @SystemApi(client = MODULE_LIBRARIES) 108 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) createFailChunk(int errorCode, String msg)109 public static Chunk createFailChunk(int errorCode, String msg) { 110 if (msg == null) 111 msg = ""; 112 113 ByteBuffer out = ByteBuffer.allocate(8 + msg.length() * 2); 114 out.order(ChunkHandler.CHUNK_ORDER); 115 out.putInt(errorCode); 116 out.putInt(msg.length()); 117 final int len = msg.length(); 118 for (int i = 0; i < len; i++) { 119 out.putChar(msg.charAt(i)); 120 } 121 122 return new Chunk(CHUNK_FAIL, out); 123 } 124 125 /** 126 * Utility function to wrap a {@link ByteBuffer} around a {@link Chunk}. 127 * 128 * @param request chunk to be wrapped 129 * @return {@link ByteBuffer} wrapping data from the given chunk 130 * 131 * @hide 132 */ 133 @SystemApi(client = MODULE_LIBRARIES) 134 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) wrapChunk(Chunk request)135 public static ByteBuffer wrapChunk(Chunk request) { 136 ByteBuffer in; 137 138 in = ByteBuffer.wrap(request.data, request.offset, request.length); 139 in.order(CHUNK_ORDER); 140 return in; 141 } 142 143 /** 144 * Convert a 4-character string to a 32-bit type. 145 * 146 * @hide 147 */ 148 @SystemApi(client = MODULE_LIBRARIES) 149 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) type(String typeName)150 public static int type(String typeName) { 151 if (typeName.length() != 4) { 152 throw new IllegalArgumentException("Bad type name: " + typeName); 153 } 154 int result = 0; 155 for (int i = 0; i < 4; ++i) { 156 result = ((result << 8) | (typeName.charAt(i) & 0xff)); 157 } 158 return result; 159 } 160 161 /** 162 * Convert an integer type to a 4-character string. 163 * 164 * @hide 165 */ 166 @SystemApi(client = MODULE_LIBRARIES) 167 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) name(int type)168 public static String name(int type) 169 { 170 char[] ascii = new char[4]; 171 172 ascii[0] = (char) ((type >> 24) & 0xff); 173 ascii[1] = (char) ((type >> 16) & 0xff); 174 ascii[2] = (char) ((type >> 8) & 0xff); 175 ascii[3] = (char) (type & 0xff); 176 177 return new String(ascii); 178 } 179 } 180