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