1

Does any of you have experience with return value of setWifiEnabled()?

Documentation is unclear, it says:

Returns true if the operation succeeds (or if the existing state is the same as the requested state).

What it does when operation fails? Does it throw exception or return false?

Is it possible to do something like:

if (!WifiManager.setWifiEnabled(true)) {
    Log.i(LOG_TAG, "Wifi switch failed.");
} else {
    Log.i(LOG_TAG, "Wifi switch succeeded.")
}

Many thanks.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
Matej Lachman
  • 19
  • 1
  • 8

2 Answers2

2

The accepted answer is outdated (source is from android 4.2 where current android is now 10 and 11 will be out soon). This method can return false. WifiServiceImpl.java is the current source for handling WifiManager#setWifiEnabled(boolean):

Code:

 /**
 * see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}
 * @param enable {@code true} to enable, {@code false} to disable.
 * @return {@code true} if the enable/disable operation was
 *         started or is already in the queue.
 */
@Override
public synchronized boolean setWifiEnabled(String packageName, boolean enable) {
    if (enforceChangePermission(packageName) != MODE_ALLOWED) {
        return false;
    }
    boolean isPrivileged = isPrivileged(Binder.getCallingPid(), Binder.getCallingUid());
    if (!isPrivileged && !isDeviceOrProfileOwner(Binder.getCallingUid())
            && !mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q,
              Binder.getCallingUid())
            && !isSystem(packageName, Binder.getCallingUid())) {
        mLog.info("setWifiEnabled not allowed for uid=%")
                .c(Binder.getCallingUid()).flush();
        return false;
    }
    // If Airplane mode is enabled, only privileged apps are allowed to toggle Wifi
    if (mSettingsStore.isAirplaneModeOn() && !isPrivileged) {
        mLog.err("setWifiEnabled in Airplane mode: only Settings can toggle wifi").flush();
        return false;
    }
    // If SoftAp is enabled, only privileged apps are allowed to toggle wifi
    boolean apEnabled = mWifiApState == WifiManager.WIFI_AP_STATE_ENABLED;
    if (apEnabled && !isPrivileged) {
        mLog.err("setWifiEnabled SoftAp enabled: only Settings can toggle wifi").flush();
        return false;
    }
    // If we're in crypt debounce, ignore any wifi state change APIs.
    if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
        return false;
    }
    mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
            .c(Binder.getCallingUid()).c(enable).flush();
    long ident = Binder.clearCallingIdentity();
    try {
        if (!mSettingsStore.handleWifiToggled(enable)) {
            // Nothing to do if wifi cannot be toggled
            return true;
        }
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
    mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);
    mWifiController.sendMessage(CMD_WIFI_TOGGLED);
    return true;
}
Matt Wolfe
  • 8,924
  • 8
  • 60
  • 77
1

Have a look at implementation of WifiService#setWifiEnabled(boolean):

    /**
     * see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}
     * @param enable {@code true} to enable, {@code false} to disable.
     * @return {@code true} if the enable/disable operation was
     *         started or is already in the queue.
     */
    public synchronized boolean setWifiEnabled(boolean enable) {
        enforceChangePermission();
        Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
        if (DBG) {
            Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
        }
        if (enable) {
            reportStartWorkSource();
        }
        mWifiStateMachine.setWifiEnabled(enable);
        /*
         * Caller might not have WRITE_SECURE_SETTINGS,
         * only CHANGE_WIFI_STATE is enforced
         */
        long ident = Binder.clearCallingIdentity();
        try {
            handleWifiToggled(enable);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        if (enable) {
            if (!mIsReceiverRegistered) {
                registerForBroadcasts();
                mIsReceiverRegistered = true;
            }
        } else if (mIsReceiverRegistered) {
            mContext.unregisterReceiver(mReceiver);
            mIsReceiverRegistered = false;
        }
        return true;
    }

So, it never returns false. If for some reason the desired operation couldn't succeed, then exception will be thrown, see WifiManager.setWifiEnabled(boolean):

    /**
     * Enable or disable Wi-Fi.
     * @param enabled {@code true} to enable, {@code false} to disable.
     * @return {@code true} if the operation succeeds (or if the existing state
     *         is the same as the requested state).
     */
    public boolean setWifiEnabled(boolean enabled) {
        try {
            return mService.setWifiEnabled(enabled);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
azizbekian
  • 60,783
  • 13
  • 169
  • 249