Source code analysis for determining whether WiFi P2P options are displayed in android4.0

Source: Internet
Author: User

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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.