How to directly access WifiService and androidwifiservice at the android framework layer from C ++ code
After all, the service at the Java layer is the encapsulation of the binder at the C ++ layer. In principle, it is entirely possible to directly access the service at the android framework layer through the C ++ code, this article uses WifiService as an example to explain how to implement this function.
To put it bluntly, go directly to the Code:
WifiTest. cpp
#include <sys/types.h>#include <unistd.h>#include <grp.h>#include <binder/IPCThreadState.h>#include <binder/ProcessState.h>#include <binder/IServiceManager.h>#include <utils/Log.h>#include <utils/String16.h>//#include <utils/Vector.h>#include <utils/List.h>#include <utils/PropertyMap.h>using namespace android;#define WIFI_SERVICE "wifi"const String16 WIFI_DESCRIPTOR("android.net.wifi.IWifiManager");class ScanResult{private: ScanResult& operator=(const ScanResult& o);public: ScanResult(const ScanResult& o): mSsid(o.mSsid),mBssid(o.mBssid),mCaps(o.mCaps),mLevel(o.mLevel),mFrequency(o.mFrequency),mTimestamp(o.mTimestamp) { } ScanResult(String8 ssid,String16 bssid,String16 caps,int level,int freq,int64_t timeStamp): mSsid(ssid),mBssid(bssid),mCaps(caps),mLevel(level),mFrequency(freq),mTimestamp(timeStamp) { } void dump() { char temp[130]; int size; memset(temp,0,sizeof(temp)); printf("ssid %s \n",mSsid.string()); size = mBssid.size(); if(size > sizeof(temp)/2 - 1) { size = sizeof(temp)/2 - 1; } utf16_to_utf8(mBssid.string(), size, temp); printf("Bssid %s \n",temp); size = mCaps.size(); if(size > sizeof(temp)/2 - 1) { size = sizeof(temp)/2 - 1; } utf16_to_utf8(mCaps.string(), size, temp); printf("ssid %s \n",temp); printf("level %d \n",mLevel); printf("freq %d \n",mFrequency); printf("freq %ld \n",mTimestamp); }private: String8 mSsid; String16 mBssid; String16 mCaps; int mLevel; int mFrequency; int64_t mTimestamp;};class IWifiService: public android::IInterface {public: DECLARE_META_INTERFACE(WifiService) virtual void startScan(int forceActive) = 0; virtual int getScanResults(List<ScanResult> &list) = 0; virtual bool setWifiEnabled(bool enable) = 0;};class BpWifiService: public android::BpInterface<IWifiService>{ enum { FIRST_CALL_TRANSACTION = 1, TRANSACTION_getConfiguredNetworks = (android::IBinder::FIRST_CALL_TRANSACTION + 0), TRANSACTION_addOrUpdateNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 1), TRANSACTION_removeNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 2), TRANSACTION_enableNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 3), TRANSACTION_disableNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 4), TRANSACTION_pingSupplicant = (android::IBinder::FIRST_CALL_TRANSACTION + 5), TRANSACTION_startScan = (android::IBinder::FIRST_CALL_TRANSACTION + 6), TRANSACTION_getScanResults = (android::IBinder::FIRST_CALL_TRANSACTION + 7), TRANSACTION_disconnect = (android::IBinder::FIRST_CALL_TRANSACTION + 8), TRANSACTION_reconnect = (android::IBinder::FIRST_CALL_TRANSACTION + 9), TRANSACTION_reassociate = (android::IBinder::FIRST_CALL_TRANSACTION + 10), TRANSACTION_getConnectionInfo = (android::IBinder::FIRST_CALL_TRANSACTION + 11), TRANSACTION_setWifiEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 12), TRANSACTION_getWifiEnabledState = (android::IBinder::FIRST_CALL_TRANSACTION + 13), TRANSACTION_setCountryCode = (android::IBinder::FIRST_CALL_TRANSACTION + 14), TRANSACTION_setFrequencyBand = (android::IBinder::FIRST_CALL_TRANSACTION + 15), TRANSACTION_getFrequencyBand = (android::IBinder::FIRST_CALL_TRANSACTION + 16), TRANSACTION_isDualBandSupported = (android::IBinder::FIRST_CALL_TRANSACTION + 17), TRANSACTION_saveConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 18), TRANSACTION_getDhcpInfo = (android::IBinder::FIRST_CALL_TRANSACTION + 19), TRANSACTION_acquireWifiLock = (android::IBinder::FIRST_CALL_TRANSACTION + 20), TRANSACTION_updateWifiLockWorkSource = (android::IBinder::FIRST_CALL_TRANSACTION + 21), TRANSACTION_releaseWifiLock = (android::IBinder::FIRST_CALL_TRANSACTION + 22), TRANSACTION_initializeMulticastFiltering = (android::IBinder::FIRST_CALL_TRANSACTION + 23), TRANSACTION_isMulticastEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 24), TRANSACTION_acquireMulticastLock = (android::IBinder::FIRST_CALL_TRANSACTION + 25), TRANSACTION_releaseMulticastLock = (android::IBinder::FIRST_CALL_TRANSACTION + 26), TRANSACTION_setWifiApEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 27), TRANSACTION_getWifiApEnabledState = (android::IBinder::FIRST_CALL_TRANSACTION + 28), TRANSACTION_getWifiApConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 29), TRANSACTION_setWifiApConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 30), TRANSACTION_startWifi = (android::IBinder::FIRST_CALL_TRANSACTION + 31), TRANSACTION_stopWifi = (android::IBinder::FIRST_CALL_TRANSACTION + 32), TRANSACTION_addToBlacklist = (android::IBinder::FIRST_CALL_TRANSACTION + 33), TRANSACTION_clearBlacklist = (android::IBinder::FIRST_CALL_TRANSACTION + 34), TRANSACTION_getWifiServiceMessenger = (android::IBinder::FIRST_CALL_TRANSACTION + 35), TRANSACTION_getWifiStateMachineMessenger = (android::IBinder::FIRST_CALL_TRANSACTION + 36), TRANSACTION_getConfigFile = (android::IBinder::FIRST_CALL_TRANSACTION + 37), TRANSACTION_captivePortalCheckComplete = (android::IBinder::FIRST_CALL_TRANSACTION + 38), };public: BpWifiService(const android::sp<android::IBinder>& impl): android::BpInterface<IWifiService>(impl) { } void startScan(int forceActive) { android::Parcel data, reply; data.writeInterfaceToken(WIFI_DESCRIPTOR); if (forceActive) { data.writeInt32(1); } else { data.writeInt32(0); } remote()->transact(TRANSACTION_startScan, data, &reply, 0); } virtual int getScanResults(List<ScanResult> &list) { Parcel data, reply; data.writeInterfaceToken(WIFI_DESCRIPTOR); remote()->transact(TRANSACTION_getScanResults, data, &reply, 0); if (0 != reply.readExceptionCode()) { return 0; } int count = reply.readInt32(); for (int i=0;i<count;i++) { String8 ssid; int res = reply.readInt32(); if (res != 0) { reply.readInt32(); reply.readInt32(); int length = reply.readInt32(); ssid = String8((const char*)reply.readInplace(length),length); }// utf16_to_utf8(const char16_t* src, size_t src_len, char* dst); String16 BSSID = reply.readString16(); String16 caps = reply.readString16(); int level = reply.readInt32(); int frequency = reply.readInt32(); int64_t timestamp = reply.readInt64(); ScanResult result(ssid,BSSID,caps,level,frequency,timestamp); list.push_back(result); } return count; } bool setWifiEnabled(bool enable) { Parcel data, reply; data.writeInterfaceToken(WIFI_DESCRIPTOR); if(enable) data.writeInt32(1); else data.writeInt32(0); remote()->transact(TRANSACTION_setWifiEnabled, data,&reply,0); reply.readExceptionCode(); return 0!=reply.readInt32(); }};IMPLEMENT_META_INTERFACE(WifiService, WIFI_DESCRIPTOR)int main(int argc, char *argv[]){ android::sp<android::IServiceManager> sm = android::defaultServiceManager(); android::sp<android::IBinder> binder; android::sp<IWifiService> wifi; binder = sm->getService(android::String16(WIFI_SERVICE)); if (binder == 0) { return 1; } wifi = android::interface_cast<IWifiService>(binder); wifi->setWifiEnabled(true);printf("+++++scan start");wifi->startScan(1);for(int i=0;i<10;i++){usleep(1*1000*1000);List<ScanResult> list;wifi->getScanResults(list);if(list.size() > 0) { for(List<ScanResult>::iterator it = list.begin();it != list.end();++it) { (*it).dump(); } break; }} return(0);}
The basic idea is simple:
First pass:
Android: defaservicservicemanager ()-> getService (android: String16 (WIFI_SERVICE ));
Obtain the binder interface, and then read and binder through Parcel. For details, refer to the code of IWifiManager. java.
Run the above Code after compilation to get output similar to the following:
Ssid wifitest
Bssid b8: 55: 10: 84: 13: 57
Ssid [WPA-PSK-CCMP] [WPA2-PSK-CCMP] [WPS] [ESS]
Level-55
Freq 2447
Time stamp 1073922473
Ssid test
Bssid 08: bd: 43: c3: a9: 96
Ssid [WPA2-PSK-CCMP] [WPS] [ESS]
Level-66
Freq 2462
Time stamp 1073922473
Download complete code:
Http://download.csdn.net/detail/i2cbus/7613361
In android, how can I view the changed effect after the framework layer code is changed?
1. the following method applies to the real machine: Download the android source code, compile the modified framwork code, generate framework. jar, push it to the system/framework directory, and restart the machine! OK
2. The following method is suitable for simulators:
(1) decompress the package with unyaffs. In the sdk directory you downloaded, replace system. img with the framework. jar and compress it into a new system. img. Then, start the simulator and OK.
(2): You can also directly compile the source code and generate system. img to replace system. img in the simulator.
How to replace the code of the framework in android
I am also working on the android framework, and I am still learning a lot of knowledge.