Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the meaning of new @SystemApi annotation, any difference from @hide?

Android introduced @SystemApi in its SDK source code recently. Seems like same in effect as the @hide annotation before, since they also got stripped from SDK jar classes.

Is there any chance an app can call them in ways different from the old @hide APIs.

/**
 * Indicates an API is exposed for use by bundled system applications.
 * <p>
 * These APIs are not guaranteed to remain consistent release-to-release,
 * and are not for use by apps linking against the Android SDK.
 * </p><p>
 * This annotation should only appear on API that is already marked <pre>@hide</pre>.
 * </p>
 *
 * @hide
 */
like image 545
Oasis Feng Avatar asked Nov 05 '14 08:11

Oasis Feng


2 Answers

@SystemApi, @PrivateApi and @hide

According to this commit, @SystemApi is a rename of the old @PrivateApi. APIs marked @hide are not necessarily @SystemApi, but @SystemApi requires @hide.

For more information about @hide javadoc annotation, this post gives a good answer.

Based on my own experiments, one (non-system application) can still access @hide APIs and fields using Java reflection like (from this post):

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

WifiConfiguration config = new WifiConfiguration();
config.SSID = "AccessPointSSID";

Method method = manager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method.invoke(manager, config, true);

But trying to access @SystemApi things using Java reflection is impossible (following code will trigger invocationTargetException):

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

Method method = manager.getClass().getMethod("getPrivilegedConfiguredNetworks");
List<WifiConfiguration> configs = (List<WifiConfiguration>)method.invoke(manager);

P.S.

In the WifiManager java code, the setWifiApEnabled and getPrivilegedConfiguredNetworks APIs are defined as:

/**
 * Start AccessPoint mode with the specified
 * configuration. If the radio is already running in
 * AP mode, update the new configuration
 * Note that starting in access point mode disables station
 * mode operation
 * @param wifiConfig SSID, security and channel details as
 *        part of WifiConfiguration
 * @return {@code true} if the operation succeeds, {@code false} otherwise
 *
 * @hide Dont open up yet
 */
public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
    try {
        mService.setWifiApEnabled(wifiConfig, enabled);
        return true;
    } catch (RemoteException e) {
        return false;
    }
}

and

/** @hide */
@SystemApi
public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
    try {
        return mService.getPrivilegedConfiguredNetworks();
    } catch (RemoteException e) {
        return null;
    }
}
like image 95
Moony Chou Avatar answered Nov 02 '22 11:11

Moony Chou


Methods annotated with @SystemApi are a subset of ones with @hide. It's apparently an indicator for internal teams (perhaps also partners) that these methods are actual APIs, although not for public developers.

As a result, @SystemApi methods will be more stable than @hide ones, which could be changed at any time in the future without any compatibility consideration, and also any OEM is allowed to change them at their own will.

If you are trying to invoke internal APIs via reflection, always prefer @SystemApi methods for better future compatibility.

like image 40
Oasis Feng Avatar answered Nov 02 '22 09:11

Oasis Feng