Home | History | Annotate | Download | only in jsonrpc
      1 /*
      2  * Copyright (C) 2017 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.googlecode.android_scripting.jsonrpc;
     18 
     19 import static com.googlecode.android_scripting.ConvertUtils.toNonNullString;
     20 
     21 import android.annotation.NonNull;
     22 import android.bluetooth.BluetoothCodecConfig;
     23 import android.bluetooth.BluetoothDevice;
     24 import android.bluetooth.BluetoothGattCharacteristic;
     25 import android.bluetooth.BluetoothGattDescriptor;
     26 import android.bluetooth.BluetoothGattService;
     27 import android.bluetooth.le.AdvertiseSettings;
     28 import android.content.ComponentName;
     29 import android.content.Intent;
     30 import android.graphics.Point;
     31 import android.location.Address;
     32 import android.location.Location;
     33 import android.media.session.PlaybackState;
     34 import android.net.DhcpInfo;
     35 import android.net.IpPrefix;
     36 import android.net.LinkAddress;
     37 import android.net.LinkProperties;
     38 import android.net.Network;
     39 import android.net.NetworkInfo;
     40 import android.net.ProxyInfo;
     41 import android.net.RouteInfo;
     42 import android.net.Uri;
     43 import android.net.wifi.RttManager.RttCapabilities;
     44 import android.net.wifi.ScanResult;
     45 import android.net.wifi.WifiActivityEnergyInfo;
     46 import android.net.wifi.WifiConfiguration;
     47 import android.net.wifi.WifiEnterpriseConfig;
     48 import android.net.wifi.WifiInfo;
     49 import android.net.wifi.WifiScanner.ScanData;
     50 import android.net.wifi.WpsInfo;
     51 import android.net.wifi.p2p.WifiP2pConfig;
     52 import android.net.wifi.p2p.WifiP2pDevice;
     53 import android.net.wifi.p2p.WifiP2pGroup;
     54 import android.net.wifi.p2p.WifiP2pInfo;
     55 import android.os.Bundle;
     56 import android.os.ParcelUuid;
     57 import android.telecom.Call;
     58 import android.telecom.CallAudioState;
     59 import android.telecom.PhoneAccount;
     60 import android.telecom.PhoneAccountHandle;
     61 import android.telecom.VideoProfile;
     62 import android.telecom.VideoProfile.CameraCapabilities;
     63 import android.telephony.CellIdentity;
     64 import android.telephony.CellIdentityCdma;
     65 import android.telephony.CellIdentityGsm;
     66 import android.telephony.CellIdentityLte;
     67 import android.telephony.CellIdentityTdscdma;
     68 import android.telephony.CellIdentityWcdma;
     69 import android.telephony.CellInfo;
     70 import android.telephony.CellInfoCdma;
     71 import android.telephony.CellInfoGsm;
     72 import android.telephony.CellInfoLte;
     73 import android.telephony.CellInfoTdscdma;
     74 import android.telephony.CellInfoWcdma;
     75 import android.telephony.CellLocation;
     76 import android.telephony.CellSignalStrengthCdma;
     77 import android.telephony.CellSignalStrengthGsm;
     78 import android.telephony.CellSignalStrengthLte;
     79 import android.telephony.CellSignalStrengthTdscdma;
     80 import android.telephony.CellSignalStrengthWcdma;
     81 import android.telephony.ModemActivityInfo;
     82 import android.telephony.NeighboringCellInfo;
     83 import android.telephony.ServiceState;
     84 import android.telephony.SignalStrength;
     85 import android.telephony.SmsMessage;
     86 import android.telephony.SubscriptionInfo;
     87 import android.telephony.VoLteServiceState;
     88 import android.telephony.gsm.GsmCellLocation;
     89 import android.util.Base64;
     90 import android.util.DisplayMetrics;
     91 import android.util.SparseArray;
     92 
     93 import com.android.internal.net.LegacyVpnInfo;
     94 
     95 import com.googlecode.android_scripting.ConvertUtils;
     96 import com.googlecode.android_scripting.Log;
     97 import com.googlecode.android_scripting.event.Event;
     98 import com.googlecode.android_scripting.facade.DataUsageController.DataUsageInfo;
     99 import com.googlecode.android_scripting.facade.telephony.InCallServiceImpl;
    100 import com.googlecode.android_scripting.facade.telephony.TelephonyConstants;
    101 import com.googlecode.android_scripting.facade.telephony.TelephonyUtils;
    102 
    103 import org.apache.commons.codec.binary.Base64Codec;
    104 import org.json.JSONArray;
    105 import org.json.JSONException;
    106 import org.json.JSONObject;
    107 
    108 import java.io.IOException;
    109 import java.net.HttpURLConnection;
    110 import java.net.InetAddress;
    111 import java.net.InetSocketAddress;
    112 import java.net.URL;
    113 import java.security.PrivateKey;
    114 import java.security.cert.CertificateEncodingException;
    115 import java.security.cert.X509Certificate;
    116 import java.util.ArrayList;
    117 import java.util.Collection;
    118 import java.util.List;
    119 import java.util.Map;
    120 import java.util.Map.Entry;
    121 import java.util.Set;
    122 
    123 public class JsonBuilder {
    124 
    125     @SuppressWarnings("unchecked")
    126     public static Object build(Object data) throws JSONException {
    127         if (data == null) {
    128             return JSONObject.NULL;
    129         }
    130         if (data instanceof Integer) {
    131             return data;
    132         }
    133         if (data instanceof Float) {
    134             return data;
    135         }
    136         if (data instanceof Double) {
    137             return data;
    138         }
    139         if (data instanceof Long) {
    140             return data;
    141         }
    142         if (data instanceof String) {
    143             return data;
    144         }
    145         if (data instanceof Boolean) {
    146             return data;
    147         }
    148         if (data instanceof JsonSerializable) {
    149             return ((JsonSerializable) data).toJSON();
    150         }
    151         if (data instanceof JSONObject) {
    152             return data;
    153         }
    154         if (data instanceof JSONArray) {
    155             return data;
    156         }
    157         if (data instanceof Set<?>) {
    158             List<Object> items = new ArrayList<Object>((Set<?>) data);
    159             return buildJsonList(items);
    160         }
    161         if (data instanceof Collection<?>) {
    162             List<Object> items = new ArrayList<Object>((Collection<?>) data);
    163             return buildJsonList(items);
    164         }
    165         if (data instanceof List<?>) {
    166             return buildJsonList((List<?>) data);
    167         }
    168         if (data instanceof Address) {
    169             return buildJsonAddress((Address) data);
    170         }
    171         if (data instanceof CallAudioState) {
    172             return buildJsonAudioState((CallAudioState) data);
    173         }
    174         if (data instanceof Location) {
    175             return buildJsonLocation((Location) data);
    176         }
    177         if (data instanceof Bundle) {
    178             return buildJsonBundle((Bundle) data);
    179         }
    180         if (data instanceof Intent) {
    181             return buildJsonIntent((Intent) data);
    182         }
    183         if (data instanceof Event) {
    184             return buildJsonEvent((Event) data);
    185         }
    186         if (data instanceof Map<?, ?>) {
    187             // TODO(damonkohler): I would like to make this a checked cast if
    188             // possible.
    189             return buildJsonMap((Map<String, ?>) data);
    190         }
    191         if (data instanceof ParcelUuid) {
    192             return data.toString();
    193         }
    194         if (data instanceof ScanResult) {
    195             return buildJsonScanResult((ScanResult) data);
    196         }
    197         if (data instanceof ScanData) {
    198             return buildJsonScanData((ScanData) data);
    199         }
    200         if (data instanceof android.bluetooth.le.ScanResult) {
    201             return buildJsonBleScanResult((android.bluetooth.le.ScanResult) data);
    202         }
    203         if (data instanceof AdvertiseSettings) {
    204             return buildJsonBleAdvertiseSettings((AdvertiseSettings) data);
    205         }
    206         if (data instanceof BluetoothGattService) {
    207             return buildJsonBluetoothGattService((BluetoothGattService) data);
    208         }
    209         if (data instanceof BluetoothGattCharacteristic) {
    210             return buildJsonBluetoothGattCharacteristic((BluetoothGattCharacteristic) data);
    211         }
    212         if (data instanceof BluetoothGattDescriptor) {
    213             return buildJsonBluetoothGattDescriptor((BluetoothGattDescriptor) data);
    214         }
    215         if (data instanceof BluetoothDevice) {
    216             return buildJsonBluetoothDevice((BluetoothDevice) data);
    217         }
    218         if (data instanceof BluetoothCodecConfig) {
    219             return buildJsonBluetoothCodecConfig((BluetoothCodecConfig) data);
    220         }
    221         if (data instanceof PlaybackState) {
    222             return buildJsonPlaybackState((PlaybackState) data);
    223         }
    224         if (data instanceof CellLocation) {
    225             return buildJsonCellLocation((CellLocation) data);
    226         }
    227         if (data instanceof WifiInfo) {
    228             return buildJsonWifiInfo((WifiInfo) data);
    229         }
    230         if (data instanceof NeighboringCellInfo) {
    231             return buildNeighboringCellInfo((NeighboringCellInfo) data);
    232         }
    233         if (data instanceof Network) {
    234             return buildNetwork((Network) data);
    235         }
    236         if (data instanceof NetworkInfo) {
    237             return buildNetworkInfo((NetworkInfo) data);
    238         }
    239         if (data instanceof HttpURLConnection) {
    240             return buildHttpURLConnection((HttpURLConnection) data);
    241         }
    242         if (data instanceof InetSocketAddress) {
    243             return buildInetSocketAddress((InetSocketAddress) data);
    244         }
    245         if (data instanceof InetAddress) {
    246             return buildInetAddress((InetAddress) data);
    247         }
    248         if (data instanceof URL) {
    249             return buildURL((URL) data);
    250         }
    251         if (data instanceof Point) {
    252             return buildPoint((Point) data);
    253         }
    254         if (data instanceof SmsMessage) {
    255             return buildSmsMessage((SmsMessage) data);
    256         }
    257         if (data instanceof PhoneAccount) {
    258             return buildPhoneAccount((PhoneAccount) data);
    259         }
    260         if (data instanceof PhoneAccountHandle) {
    261             return buildPhoneAccountHandle((PhoneAccountHandle) data);
    262         }
    263         if (data instanceof SubscriptionInfo) {
    264             return buildSubscriptionInfoRecord((SubscriptionInfo) data);
    265         }
    266         if (data instanceof DataUsageInfo) {
    267             return buildDataUsageInfo((DataUsageInfo) data);
    268         }
    269         if (data instanceof DhcpInfo) {
    270             return buildDhcpInfo((DhcpInfo) data);
    271         }
    272         if (data instanceof DisplayMetrics) {
    273             return buildDisplayMetrics((DisplayMetrics) data);
    274         }
    275         if (data instanceof RttCapabilities) {
    276             return buildRttCapabilities((RttCapabilities) data);
    277         }
    278         if (data instanceof WifiActivityEnergyInfo) {
    279             return buildWifiActivityEnergyInfo((WifiActivityEnergyInfo) data);
    280         }
    281         if (data instanceof WifiConfiguration) {
    282             return buildWifiConfiguration((WifiConfiguration) data);
    283         }
    284         if (data instanceof WifiP2pConfig) {
    285             return buildWifiP2pConfig((WifiP2pConfig) data);
    286         }
    287         if (data instanceof WifiP2pDevice) {
    288             return buildWifiP2pDevice((WifiP2pDevice) data);
    289         }
    290         if (data instanceof WifiP2pInfo) {
    291             return buildWifiP2pInfo((WifiP2pInfo) data);
    292         }
    293         if (data instanceof WifiP2pGroup) {
    294             return buildWifiP2pGroup((WifiP2pGroup) data);
    295         }
    296         if (data instanceof LinkProperties) {
    297             return buildLinkProperties((LinkProperties) data);
    298         }
    299         if (data instanceof LinkAddress) {
    300             return buildLinkAddress((LinkAddress) data);
    301         }
    302         if (data instanceof RouteInfo) {
    303             return buildRouteInfo((RouteInfo) data);
    304         }
    305         if (data instanceof IpPrefix) {
    306             return buildIpPrefix((IpPrefix) data);
    307         }
    308         if (data instanceof ProxyInfo) {
    309             return buildProxyInfo((ProxyInfo) data);
    310         }
    311         if (data instanceof byte[]) {
    312             JSONArray result = new JSONArray();
    313             for (byte b : (byte[]) data) {
    314                 result.put(b & 0xFF);
    315             }
    316             return result;
    317         }
    318         if (data instanceof Object[]) {
    319             return buildJSONArray((Object[]) data);
    320         }
    321         if (data instanceof CellInfo) {
    322             return buildCellInfo((CellInfo) data);
    323         }
    324         if (data instanceof Call) {
    325             return buildCall((Call) data);
    326         }
    327         if (data instanceof Call.Details) {
    328             return buildCallDetails((Call.Details) data);
    329         }
    330         if (data instanceof InCallServiceImpl.CallEvent<?>) {
    331             return buildCallEvent((InCallServiceImpl.CallEvent<?>) data);
    332         }
    333         if (data instanceof VideoProfile) {
    334             return buildVideoProfile((VideoProfile) data);
    335         }
    336         if (data instanceof CameraCapabilities) {
    337             return buildCameraCapabilities((CameraCapabilities) data);
    338         }
    339         if (data instanceof VoLteServiceState) {
    340             return buildVoLteServiceStateEvent((VoLteServiceState) data);
    341         }
    342         if (data instanceof LegacyVpnInfo) {
    343             return buildLegacyVpnInfo((LegacyVpnInfo) data);
    344         }
    345         if (data instanceof ModemActivityInfo) {
    346             return buildModemActivityInfo((ModemActivityInfo) data);
    347         }
    348         if (data instanceof SignalStrength) {
    349             return buildSignalStrength((SignalStrength) data);
    350         }
    351         if (data instanceof ServiceState) {
    352             return buildServiceState((ServiceState) data);
    353         }
    354 
    355         return data.toString();
    356         // throw new JSONException("Failed to build JSON result. " +
    357         // data.getClass().getName());
    358     }
    359 
    360     private static JSONObject buildJsonAudioState(CallAudioState data)
    361             throws JSONException {
    362         JSONObject state = new JSONObject();
    363         state.put("isMuted", data.isMuted());
    364         state.put("AudioRoute", InCallServiceImpl.getAudioRouteString(data.getRoute()));
    365         return state;
    366     }
    367 
    368     private static Object buildDisplayMetrics(DisplayMetrics data)
    369             throws JSONException {
    370         JSONObject dm = new JSONObject();
    371         dm.put("widthPixels", data.widthPixels);
    372         dm.put("heightPixels", data.heightPixels);
    373         dm.put("noncompatHeightPixels", data.noncompatHeightPixels);
    374         dm.put("noncompatWidthPixels", data.noncompatWidthPixels);
    375         return dm;
    376     }
    377 
    378     private static Object buildInetAddress(InetAddress data) {
    379         JSONArray address = new JSONArray();
    380         address.put(data.getHostName());
    381         address.put(data.getHostAddress());
    382         return address;
    383     }
    384 
    385     private static Object buildInetSocketAddress(InetSocketAddress data) {
    386         JSONArray address = new JSONArray();
    387         address.put(data.getHostName());
    388         address.put(data.getPort());
    389         return address;
    390     }
    391 
    392     private static JSONObject buildJsonAddress(Address address)
    393             throws JSONException {
    394         JSONObject result = new JSONObject();
    395         result.put("admin_area", address.getAdminArea());
    396         result.put("country_code", address.getCountryCode());
    397         result.put("country_name", address.getCountryName());
    398         result.put("feature_name", address.getFeatureName());
    399         result.put("phone", address.getPhone());
    400         result.put("locality", address.getLocality());
    401         result.put("postal_code", address.getPostalCode());
    402         result.put("sub_admin_area", address.getSubAdminArea());
    403         result.put("thoroughfare", address.getThoroughfare());
    404         result.put("url", address.getUrl());
    405         return result;
    406     }
    407 
    408     private static JSONArray buildJSONArray(Object[] data) throws JSONException {
    409         JSONArray result = new JSONArray();
    410         for (Object o : data) {
    411             result.put(build(o));
    412         }
    413         return result;
    414     }
    415 
    416     private static JSONObject buildJsonBleAdvertiseSettings(
    417             AdvertiseSettings advertiseSettings) throws JSONException {
    418         JSONObject result = new JSONObject();
    419         result.put("mode", advertiseSettings.getMode());
    420         result.put("txPowerLevel", advertiseSettings.getTxPowerLevel());
    421         result.put("isConnectable", advertiseSettings.isConnectable());
    422         return result;
    423     }
    424 
    425     private static JSONObject buildJsonBleScanResult(
    426             android.bluetooth.le.ScanResult scanResult) throws JSONException {
    427         JSONObject result = new JSONObject();
    428         result.put("rssi", scanResult.getRssi());
    429         result.put("timestampNanos", scanResult.getTimestampNanos());
    430         result.put("deviceName", scanResult.getScanRecord().getDeviceName());
    431         result.put("txPowerLevel", scanResult.getScanRecord().getTxPowerLevel());
    432         result.put("advertiseFlags", scanResult.getScanRecord()
    433                 .getAdvertiseFlags());
    434         ArrayList<String> manufacturerDataList = new ArrayList<String>();
    435         ArrayList<Integer> idList = new ArrayList<Integer>();
    436         if (scanResult.getScanRecord().getManufacturerSpecificData() != null) {
    437             SparseArray<byte[]> manufacturerSpecificData = scanResult
    438                     .getScanRecord().getManufacturerSpecificData();
    439             for (int i = 0; i < manufacturerSpecificData.size(); i++) {
    440                 manufacturerDataList.add(ConvertUtils
    441                         .convertByteArrayToString(manufacturerSpecificData
    442                                 .valueAt(i)));
    443                 idList.add(manufacturerSpecificData.keyAt(i));
    444             }
    445         }
    446         result.put("manufacturerSpecificDataList", manufacturerDataList);
    447         result.put("manufacturerIdList", idList);
    448         ArrayList<String> serviceUuidList = new ArrayList<String>();
    449         ArrayList<String> serviceDataList = new ArrayList<String>();
    450         if (scanResult.getScanRecord().getServiceData() != null) {
    451             Map<ParcelUuid, byte[]> serviceDataMap = scanResult.getScanRecord()
    452                     .getServiceData();
    453             for (ParcelUuid serviceUuid : serviceDataMap.keySet()) {
    454                 serviceUuidList.add(serviceUuid.toString());
    455                 serviceDataList.add(ConvertUtils
    456                         .convertByteArrayToString(serviceDataMap
    457                                 .get(serviceUuid)));
    458             }
    459         }
    460         result.put("serviceUuidList", serviceUuidList);
    461         result.put("serviceDataList", serviceDataList);
    462         List<ParcelUuid> serviceUuids = scanResult.getScanRecord()
    463                 .getServiceUuids();
    464         String serviceUuidsString = "";
    465         if (serviceUuids != null && serviceUuids.size() > 0) {
    466             for (ParcelUuid uuid : serviceUuids) {
    467                 serviceUuidsString = serviceUuidsString + "," + uuid;
    468             }
    469         }
    470         result.put("serviceUuids", serviceUuidsString);
    471         result.put("scanRecord",
    472                 build(ConvertUtils.convertByteArrayToString(scanResult
    473                         .getScanRecord().getBytes())));
    474         result.put("deviceInfo", build(scanResult.getDevice()));
    475         return result;
    476     }
    477 
    478     private static JSONObject buildJsonBluetoothCodecConfig(BluetoothCodecConfig codecConfig)
    479             throws JSONException {
    480         JSONObject result = new JSONObject();
    481         result.put("codecType", codecConfig.getCodecType());
    482         result.put("sampleRate", codecConfig.getSampleRate());
    483         result.put("bitsPerSample", codecConfig.getBitsPerSample());
    484         result.put("channelMode", codecConfig.getChannelMode());
    485         result.put("codecSpecific1", codecConfig.getCodecSpecific1());
    486         return result;
    487     }
    488 
    489     private static JSONObject buildJsonBluetoothDevice(BluetoothDevice data)
    490             throws JSONException {
    491         JSONObject deviceInfo = new JSONObject();
    492         deviceInfo.put("address", data.getAddress());
    493         deviceInfo.put("state", data.getBondState());
    494         deviceInfo.put("name", data.getName());
    495         deviceInfo.put("type", data.getType());
    496         return deviceInfo;
    497     }
    498 
    499     private static Object buildJsonBluetoothGattCharacteristic(
    500             BluetoothGattCharacteristic data) throws JSONException {
    501         JSONObject result = new JSONObject();
    502         result.put("instanceId", data.getInstanceId());
    503         result.put("permissions", data.getPermissions());
    504         result.put("properties", data.getProperties());
    505         result.put("writeType", data.getWriteType());
    506         result.put("descriptorsList", build(data.getDescriptors()));
    507         result.put("uuid", data.getUuid().toString());
    508         result.put("value", build(data.getValue()));
    509 
    510         return result;
    511     }
    512 
    513     private static Object buildJsonBluetoothGattDescriptor(
    514             BluetoothGattDescriptor data) throws JSONException {
    515         JSONObject result = new JSONObject();
    516         result.put("instanceId", data.getInstanceId());
    517         result.put("permissions", data.getPermissions());
    518         result.put("characteristic", data.getCharacteristic());
    519         result.put("uuid", data.getUuid().toString());
    520         result.put("value", build(data.getValue()));
    521         return result;
    522     }
    523 
    524     private static Object buildJsonBluetoothGattService(
    525             BluetoothGattService data) throws JSONException {
    526         JSONObject result = new JSONObject();
    527         result.put("instanceId", data.getInstanceId());
    528         result.put("type", data.getType());
    529         result.put("gattCharacteristicList", build(data.getCharacteristics()));
    530         result.put("includedServices", build(data.getIncludedServices()));
    531         result.put("uuid", data.getUuid().toString());
    532         return result;
    533     }
    534 
    535     private static JSONObject buildJsonBundle(Bundle bundle)
    536             throws JSONException {
    537         JSONObject result = new JSONObject();
    538         for (String key : bundle.keySet()) {
    539             result.put(key, build(bundle.get(key)));
    540         }
    541         return result;
    542     }
    543 
    544     private static JSONObject buildJsonCellLocation(CellLocation cellLocation)
    545             throws JSONException {
    546         JSONObject result = new JSONObject();
    547         if (cellLocation instanceof GsmCellLocation) {
    548             GsmCellLocation location = (GsmCellLocation) cellLocation;
    549             result.put("lac", location.getLac());
    550             result.put("cid", location.getCid());
    551         }
    552         // TODO(damonkohler): Add support for CdmaCellLocation. Not supported
    553         // until API level 5.
    554         return result;
    555     }
    556 
    557     private static JSONObject buildDhcpInfo(DhcpInfo data) throws JSONException {
    558         JSONObject result = new JSONObject();
    559         result.put("ipAddress", data.ipAddress);
    560         result.put("dns1", data.dns1);
    561         result.put("dns2", data.dns2);
    562         result.put("gateway", data.gateway);
    563         result.put("serverAddress", data.serverAddress);
    564         result.put("leaseDuration", data.leaseDuration);
    565         return result;
    566     }
    567 
    568     private static JSONObject buildJsonEvent(Event event) throws JSONException {
    569         JSONObject result = new JSONObject();
    570         result.put("name", event.getName());
    571         result.put("data", build(event.getData()));
    572         result.put("time", event.getCreationTime());
    573         return result;
    574     }
    575 
    576     private static JSONObject buildJsonIntent(Intent data) throws JSONException {
    577         JSONObject result = new JSONObject();
    578         result.put("data", data.getDataString());
    579         result.put("type", data.getType());
    580         result.put("extras", build(data.getExtras()));
    581         result.put("categories", build(data.getCategories()));
    582         result.put("action", data.getAction());
    583         ComponentName component = data.getComponent();
    584         if (component != null) {
    585             result.put("packagename", component.getPackageName());
    586             result.put("classname", component.getClassName());
    587         }
    588         result.put("flags", data.getFlags());
    589         return result;
    590     }
    591 
    592     private static <T> JSONArray buildJsonList(final List<T> list)
    593             throws JSONException {
    594         JSONArray result = new JSONArray();
    595         for (T item : list) {
    596             result.put(build(item));
    597         }
    598         return result;
    599     }
    600 
    601     private static JSONObject buildJsonLocation(Location location)
    602             throws JSONException {
    603         JSONObject result = new JSONObject();
    604         result.put("altitude", location.getAltitude());
    605         result.put("latitude", location.getLatitude());
    606         result.put("longitude", location.getLongitude());
    607         result.put("time", location.getTime());
    608         result.put("accuracy", location.getAccuracy());
    609         result.put("speed", location.getSpeed());
    610         result.put("provider", location.getProvider());
    611         result.put("bearing", location.getBearing());
    612         return result;
    613     }
    614 
    615     private static JSONObject buildJsonMap(Map<String, ?> map)
    616             throws JSONException {
    617         JSONObject result = new JSONObject();
    618         for (Entry<String, ?> entry : map.entrySet()) {
    619             String key = entry.getKey();
    620             if (key == null) {
    621                 key = "";
    622             }
    623             result.put(key, build(entry.getValue()));
    624         }
    625         return result;
    626     }
    627 
    628     private static JSONObject buildJsonPlaybackState(PlaybackState playbackState)
    629             throws JSONException {
    630         JSONObject result = new JSONObject();
    631         result.put("state", playbackState.getState());
    632         result.put("position", playbackState.getPosition());
    633         result.put("speed", playbackState.getPlaybackSpeed());
    634         result.put("actions", playbackState.getActions());
    635         return result;
    636     }
    637 
    638     private static JSONObject buildJsonScanResult(ScanResult scanResult)
    639             throws JSONException {
    640         JSONObject result = new JSONObject();
    641         result.put("BSSID", scanResult.BSSID);
    642         result.put("SSID", scanResult.SSID);
    643         result.put("frequency", scanResult.frequency);
    644         result.put("level", scanResult.level);
    645         result.put("capabilities", scanResult.capabilities);
    646         result.put("timestamp", scanResult.timestamp);
    647         result.put("centerFreq0", scanResult.centerFreq0);
    648         result.put("centerFreq1", scanResult.centerFreq1);
    649         result.put("channelWidth", scanResult.channelWidth);
    650         result.put("distanceCm", scanResult.distanceCm);
    651         result.put("distanceSdCm", scanResult.distanceSdCm);
    652         result.put("is80211McRTTResponder", scanResult.is80211mcResponder());
    653         result.put("passpointNetwork", scanResult.isPasspointNetwork());
    654         result.put("numUsage", scanResult.numUsage);
    655         result.put("seen", scanResult.seen);
    656         result.put("untrusted", scanResult.untrusted);
    657         result.put("operatorFriendlyName", scanResult.operatorFriendlyName);
    658         result.put("venueName", scanResult.venueName);
    659         if (scanResult.informationElements != null) {
    660             JSONArray infoEles = new JSONArray();
    661             for (ScanResult.InformationElement ie : scanResult.informationElements) {
    662                 JSONObject infoEle = new JSONObject();
    663                 infoEle.put("id", ie.id);
    664                 infoEle.put("bytes", Base64Codec.encodeBase64String(ie.bytes));
    665                 infoEles.put(infoEle);
    666             }
    667             result.put("InformationElements", infoEles);
    668         } else {
    669             result.put("InformationElements", null);
    670         }
    671         if (scanResult.radioChainInfos != null) {
    672             JSONArray radioChainEles = new JSONArray();
    673             for (ScanResult.RadioChainInfo item : scanResult.radioChainInfos) {
    674                 JSONObject radioChainEle = new JSONObject();
    675                 radioChainEle.put("id", item.id);
    676                 radioChainEle.put("level", item.level);
    677                 radioChainEles.put(radioChainEle);
    678             }
    679             result.put("radioChainInfos", radioChainEles);
    680         } else {
    681             result.put("radioChainInfos", null);
    682         }
    683         return result;
    684     }
    685 
    686     private static JSONObject buildJsonScanData(ScanData scanData)
    687             throws JSONException {
    688         JSONObject result = new JSONObject();
    689         result.put("Id", scanData.getId());
    690         result.put("Flags", scanData.getFlags());
    691         JSONArray scanResults = new JSONArray();
    692         for (ScanResult sr : scanData.getResults()) {
    693             scanResults.put(buildJsonScanResult(sr));
    694         }
    695         result.put("ScanResults", scanResults);
    696         return result;
    697     }
    698 
    699     private static JSONObject buildJsonWifiInfo(WifiInfo data)
    700             throws JSONException {
    701         JSONObject result = new JSONObject();
    702         result.put("hidden_ssid", data.getHiddenSSID());
    703         result.put("ip_address", data.getIpAddress());
    704         result.put("link_speed", data.getLinkSpeed());
    705         result.put("network_id", data.getNetworkId());
    706         result.put("rssi", data.getRssi());
    707         result.put("BSSID", data.getBSSID());
    708         result.put("mac_address", data.getMacAddress());
    709         result.put("frequency", data.getFrequency());
    710         // Trim the double quotes if exist
    711         String ssid = data.getSSID();
    712         if (ssid.charAt(0) == '"'
    713                 && ssid.charAt(ssid.length() - 1) == '"') {
    714             result.put("SSID", ssid.substring(1, ssid.length() - 1));
    715         } else {
    716             result.put("SSID", ssid);
    717         }
    718         String supplicantState = "";
    719         switch (data.getSupplicantState()) {
    720             case ASSOCIATED:
    721                 supplicantState = "associated";
    722                 break;
    723             case ASSOCIATING:
    724                 supplicantState = "associating";
    725                 break;
    726             case COMPLETED:
    727                 supplicantState = "completed";
    728                 break;
    729             case DISCONNECTED:
    730                 supplicantState = "disconnected";
    731                 break;
    732             case DORMANT:
    733                 supplicantState = "dormant";
    734                 break;
    735             case FOUR_WAY_HANDSHAKE:
    736                 supplicantState = "four_way_handshake";
    737                 break;
    738             case GROUP_HANDSHAKE:
    739                 supplicantState = "group_handshake";
    740                 break;
    741             case INACTIVE:
    742                 supplicantState = "inactive";
    743                 break;
    744             case INVALID:
    745                 supplicantState = "invalid";
    746                 break;
    747             case SCANNING:
    748                 supplicantState = "scanning";
    749                 break;
    750             case UNINITIALIZED:
    751                 supplicantState = "uninitialized";
    752                 break;
    753             default:
    754                 supplicantState = null;
    755         }
    756         result.put("supplicant_state", build(supplicantState));
    757         result.put("is_5ghz", data.is5GHz());
    758         result.put("is_24ghz", data.is24GHz());
    759         return result;
    760     }
    761 
    762     private static JSONObject buildNeighboringCellInfo(NeighboringCellInfo data)
    763             throws JSONException {
    764         JSONObject result = new JSONObject();
    765         result.put("cid", data.getCid());
    766         result.put("rssi", data.getRssi());
    767         result.put("lac", data.getLac());
    768         result.put("psc", data.getPsc());
    769         String networkType = TelephonyUtils.getNetworkTypeString(data.getNetworkType());
    770         result.put("network_type", build(networkType));
    771         return result;
    772     }
    773 
    774     private static JSONObject buildCellInfo(CellInfo data) throws JSONException {
    775         JSONObject result = new JSONObject();
    776         result.put("registered", data.isRegistered());
    777         result.put("connection_status", data.getCellConnectionStatus());
    778         result.put("timestamp", data.getTimeStamp());
    779 
    780         CellIdentity cid = data.getCellIdentity();
    781         result.put("channel_number", cid.getChannelNumber());
    782         result.put("alpha_long", cid.getOperatorAlphaLong());
    783         result.put("alpha_short", cid.getOperatorAlphaShort());
    784 
    785         if (data instanceof CellInfoLte) {
    786             return buildCellInfoLte((CellInfoLte) data, result);
    787         } else if (data instanceof CellInfoWcdma) {
    788             return buildCellInfoWcdma((CellInfoWcdma) data, result);
    789         } else if (data instanceof CellInfoTdscdma) {
    790             return buildCellInfoTdscdma((CellInfoTdscdma) data, result);
    791         } else if (data instanceof CellInfoGsm) {
    792             return buildCellInfoGsm((CellInfoGsm) data, result);
    793         } else if (data instanceof CellInfoCdma) {
    794             return buildCellInfoCdma((CellInfoCdma) data, result);
    795         }
    796         return result;
    797     }
    798 
    799     private static JSONObject buildCellInfoLte(CellInfoLte data, JSONObject result)
    800             throws JSONException {
    801         result.put("rat", "lte");
    802         CellIdentityLte cellidentity = data.getCellIdentity();
    803         CellSignalStrengthLte signalstrength = data.getCellSignalStrength();
    804         result.put("mcc", cellidentity.getMcc());
    805         result.put("mnc", cellidentity.getMnc());
    806         result.put("mcc_string", cellidentity.getMccString());
    807         result.put("mnc_string", cellidentity.getMncString());
    808         result.put("cid", cellidentity.getCi());
    809         result.put("pcid", cellidentity.getPci());
    810         result.put("tac", cellidentity.getTac());
    811         result.put("bandwidth", cellidentity.getBandwidth());
    812         result.put("rsrp", signalstrength.getDbm());
    813         result.put("asulevel", signalstrength.getAsuLevel());
    814         result.put("timing_advance", signalstrength.getTimingAdvance());
    815         return result;
    816     }
    817 
    818     private static JSONObject buildCellInfoGsm(CellInfoGsm data, JSONObject result)
    819             throws JSONException {
    820         result.put("rat", "gsm");
    821         CellIdentityGsm cellidentity = data.getCellIdentity();
    822         CellSignalStrengthGsm signalstrength = data.getCellSignalStrength();
    823         result.put("mcc", cellidentity.getMcc());
    824         result.put("mnc", cellidentity.getMnc());
    825         result.put("mcc_string", cellidentity.getMccString());
    826         result.put("mnc_string", cellidentity.getMncString());
    827         result.put("cid", cellidentity.getCid());
    828         result.put("lac", cellidentity.getLac());
    829         result.put("bsic", cellidentity.getBsic());
    830         result.put("arfcn", cellidentity.getArfcn());
    831         result.put("signal_strength", signalstrength.getDbm());
    832         result.put("asulevel", signalstrength.getAsuLevel());
    833         return result;
    834     }
    835 
    836     private static JSONObject buildCellInfoWcdma(CellInfoWcdma data, JSONObject result)
    837             throws JSONException {
    838         result.put("rat", "wcdma");
    839         CellIdentityWcdma cellidentity = data.getCellIdentity();
    840         CellSignalStrengthWcdma signalstrength = data.getCellSignalStrength();
    841         result.put("mcc", cellidentity.getMcc());
    842         result.put("mnc", cellidentity.getMnc());
    843         result.put("mcc_string", cellidentity.getMccString());
    844         result.put("mnc_string", cellidentity.getMncString());
    845         result.put("cid", cellidentity.getCid());
    846         result.put("lac", cellidentity.getLac());
    847         result.put("psc", cellidentity.getPsc());
    848         result.put("signal_strength", signalstrength.getDbm());
    849         result.put("asulevel", signalstrength.getAsuLevel());
    850         return result;
    851     }
    852 
    853     private static JSONObject buildCellInfoTdscdma(CellInfoTdscdma data, JSONObject result)
    854             throws JSONException {
    855         result.put("rat", "tdscdma");
    856         CellIdentityTdscdma cellidentity = data.getCellIdentity();
    857         CellSignalStrengthTdscdma signalstrength = data.getCellSignalStrength();
    858         result.put("mcc_string", cellidentity.getMccString());
    859         result.put("mnc_string", cellidentity.getMncString());
    860         result.put("cid", cellidentity.getCid());
    861         result.put("lac", cellidentity.getLac());
    862         result.put("cpid", cellidentity.getCpid());
    863         result.put("signal_strength", signalstrength.getDbm());
    864         result.put("asulevel", signalstrength.getAsuLevel());
    865         return result;
    866     }
    867 
    868     private static JSONObject buildCellInfoCdma(CellInfoCdma data, JSONObject result)
    869             throws JSONException {
    870         result.put("rat", "cdma");
    871         result.put("registered", data.isRegistered());
    872         CellIdentityCdma cellidentity = data.getCellIdentity();
    873         CellSignalStrengthCdma signalstrength = data.getCellSignalStrength();
    874         result.put("network_id", cellidentity.getNetworkId());
    875         result.put("system_id", cellidentity.getSystemId());
    876         result.put("basestation_id", cellidentity.getBasestationId());
    877         result.put("longitude", cellidentity.getLongitude());
    878         result.put("latitude", cellidentity.getLatitude());
    879         result.put("cdma_dbm", signalstrength.getCdmaDbm());
    880         result.put("cdma_ecio", signalstrength.getCdmaEcio());
    881         result.put("evdo_dbm", signalstrength.getEvdoDbm());
    882         result.put("evdo_ecio", signalstrength.getEvdoEcio());
    883         result.put("evdo_snr", signalstrength.getEvdoSnr());
    884         return result;
    885     }
    886 
    887     private static Object buildHttpURLConnection(HttpURLConnection data)
    888             throws JSONException {
    889         JSONObject con = new JSONObject();
    890         try {
    891             con.put("ResponseCode", data.getResponseCode());
    892             con.put("ResponseMessage", data.getResponseMessage());
    893         } catch (IOException e) {
    894             e.printStackTrace();
    895             return con;
    896         }
    897         con.put("ContentLength", data.getContentLength());
    898         con.put("ContentEncoding", data.getContentEncoding());
    899         con.put("ContentType", data.getContentType());
    900         con.put("Date", data.getDate());
    901         con.put("ReadTimeout", data.getReadTimeout());
    902         con.put("HeaderFields", buildJsonMap(data.getHeaderFields()));
    903         con.put("URL", buildURL(data.getURL()));
    904         return con;
    905     }
    906 
    907     private static Object buildNetwork(Network data) throws JSONException {
    908         JSONObject nw = new JSONObject();
    909         nw.put("netId", data.netId);
    910         return nw;
    911     }
    912 
    913     private static Object buildNetworkInfo(NetworkInfo data)
    914             throws JSONException {
    915         JSONObject info = new JSONObject();
    916         info.put("isAvailable", data.isAvailable());
    917         info.put("isConnected", data.isConnected());
    918         info.put("isFailover", data.isFailover());
    919         info.put("isRoaming", data.isRoaming());
    920         info.put("ExtraInfo", data.getExtraInfo());
    921         info.put("FailedReason", data.getReason());
    922         info.put("TypeName", data.getTypeName());
    923         info.put("SubtypeName", data.getSubtypeName());
    924         info.put("State", data.getState().name().toString());
    925         return info;
    926     }
    927 
    928     private static Object buildURL(URL data) throws JSONException {
    929         JSONObject url = new JSONObject();
    930         url.put("Authority", data.getAuthority());
    931         url.put("Host", data.getHost());
    932         url.put("Path", data.getPath());
    933         url.put("Port", data.getPort());
    934         url.put("Protocol", data.getProtocol());
    935         return url;
    936     }
    937 
    938     /**
    939      * Builds a json representation of a {@link DataUsageInfo}.
    940      * @param data The DataUsageInfo convert to JSON.
    941      * @return A JSONObject representation of a {@link DataUsageInfo}.
    942      * @throws JSONException
    943      */
    944     private static JSONObject buildDataUsageInfo(@NonNull DataUsageInfo data)
    945             throws JSONException {
    946         JSONObject usage = new JSONObject();
    947         usage.put("SubscriberId", data.subscriberId);
    948         usage.put("Period", data.period);
    949         usage.put("StartEpochMilli", data.startEpochMilli);
    950         usage.put("EndEpochMilli", data.endEpochMilli);
    951         usage.put("CycleStart", data.cycleStart);
    952         usage.put("CycleEnd", data.cycleEnd);
    953         usage.put("LimitLevel", data.limitLevel);
    954         usage.put("WarningLevel", data.warningLevel);
    955         usage.put("UsageLevel", data.usageLevel);
    956         usage.put("Uid", data.uId);
    957         return usage;
    958     }
    959 
    960     /**
    961      * Builds a json representation of a {@link PhoneAccount}.
    962      * @param data The PhoneAccount convert to JSON.
    963      * @return A JSONObject representation of a {@link PhoneAccount}.
    964      * @throws JSONException
    965      */
    966     private static JSONObject buildPhoneAccount(@NonNull PhoneAccount data)
    967             throws JSONException {
    968         JSONObject acct = new JSONObject();
    969         acct.put("Address", toNonNullString(data.getAddress(), Uri::toSafeString));
    970         acct.put("SubscriptionAddress", toNonNullString(data.getSubscriptionAddress(),
    971                 Uri::toSafeString));
    972         acct.put("Label", toNonNullString(data.getLabel()));
    973         acct.put("ShortDescription", toNonNullString(data.getShortDescription()));
    974         return acct;
    975     }
    976 
    977     private static Object buildPhoneAccountHandle(PhoneAccountHandle data)
    978             throws JSONException {
    979         JSONObject msg = new JSONObject();
    980         msg.put("id", data.getId());
    981         msg.put("ComponentName", data.getComponentName().flattenToString());
    982         return msg;
    983     }
    984 
    985     private static Object buildSubscriptionInfoRecord(SubscriptionInfo data)
    986             throws JSONException {
    987         JSONObject msg = new JSONObject();
    988         msg.put("subscriptionId", data.getSubscriptionId());
    989         msg.put("iccId", data.getIccId());
    990         msg.put("simSlotIndex", data.getSimSlotIndex());
    991         msg.put("displayName", data.getDisplayName());
    992         msg.put("nameSource", data.getNameSource());
    993         msg.put("iconTint", data.getIconTint());
    994         msg.put("number", data.getNumber());
    995         msg.put("dataRoaming", data.getDataRoaming());
    996         msg.put("mcc", data.getMcc());
    997         msg.put("mnc", data.getMnc());
    998         return msg;
    999     }
   1000 
   1001     private static Object buildPoint(Point data) throws JSONException {
   1002         JSONObject point = new JSONObject();
   1003         point.put("x", data.x);
   1004         point.put("y", data.y);
   1005         return point;
   1006     }
   1007 
   1008     private static Object buildRttCapabilities(RttCapabilities data)
   1009             throws JSONException {
   1010         JSONObject cap = new JSONObject();
   1011         cap.put("bwSupported", data.bwSupported);
   1012         cap.put("lciSupported", data.lciSupported);
   1013         cap.put("lcrSupported", data.lcrSupported);
   1014         cap.put("oneSidedRttSupported", data.oneSidedRttSupported);
   1015         cap.put("preambleSupported", data.preambleSupported);
   1016         cap.put("twoSided11McRttSupported", data.twoSided11McRttSupported);
   1017         return cap;
   1018     }
   1019 
   1020     private static Object buildSmsMessage(SmsMessage data) throws JSONException {
   1021         JSONObject msg = new JSONObject();
   1022         msg.put("originatingAddress", data.getOriginatingAddress());
   1023         msg.put("messageBody", data.getMessageBody());
   1024         return msg;
   1025     }
   1026 
   1027     private static JSONObject buildWifiActivityEnergyInfo(
   1028             WifiActivityEnergyInfo data) throws JSONException {
   1029         JSONObject result = new JSONObject();
   1030         result.put("ControllerEnergyUsed", data.getControllerEnergyUsed());
   1031         result.put("ControllerIdleTimeMillis",
   1032                 data.getControllerIdleTimeMillis());
   1033         result.put("ControllerRxTimeMillis", data.getControllerRxTimeMillis());
   1034         result.put("ControllerTxTimeMillis", data.getControllerTxTimeMillis());
   1035         result.put("StackState", data.getStackState());
   1036         result.put("TimeStamp", data.getTimeStamp());
   1037         return result;
   1038     }
   1039 
   1040     private static Object buildWifiConfiguration(WifiConfiguration data)
   1041             throws JSONException {
   1042         JSONObject config = new JSONObject();
   1043         config.put("networkId", data.networkId);
   1044         // Trim the double quotes if exist
   1045         if (data.SSID.charAt(0) == '"'
   1046                 && data.SSID.charAt(data.SSID.length() - 1) == '"') {
   1047             config.put("SSID", data.SSID.substring(1, data.SSID.length() - 1));
   1048         } else {
   1049             config.put("SSID", data.SSID);
   1050         }
   1051         config.put("BSSID", data.BSSID);
   1052         config.put("priority", data.priority);
   1053         config.put("hiddenSSID", data.hiddenSSID);
   1054         config.put("FQDN", data.FQDN);
   1055         config.put("providerFriendlyName", data.providerFriendlyName);
   1056         config.put("isPasspoint", data.isPasspoint());
   1057         config.put("hiddenSSID", data.hiddenSSID);
   1058         if (data.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
   1059             config.put("security", "SAE");
   1060         } else if (data.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
   1061             config.put("security", "PSK");
   1062         } else if (data.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)) {
   1063             config.put("security", "OWE");
   1064         } else if (data.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192)) {
   1065             config.put("security", "SUITE_B_192");
   1066         } else if (data.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
   1067             config.put("security", "EAP");
   1068         } else if (data.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
   1069             config.put("security", "NONE");
   1070         }
   1071         if (data.status == WifiConfiguration.Status.CURRENT) {
   1072             config.put("status", "CURRENT");
   1073         } else if (data.status == WifiConfiguration.Status.DISABLED) {
   1074             config.put("status", "DISABLED");
   1075         } else if (data.status == WifiConfiguration.Status.ENABLED) {
   1076             config.put("status", "ENABLED");
   1077         } else {
   1078             config.put("status", "UNKNOWN");
   1079         }
   1080         // config.put("enterpriseConfig", buildWifiEnterpriseConfig(data.enterpriseConfig));
   1081         return config;
   1082     }
   1083 
   1084     private static Object buildWifiEnterpriseConfig(WifiEnterpriseConfig data)
   1085             throws JSONException, CertificateEncodingException {
   1086         JSONObject config = new JSONObject();
   1087         config.put(WifiEnterpriseConfig.PLMN_KEY, data.getPlmn());
   1088         config.put(WifiEnterpriseConfig.REALM_KEY, data.getRealm());
   1089         config.put(WifiEnterpriseConfig.EAP_KEY, data.getEapMethod());
   1090         config.put(WifiEnterpriseConfig.PHASE2_KEY, data.getPhase2Method());
   1091         config.put(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, data.getAltSubjectMatch());
   1092         X509Certificate caCert = data.getCaCertificate();
   1093         String caCertString = Base64.encodeToString(caCert.getEncoded(), Base64.DEFAULT);
   1094         config.put(WifiEnterpriseConfig.CA_CERT_KEY, caCertString);
   1095         X509Certificate clientCert = data.getClientCertificate();
   1096         String clientCertString = Base64.encodeToString(clientCert.getEncoded(), Base64.DEFAULT);
   1097         config.put(WifiEnterpriseConfig.CLIENT_CERT_KEY, clientCertString);
   1098         PrivateKey pk = data.getClientPrivateKey();
   1099         String privateKeyString = Base64.encodeToString(pk.getEncoded(), Base64.DEFAULT);
   1100         config.put(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, privateKeyString);
   1101         config.put(WifiEnterpriseConfig.PASSWORD_KEY, data.getPassword());
   1102         return config;
   1103     }
   1104 
   1105     private static JSONObject buildWpsInfo(WpsInfo data)
   1106             throws JSONException {
   1107         JSONObject wpsInfo = new JSONObject();
   1108         wpsInfo.put("setup", data.setup);
   1109         wpsInfo.put("BSSID", data.BSSID);
   1110         wpsInfo.put("pin", data.pin);
   1111         return wpsInfo;
   1112     }
   1113 
   1114     private static JSONObject buildWifiP2pConfig(WifiP2pConfig data)
   1115             throws JSONException {
   1116         JSONObject wifiP2pConfig = new JSONObject();
   1117         wifiP2pConfig.put("deviceAddress", data.deviceAddress);
   1118         wifiP2pConfig.put("wpsInfo", buildWpsInfo(data.wps));
   1119         wifiP2pConfig.put("groupOwnerIntent", data.groupOwnerIntent);
   1120         wifiP2pConfig.put("netId", data.netId);
   1121         return wifiP2pConfig;
   1122     }
   1123 
   1124     private static JSONObject buildWifiP2pDevice(WifiP2pDevice data)
   1125             throws JSONException {
   1126         JSONObject deviceInfo = new JSONObject();
   1127         deviceInfo.put("Name", data.deviceName);
   1128         deviceInfo.put("Address", data.deviceAddress);
   1129         deviceInfo.put("GroupCapability", data.groupCapability);
   1130         return deviceInfo;
   1131     }
   1132 
   1133     private static JSONObject buildWifiP2pGroup(WifiP2pGroup data)
   1134             throws JSONException {
   1135         JSONObject group = new JSONObject();
   1136         Log.d("build p2p group.");
   1137         group.put("ClientList", build(data.getClientList()));
   1138         group.put("Interface", data.getInterface());
   1139         group.put("Networkname", data.getNetworkName());
   1140         group.put("Owner", data.getOwner());
   1141         group.put("Passphrase", data.getPassphrase());
   1142         group.put("NetworkId", data.getNetworkId());
   1143         return group;
   1144     }
   1145 
   1146     private static JSONObject buildWifiP2pInfo(WifiP2pInfo data)
   1147             throws JSONException {
   1148         JSONObject info = new JSONObject();
   1149         Log.d("build p2p info.");
   1150         info.put("groupFormed", data.groupFormed);
   1151         info.put("isGroupOwner", data.isGroupOwner);
   1152         info.put("groupOwnerAddress", data.groupOwnerAddress);
   1153         return info;
   1154     }
   1155 
   1156     private static JSONObject buildLinkProperties(LinkProperties data) throws JSONException {
   1157         JSONObject info = new JSONObject();
   1158         info.put("InterfaceName", data.getInterfaceName());
   1159         info.put("LinkAddresses", build(data.getLinkAddresses()));
   1160         info.put("DnsServers", build(data.getDnsServers()));
   1161         info.put("Domains", data.getDomains());
   1162         info.put("Mtu", data.getMtu());
   1163         info.put("Routes", build(data.getRoutes()));
   1164         info.put("IsPrivateDnsActive", data.isPrivateDnsActive());
   1165         info.put("PrivateDnsServerName", data.getPrivateDnsServerName());
   1166         info.put("ValidatedPrivateDnsServers", build(data.getValidatedPrivateDnsServers()));
   1167         return info;
   1168     }
   1169 
   1170     private static JSONObject buildLinkAddress(LinkAddress data) throws JSONException {
   1171         JSONObject info = new JSONObject();
   1172         info.put("Address", build(data.getAddress()));
   1173         info.put("PrefixLength", data.getPrefixLength());
   1174         info.put("Scope", data.getScope());
   1175         info.put("Flags", data.getFlags());
   1176         return info;
   1177     }
   1178 
   1179     private static JSONObject buildRouteInfo(RouteInfo data) throws JSONException {
   1180         JSONObject info = new JSONObject();
   1181         info.put("Destination", build(data.getDestination()));
   1182         info.put("Gateway", build(data.getGateway()));
   1183         info.put("Interface", data.getInterface());
   1184         info.put("IsDefaultRoute", data.isDefaultRoute());
   1185         return info;
   1186     }
   1187 
   1188     private static JSONObject buildIpPrefix(IpPrefix data) throws JSONException {
   1189         JSONObject info = new JSONObject();
   1190         info.put("Address", data.getAddress());
   1191         info.put("PrefixLength", data.getPrefixLength());
   1192         return info;
   1193     }
   1194 
   1195     private static JSONObject buildProxyInfo(ProxyInfo data) throws JSONException {
   1196         JSONObject info = new JSONObject();
   1197         info.put("Hostname", data.getHost());
   1198         info.put("Port", data.getPort());
   1199         info.put("ExclList", data.getExclusionListAsString());
   1200         info.put("PacUrl", data.getPacFileUrl().toString());
   1201         return info;
   1202     }
   1203 
   1204     private static <T> JSONObject buildCallEvent(InCallServiceImpl.CallEvent<T> callEvent)
   1205             throws JSONException {
   1206         JSONObject jsonEvent = new JSONObject();
   1207         jsonEvent.put("CallId", callEvent.getCallId());
   1208         jsonEvent.put("Event", build(callEvent.getEvent()));
   1209         return jsonEvent;
   1210     }
   1211 
   1212     private static JSONObject buildUri(Uri uri) throws JSONException {
   1213         return new JSONObject().put("Uri", build((uri != null) ? uri.toString() : ""));
   1214     }
   1215 
   1216     private static JSONObject buildCallDetails(Call.Details details) throws JSONException {
   1217 
   1218         JSONObject callDetails = new JSONObject();
   1219 
   1220         callDetails.put("Handle", buildUri(details.getHandle()));
   1221         callDetails.put("HandlePresentation",
   1222                 build(InCallServiceImpl.getCallPresentationInfoString(
   1223                         details.getHandlePresentation())));
   1224         callDetails.put("CallerDisplayName", build(details.getCallerDisplayName()));
   1225 
   1226         // TODO AccountHandle
   1227         // callDetails.put("AccountHandle", build(""));
   1228 
   1229         callDetails.put("Capabilities",
   1230                 build(InCallServiceImpl.getCallCapabilitiesString(details.getCallCapabilities())));
   1231 
   1232         callDetails.put("Properties",
   1233                 build(InCallServiceImpl.getCallPropertiesString(details.getCallProperties())));
   1234 
   1235         // TODO Parse fields in Disconnect Cause
   1236         callDetails.put("DisconnectCause", build((details.getDisconnectCause() != null) ? details
   1237                 .getDisconnectCause().toString() : ""));
   1238         callDetails.put("ConnectTimeMillis", build(details.getConnectTimeMillis()));
   1239 
   1240         // TODO: GatewayInfo
   1241         // callDetails.put("GatewayInfo", build(""));
   1242 
   1243         callDetails.put("VideoState",
   1244                 build(InCallServiceImpl.getVideoCallStateString(details.getVideoState())));
   1245 
   1246         // TODO: StatusHints
   1247         // callDetails.put("StatusHints", build(""));
   1248 
   1249         callDetails.put("Extras", build(details.getExtras()));
   1250 
   1251         return callDetails;
   1252     }
   1253 
   1254     private static JSONObject buildCall(Call call) throws JSONException {
   1255 
   1256         JSONObject callInfo = new JSONObject();
   1257 
   1258         callInfo.put("Parent", build(InCallServiceImpl.getCallId(call)));
   1259 
   1260         // TODO:Make a function out of this for consistency
   1261         ArrayList<String> children = new ArrayList<String>();
   1262         for (Call child : call.getChildren()) {
   1263             children.add(InCallServiceImpl.getCallId(child));
   1264         }
   1265         callInfo.put("Children", build(children));
   1266 
   1267         // TODO:Make a function out of this for consistency
   1268         ArrayList<String> conferenceables = new ArrayList<String>();
   1269         for (Call conferenceable : call.getChildren()) {
   1270             children.add(InCallServiceImpl.getCallId(conferenceable));
   1271         }
   1272         callInfo.put("ConferenceableCalls", build(conferenceables));
   1273 
   1274         callInfo.put("State", build(InCallServiceImpl.getCallStateString(call.getState())));
   1275         callInfo.put("CannedTextResponses", build(call.getCannedTextResponses()));
   1276         callInfo.put("VideoCall", InCallServiceImpl.getVideoCallId(call.getVideoCall()));
   1277         callInfo.put("Details", build(call.getDetails()));
   1278 
   1279         return callInfo;
   1280     }
   1281 
   1282     private static JSONObject buildVideoProfile(VideoProfile videoProfile) throws JSONException {
   1283         JSONObject profile = new JSONObject();
   1284 
   1285         profile.put("VideoState",
   1286                 InCallServiceImpl.getVideoCallStateString(videoProfile.getVideoState()));
   1287         profile.put("VideoQuality",
   1288                 InCallServiceImpl.getVideoCallQualityString(videoProfile.getQuality()));
   1289 
   1290         return profile;
   1291     }
   1292 
   1293     private static JSONObject buildCameraCapabilities(CameraCapabilities cameraCapabilities)
   1294             throws JSONException {
   1295         JSONObject capabilities = new JSONObject();
   1296 
   1297         capabilities.put("Height", build(cameraCapabilities.getHeight()));
   1298         capabilities.put("Width", build(cameraCapabilities.getWidth()));
   1299         capabilities.put("ZoomSupported", build(cameraCapabilities.isZoomSupported()));
   1300         capabilities.put("MaxZoom", build(cameraCapabilities.getMaxZoom()));
   1301 
   1302         return capabilities;
   1303     }
   1304 
   1305     private static JSONObject buildVoLteServiceStateEvent(
   1306             VoLteServiceState volteInfo)
   1307             throws JSONException {
   1308         JSONObject info = new JSONObject();
   1309         info.put(TelephonyConstants.VoLteServiceStateContainer.SRVCC_STATE,
   1310                 TelephonyUtils.getSrvccStateString(volteInfo.getSrvccState()));
   1311         return info;
   1312     }
   1313 
   1314     private static JSONObject buildLegacyVpnInfo(LegacyVpnInfo data) throws JSONException {
   1315         JSONObject info = new JSONObject();
   1316         if (data == null) {
   1317             return info;
   1318         }
   1319         info.put("state", data.state);
   1320         info.put("key", data.key);
   1321         String intentStr = "";
   1322         if (data.intent != null) {
   1323             intentStr = data.intent.toString();
   1324         }
   1325         info.put("intent", intentStr);
   1326         return info;
   1327     }
   1328 
   1329     private static JSONObject buildModemActivityInfo(ModemActivityInfo modemInfo)
   1330             throws JSONException {
   1331         JSONObject info = new JSONObject();
   1332 
   1333         info.put("Timestamp", modemInfo.getTimestamp());
   1334         info.put("SleepTimeMs", modemInfo.getSleepTimeMillis());
   1335         info.put("IdleTimeMs", modemInfo.getIdleTimeMillis());
   1336         // convert from int[] to List<Integer> for proper JSON translation
   1337         int[] txTimes = modemInfo.getTxTimeMillis();
   1338         List<Integer> tmp = new ArrayList<Integer>(txTimes.length);
   1339         for (int val : txTimes) {
   1340             tmp.add(val);
   1341         }
   1342         info.put("TxTimeMs", build(tmp));
   1343         info.put("RxTimeMs", modemInfo.getRxTimeMillis());
   1344         info.put("EnergyUsedMw", modemInfo.getEnergyUsed());
   1345         return info;
   1346     }
   1347 
   1348     private static JSONObject buildSignalStrength(SignalStrength signalStrength)
   1349             throws JSONException {
   1350         JSONObject info = new JSONObject();
   1351         info.put(TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM,
   1352                 signalStrength.getGsmSignalStrength());
   1353         info.put(
   1354                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM_DBM,
   1355                 signalStrength.getGsmDbm());
   1356         info.put(
   1357                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM_LEVEL,
   1358                 signalStrength.getGsmLevel());
   1359         info.put(
   1360                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM_ASU_LEVEL,
   1361                 signalStrength.getGsmAsuLevel());
   1362         info.put(
   1363                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM_BIT_ERROR_RATE,
   1364                 signalStrength.getGsmBitErrorRate());
   1365         info.put(
   1366                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_CDMA_DBM,
   1367                 signalStrength.getCdmaDbm());
   1368         info.put(
   1369                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_CDMA_LEVEL,
   1370                 signalStrength.getCdmaLevel());
   1371         info.put(
   1372                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_CDMA_ASU_LEVEL,
   1373                 signalStrength.getCdmaAsuLevel());
   1374         info.put(
   1375                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_CDMA_ECIO,
   1376                 signalStrength.getCdmaEcio());
   1377         info.put(
   1378                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_EVDO_DBM,
   1379                 signalStrength.getEvdoDbm());
   1380         info.put(
   1381                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_EVDO_ECIO,
   1382                 signalStrength.getEvdoEcio());
   1383         info.put(TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LTE,
   1384                 signalStrength.getLteSignalStrength());
   1385         info.put(
   1386                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LTE_DBM,
   1387                 signalStrength.getLteDbm());
   1388         info.put(
   1389                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LTE_LEVEL,
   1390                 signalStrength.getLteLevel());
   1391         info.put(
   1392                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LTE_ASU_LEVEL,
   1393                 signalStrength.getLteAsuLevel());
   1394         info.put(
   1395                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LEVEL,
   1396                 signalStrength.getLevel());
   1397         info.put(
   1398                 TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_ASU_LEVEL,
   1399                 signalStrength.getAsuLevel());
   1400         info.put(TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_DBM,
   1401                 signalStrength.getDbm());
   1402         return info;
   1403     }
   1404 
   1405     public static JSONObject buildServiceState(ServiceState ss) throws JSONException {
   1406         JSONObject info = new JSONObject();
   1407 
   1408     info.put(TelephonyConstants.ServiceStateContainer.VOICE_REG_STATE,
   1409             TelephonyUtils.getNetworkStateString(ss.getVoiceRegState()));
   1410     info.put(TelephonyConstants.ServiceStateContainer.VOICE_NETWORK_TYPE,
   1411             TelephonyUtils.getNetworkTypeString(ss.getVoiceNetworkType()));
   1412     info.put(TelephonyConstants.ServiceStateContainer.DATA_REG_STATE,
   1413             TelephonyUtils.getNetworkStateString(ss.getDataRegState()));
   1414     info.put(TelephonyConstants.ServiceStateContainer.DATA_NETWORK_TYPE,
   1415             TelephonyUtils.getNetworkTypeString(ss.getDataNetworkType()));
   1416     info.put(TelephonyConstants.ServiceStateContainer.OPERATOR_NAME, ss.getOperatorAlphaLong());
   1417     info.put(TelephonyConstants.ServiceStateContainer.OPERATOR_ID, ss.getOperatorNumeric());
   1418     info.put(TelephonyConstants.ServiceStateContainer.IS_MANUAL_NW_SELECTION,
   1419             ss.getIsManualSelection());
   1420     info.put(TelephonyConstants.ServiceStateContainer.ROAMING, ss.getRoaming());
   1421     info.put(TelephonyConstants.ServiceStateContainer.IS_EMERGENCY_ONLY, ss.isEmergencyOnly());
   1422     info.put(TelephonyConstants.ServiceStateContainer.NETWORK_ID, ss.getCdmaNetworkId());
   1423     info.put(TelephonyConstants.ServiceStateContainer.SYSTEM_ID, ss.getCdmaSystemId());
   1424     info.put(TelephonyConstants.ServiceStateContainer.SERVICE_STATE,
   1425             TelephonyUtils.getNetworkStateString(ss.getState()));
   1426     info.put(TelephonyConstants.ServiceStateContainer.CHANNEL_NUMBER, ss.getChannelNumber());
   1427     info.put(TelephonyConstants.ServiceStateContainer.CELL_BANDWIDTHS,
   1428             ss.getCellBandwidths() != null
   1429                     ? new JSONArray(ss.getCellBandwidths())
   1430                     : JSONObject.NULL);
   1431     info.put(TelephonyConstants.ServiceStateContainer.DUPLEX_MODE, ss.getDuplexMode());
   1432     info.put(TelephonyConstants.ServiceStateContainer.VOICE_ROAMING_TYPE,
   1433             ss.getVoiceRoamingType());
   1434     info.put(TelephonyConstants.ServiceStateContainer.DATA_ROAMING_TYPE,
   1435             ss.getDataRoamingType());
   1436     info.put(TelephonyConstants.ServiceStateContainer.VOICE_OPERATOR_ALPHA_LONG,
   1437             ss.getVoiceOperatorAlphaLong());
   1438     info.put(TelephonyConstants.ServiceStateContainer.VOICE_OPERATOR_ALPHA_SHORT,
   1439             ss.getVoiceOperatorAlphaShort());
   1440     info.put(TelephonyConstants.ServiceStateContainer.VOICE_OPERATOR_NUMERIC,
   1441             ss.getVoiceOperatorNumeric());
   1442     info.put(TelephonyConstants.ServiceStateContainer.DATA_OPERATOR_ALPHA_LONG,
   1443             ss.getDataOperatorAlphaLong());
   1444     info.put(TelephonyConstants.ServiceStateContainer.DATA_OPERATOR_ALPHA_SHORT,
   1445             ss.getDataOperatorAlphaShort());
   1446     info.put(TelephonyConstants.ServiceStateContainer.DATA_OPERATOR_NUMERIC,
   1447             ss.getDataOperatorNumeric());
   1448     info.put(TelephonyConstants.ServiceStateContainer.VOICE_RADIO_TECHNOLOGY,
   1449             ss.getRilVoiceRadioTechnology());
   1450     info.put(TelephonyConstants.ServiceStateContainer.DATA_RADIO_TECHNOLOGY,
   1451             ss.getRilDataRadioTechnology());
   1452     info.put(TelephonyConstants.ServiceStateContainer.CSS_INDICATOR, ss.getCssIndicator());
   1453     info.put(TelephonyConstants.ServiceStateContainer.CDMA_ROAMING_INDICATOR,
   1454             ss.getCdmaRoamingIndicator());
   1455     info.put(TelephonyConstants.ServiceStateContainer.CDMA_DEFAULT_ROAMING_INDICATOR,
   1456             ss.getCdmaDefaultRoamingIndicator());
   1457     info.put(TelephonyConstants.ServiceStateContainer.IS_DATA_ROAMING_FROM_REGISTRATION,
   1458             ss.getDataRoamingFromRegistration());
   1459     info.put(TelephonyConstants.ServiceStateContainer.IS_USING_CARRIER_AGGREGATION,
   1460             ss.isUsingCarrierAggregation());
   1461     info.put(TelephonyConstants.ServiceStateContainer.LTE_EARFCN_RSRP_BOOST,
   1462             ss.getLteEarfcnRsrpBoost());
   1463     return info;
   1464     }
   1465 
   1466     private JsonBuilder() {
   1467         // This is a utility class.
   1468     }
   1469 }
   1470