Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a2317a3 authored by paulhu's avatar paulhu Committed by Paul Hu
Browse files

Implement Settings#checkAndNoteChangeNetworkStateOperation on CS

Connectivity is becoming a mainline module in S and
ConnectivityManager#enforceChangePermission is using
Settings#checkAndNoteChangeNetworkStateOperation for performing a
strict and comprehensive check of whether a calling package is
allowed to change the state of network. However, Mainline modules
are not allowed to use non-formal APIs, fortunately CS is the
only caller of this ConnectivityManager#enforceChangePermission.
Thus, implement the Settings API on ConnectivityService and remove
the ConnectivityManager#enforceChangePermission and
Settings#checkAndNoteChangeNetworkStateOperation.

Bug: 178565313
Test: atest FrameworksNetTests
Change-Id: I6f03398c1735b89470ad5bdbe3a036929daeb53c
Merged-In: I6f03398c1735b89470ad5bdbe3a036929daeb53c
parent 654b0fff
Loading
Loading
Loading
Loading
+0 −24
Original line number Diff line number Diff line
@@ -15091,30 +15091,6 @@ public final class Settings {
                PM_WRITE_SETTINGS, true);
    }
    /**
     * Performs a strict and comprehensive check of whether a calling package is allowed to
     * change the state of network, as the condition differs for pre-M, M+, and
     * privileged/preinstalled apps. The caller is expected to have either the
     * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
     * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
     * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
     * permission and cannot be revoked. See http://b/23597341
     *
     * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
     * of this app will be updated to the current time.
     * @hide
     */
    public static boolean checkAndNoteChangeNetworkStateOperation(Context context, int uid,
            String callingPackage, boolean throwException) {
        if (context.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
                == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid,
                callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS,
                PM_CHANGE_NETWORK_STATE, true);
    }
    /**
     * Performs a strict and comprehensive check of whether a calling package is allowed to
     * draw on top of other apps, as the conditions differs for pre-M, M+, and
+0 −25
Original line number Diff line number Diff line
@@ -2245,31 +2245,6 @@ public class ConnectivityManager {
        }
    }

    /* TODO: These permissions checks don't belong in client-side code. Move them to
     * services.jar, possibly in com.android.server.net. */

    /** {@hide} */
    public static final void enforceChangePermission(Context context,
            String callingPkg, String callingAttributionTag) {
        int uid = Binder.getCallingUid();
        checkAndNoteChangeNetworkStateOperation(context, uid, callingPkg,
                callingAttributionTag, true /* throwException */);
    }

    /**
     * Check if the package is a allowed to change the network state. This also accounts that such
     * an access happened.
     *
     * @return {@code true} iff the package is allowed to change the network state.
     */
    // TODO: Remove method and replace with direct call once R code is pushed to AOSP
    private static boolean checkAndNoteChangeNetworkStateOperation(@NonNull Context context,
            int uid, @NonNull String callingPackage, @Nullable String callingAttributionTag,
            boolean throwException) {
        return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, callingPackage,
                throwException);
    }

    /**
     * Check if the package is a allowed to write settings. This also accounts that such an access
     * happened.
+38 −1
Original line number Diff line number Diff line
@@ -2190,8 +2190,45 @@ public class ConnectivityService extends IConnectivityManager.Stub
                "ConnectivityService");
    }

    /**
     * Performs a strict and comprehensive check of whether a calling package is allowed to
     * change the state of network, as the condition differs for pre-M, M+, and
     * privileged/preinstalled apps. The caller is expected to have either the
     * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
     * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
     * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
     * permission and cannot be revoked. See http://b/23597341
     *
     * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
     * of this app will be updated to the current time.
     */
    private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
        ConnectivityManager.enforceChangePermission(mContext, callingPkg, callingAttributionTag);
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
                == PackageManager.PERMISSION_GRANTED) {
            return;
        }

        if (callingPkg == null) {
            throw new SecurityException("Calling package name is null.");
        }

        final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class);
        final int uid = mDeps.getCallingUid();
        final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid,
                callingPkg, callingAttributionTag, null /* message */);

        if (mode == AppOpsManager.MODE_ALLOWED) {
            return;
        }

        if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) {
            return;
        }

        throw new SecurityException(callingPkg + " was not granted either of these permissions:"
                + android.Manifest.permission.CHANGE_NETWORK_STATE + ","
                + android.Manifest.permission.WRITE_SETTINGS + ".");
    }

    private void enforceSettingsPermission() {