The wifi direct function is added to Android 4.0. However, on the simulator and some mobile phones or tablets that can be upgraded to Android 4.0, there is still no wifi direct function option in settings. So out of curiosity, I followed
Source code.
1. Check whether WiFi direct is available in the System Configuration package.
In the source code path of android4.0 (my source code path is myandroid_4.0)/packages/apps/settings/src/COM/Android/settings/WiFi, a P2P folder is found, which of the following describes how to process the Code with WiFi direct in the configuration package.
2. Check whether WiFi direct is filtered in system settings.
Tracking the source code of the settings package, and finally finding out that it is in the wirelesssettings. Java (myandroid_4.0 \ packages \ apps \ Settings \ SRC \ com \ Android \ Settings) File
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); .......................................... ........................................... WifiP2pManager p2p = (WifiP2pManager) activity.getSystemService(Context.WIFI_P2P_SERVICE); if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) { getPreferenceScreen().removePreference(wifiP2p); } else { mWifiP2pEnabler = new WifiP2pEnabler(activity, wifiP2p); } ........................................... ...........................................}
1) analyze packagemanager. feature_wifi_direct: file packagemanager. Java (frameworks \ base \ core \ Java \ Android \ content \ pm:
@ Sdkconstant (sdkconstanttype. feature)
Public static final string feature_wifi_direct = "android. Hardware. Wifi. Direct"; // It is the string passed in for judgment.
2) analyze the getpackagemanager () function
File settingspreferencefragment. Java (packages \ apps \ Settings \ SRC \ com \ Android \ Settings,
...................................................................... /** * Returns the PackageManager from the owning Activity. */ protected PackageManager getPackageManager() { return getActivity().getPackageManager(); }......................................................................
Getacivity () returns an activity. Activity. Java (frameworks \ base \ core \ Java \ Android \ APP) does not contain the getpackagemanager () function;
Because the public class activity extends contextthemewrapper, it enters the file contextthemewrapper. Java (frameworks \ base \ core \ Java \ Android \ view,
There is no getpackagemanager () function. Similarly, public class contextthemewrapper extends contextwrapper is found, so the file contextwrapper is entered. java (frameworks \ base \ core \ Java \ Android \ content). At this time, we finally see the getpackagemanager () Trace:
Public class contextwrapper extends context {
Context mbase;
....................................
....................................
@ Override
Public packagemanager getpackagemanager (){
Return mbase. getpackagemanager ();
}
.....................................
......................................
}
Keep track of the context. Java (frameworks \ base \ core \ Java \ Android \ content) file and find that getpackagemanager () is an abstract function:
/** Return packagemanager instance to find global package information .*/
Public abstract packagemanager getpackagemanager ();
I don't know how to keep track of this function after analysis. I want to see if it is related to this file (because the class contextimpl extends context. java (frameworks \ base \ core \ Java \ Android \ APP), indeed found the concerned code:
@Override public PackageManager getPackageManager() { if (mPackageManager != null) { return mPackageManager; } IPackageManager pm = ActivityThread.getPackageManager(); if (pm != null) { // Doesn't matter if we make more than one instance. return (mPackageManager = new ApplicationPackageManager(this, pm)); } return null; }
Because final class applicationpackagemanager extends packagemanager, getpackagemanager () from the above Code Analysis returns an applicationpackagemanager.
3) analyze getpackagemanager (). hassystemfeature (packagemanager. feature_wifi_direct)
According to the analysis above, the getpackagemanager (). hassystemfeature function should be tuned to the applicationpackagemanager. Java (frameworks \ base \ core \ Java \ Android \ APP) file ),
final class ApplicationPackageManager extends PackageManager {............................................................ @Override public boolean hasSystemFeature(String name) { try { return mPM.hasSystemFeature(name); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } }.............................................................}
MPM. hassystemfeature (name) is actually called by aidl to packagemanagerservice. Java (frameworks \ base \ Services \ Java \ com \ Android \ Server \ pm)
public class PackageManagerService extends IPackageManager.Stub {........................................................................ public boolean hasSystemFeature(String name) { synchronized (mPackages) { return mAvailableFeatures.containsKey(name); } }......................................................................}
The content in mavailablefeatures is to read the documents under/system/etc/permissions. The Code is as follows:
void readPermissions() { // Read permissions from .../etc/permission directory. File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions"); if (!libraryDir.exists() || !libraryDir.isDirectory()) { Slog.w(TAG, "No directory " + libraryDir + ", skipping"); return; } if (!libraryDir.canRead()) { Slog.w(TAG, "Directory " + libraryDir + " cannot be read"); return; } // Iterate over the files in the directory and scan .xml files for (File f : libraryDir.listFiles()) { // We'll read platform.xml last if (f.getPath().endsWith("etc/permissions/platform.xml")) { continue; } if (!f.getPath().endsWith(".xml")) { Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring"); continue; } if (!f.canRead()) { Slog.w(TAG, "Permissions library file " + f + " cannot be read"); continue; } readPermissionsFromXml(f); } // Read permissions from .../etc/permissions/platform.xml last so it will take precedence final File permFile = new File(Environment.getRootDirectory(), "etc/permissions/platform.xml"); readPermissionsFromXml(permFile); } private void readPermissionsFromXml(File permFile) { FileReader permReader = null; try { permReader = new FileReader(permFile); } catch (FileNotFoundException e) { Slog.w(TAG, "Couldn't find or open permissions file " + permFile); return; } try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(permReader); XmlUtils.beginDocument(parser, "permissions"); while (true) { XmlUtils.nextElement(parser); if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { break; } String name = parser.getName(); if ("group".equals(name)) { String gidStr = parser.getAttributeValue(null, "gid"); if (gidStr != null) { int gid = Integer.parseInt(gidStr); mGlobalGids = appendInt(mGlobalGids, gid); } else { Slog.w(TAG, "<group> without gid at " + parser.getPositionDescription()); } XmlUtils.skipCurrentTag(parser); continue; } ......................................else if ("feature".equals(name)) { String fname = parser.getAttributeValue(null, "name"); if (fname == null) { Slog.w(TAG, "<feature> without name at " + parser.getPositionDescription()); } else { //Log.i(TAG, "Got feature " + fname); FeatureInfo fi = new FeatureInfo(); fi.name = fname; mAvailableFeatures.put(fname, fi); } XmlUtils.skipCurrentTag(parser); continue; } else { XmlUtils.skipCurrentTag(parser); continue; } } permReader.close(); } catch (XmlPullParserException e) { Slog.w(TAG, "Got execption parsing permissions.", e); } catch (IOException e) { Slog.w(TAG, "Got execption parsing permissions.", e); } }
3. verify the correctness of the above code analysis.
1) Start an android 4.0 simulator and use the ADB shell to access the/system/etc/permissions directory,
# Cd/system/etc/Permissions
# Ls
Com. Android. Location. provider. xml
Platform. xml
#
There is indeed no Android. Hardware. Wifi. Direct. xml file.
2) Because Android is available in the source code/frameworks/base/data/etc. hardware. wiFi. direct. XML file, so I manually copy this file to out/target/product/generic/system/etc/permissions/
Directory, then compile the source code, and then use the command line to specify the compiled system. IMG, userdata. IMG, ramdisk. IMG to start the simulator:
Xxx @ xxx :~ /Android_code/system_img $/home/XXX/android_install/android-sdk-linux_x86/tools/emulator-system. IMG-data userdata. IMG-ramdisk. IMG-partition-size 256-AVD android4.0.3-apilevel15
Then, the settings of wifi direct are displayed in the simulator settings ,:
The error message "couldn't start wi-fi direct" is displayed when you click it. wifip2pservice is a simple tracking. java contains wifinative. A judgment of startp2psupplicant (), followed by the JNI Layer
Wifip2pservice. Java (frameworks \ base \ WiFi \ Java \ Android \ net \ WiFi \ P2P)
Static jboolean android_net_wifi_startp2psupplicant (jnienv * ENV, jobject)
{
Return (jboolean) (: wifi_start_p2p_supplicant () = 0); // This should be a hardware judgment.
}
No more tracking, at least the filtering process for WiFi P2P settings is clear.