1 /* 2 * Copyright (C) 2015 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 com.android.server.wifi; 18 19 import android.os.Bundle; 20 import android.util.Log; 21 22 import com.android.server.wifi.WifiNative; 23 24 import org.json.JSONArray; 25 import org.json.JSONException; 26 import org.json.JSONObject; 27 28 import java.lang.reflect.Field; 29 import java.util.Iterator; 30 31 public class HalMockUtils { 32 private static final String TAG = "HalMockUtils"; 33 private static final boolean DBG = true; 34 private static final boolean VDBG = true; 35 initHalMock()36 private static native int initHalMock(); 37 setHalMockObject(Object obj)38 public static native void setHalMockObject(Object obj); 39 40 static { 41 System.loadLibrary("wifi-hal-mock"); 42 } 43 initHalMockLibrary()44 public static void initHalMockLibrary() throws Exception { 45 /* 46 * Setting the Wi-Fi HAL handle and interface (array) to dummy 47 * values. Required to fake the init checking code to think that 48 * the HAL actually started. 49 * 50 * Note that values are not important since they are only used by 51 * the real HAL - which is mocked-out in this use-case. 52 */ 53 Field field = WifiNative.class.getDeclaredField("sWifiHalHandle"); 54 field.setAccessible(true); 55 long currentWifiHalHandle = field.getLong(null); 56 if (DBG) Log.d(TAG, "currentWifiHalHandle=" + currentWifiHalHandle); 57 if (currentWifiHalHandle == 0) { 58 field.setLong(null, 5); 59 60 field = WifiNative.class.getDeclaredField("sWifiIfaceHandles"); 61 field.setAccessible(true); 62 long[] wifiIfaceHandles = { 63 10 }; 64 field.set(null, wifiIfaceHandles); 65 } 66 67 initHalMock(); 68 } 69 70 /* 71 * JSON data-model for passing arguments between mock host (java) and mock 72 * HAL (C): 73 * { 74 * "name" : { "type" : "int|byte_array", "value" : 123 | [1, 2, 3, 4] } 75 * } 76 */ 77 78 private static final String TYPE_KEY = "type"; 79 private static final String VALUE_KEY = "value"; 80 81 private static final String TYPE_INT = "int"; 82 private static final String TYPE_BYTE_ARRAY = "byte_array"; 83 convertJsonToBundle(String jsonArgs)84 public static Bundle convertJsonToBundle(String jsonArgs) throws JSONException { 85 if (VDBG) Log.v(TAG, "convertJsonToBundle: jsonArgs=" + jsonArgs); 86 87 Bundle bundle = new Bundle(); 88 89 JSONObject jsonObject = new JSONObject(jsonArgs); 90 Iterator<String> iter = jsonObject.keys(); 91 while (iter.hasNext()) { 92 String key = iter.next(); 93 JSONObject field = jsonObject.optJSONObject(key); 94 95 String type = field.getString(TYPE_KEY); 96 97 if (TYPE_INT.equals(type)) { 98 bundle.putInt(key, field.optInt(VALUE_KEY)); 99 } else if (TYPE_BYTE_ARRAY.equals(type)) { 100 JSONArray array = field.optJSONArray(VALUE_KEY); 101 byte[] bArray = new byte[array.length()]; 102 for (int i = 0; i < array.length(); ++i) { 103 bArray[i] = (byte) array.getInt(i); 104 } 105 bundle.putByteArray(key, bArray); 106 } else { 107 throw new JSONException("Unexpected TYPE read from mock HAL -- '" + type + "'"); 108 } 109 } 110 111 if (DBG) Log.d(TAG, "convertJsonToBundle: returning bundle=" + bundle); 112 return bundle; 113 } 114 convertBundleToJson(Bundle bundle)115 public static JSONObject convertBundleToJson(Bundle bundle) throws JSONException { 116 if (VDBG) Log.v(TAG, "convertBundleToJson: bundle=" + bundle.toString()); 117 118 JSONObject json = new JSONObject(); 119 for (String key : bundle.keySet()) { 120 Object value = bundle.get(key); 121 JSONObject child = new JSONObject(); 122 if (value instanceof Integer) { 123 child.put(TYPE_KEY, TYPE_INT); 124 child.put(VALUE_KEY, ((Integer) value).intValue()); 125 } else if (value instanceof byte[]) { 126 byte[] array = (byte[]) value; 127 JSONArray jsonArray = new JSONArray(); 128 for (int i = 0; i < array.length; ++i) { 129 jsonArray.put(array[i]); 130 } 131 child.put(TYPE_KEY, TYPE_BYTE_ARRAY); 132 child.put(VALUE_KEY, jsonArray); 133 } else { 134 throw new JSONException("Unexpected type of JSON tree node (not an Integer " 135 + "or byte[]): " + value); 136 } 137 json.put(key, child); 138 } 139 140 if (DBG) Log.d(TAG, "convertBundleToJson: returning JSONObject=" + json); 141 return json; 142 } 143 } 144