Merge "CaptivePortal: implement setDelegateUid API." into main

This commit is contained in:
Xiao Ma 2024-12-11 22:43:58 -08:00 • committed by Gerrit Code Review
commit 69aa3c5469
3 changed files with 212 additions and 1 deletions

View file

@ -75,6 +75,7 @@ java_defaults {
// the module builds against API (the parcelable declarations exist in framework.aidl)
"frameworks/base/core/java", // For framework parcelables
"frameworks/native/aidl/binder", // For PersistableBundle.aidl
"packages/modules/Connectivity/Tethering/common/TetheringLib/src",
],
},
stub_only_libs: [
@ -335,6 +336,7 @@ droidstubs {
aidl: {
include_dirs: [
"packages/modules/Connectivity/framework/aidl-export",
"packages/modules/Connectivity/Tethering/common/TetheringLib/src",
"frameworks/native/aidl/binder", // For PersistableBundle.aidl
],
},

View file

@ -18,10 +18,19 @@ package android.net;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TargetApi;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.OutcomeReceiver;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.system.OsConstants;
import java.util.Objects;
import java.util.concurrent.Executor;
/**
* A class allowing apps handling the {@link ConnectivityManager#ACTION_CAPTIVE_PORTAL_SIGN_IN}
@ -69,6 +78,15 @@ public class CaptivePortal implements Parcelable {
@SystemApi
public static final int APP_REQUEST_REEVALUATION_REQUIRED = APP_REQUEST_BASE + 0;
/**
* Binder object used for tracking the lifetime of the process, so CS can perform cleanup if
* the CaptivePortal app dies. This binder is not parcelled as part of this object. It is
* created in the client process and sent to the server by setDelegateUid so that the server
* can use it to register a death recipient.
*
*/
private final Binder mLifetimeBinder = new Binder();
private final IBinder mBinder;
/** @hide */
@ -167,4 +185,56 @@ public class CaptivePortal implements Parcelable {
@SystemApi
public void logEvent(int eventId, @NonNull String packageName) {
}
/**
* Sets the UID of the app that is allowed to perform network traffic for captive
* portal login.
*
* This app will be allowed to communicate directly on the captive
* portal by binding to the {@link android.net.Network} extra passed in the
* ACTION_CAPTIVE_PORTAL_SIGN_IN broadcast that contained this object.
*
* Communication will bypass network access restrictions such as VPNs and
* Private DNS settings, so the delegated UID must be trusted to ensure that only
* traffic intended for captive portal login binds to that network.
*
* By default, no UID is delegated. The delegation can be cleared by calling
* this method again with {@link android.os.Process.INVALID_UID}. Only one UID can
* be delegated at any given time.
*
* The operation is asynchronous. The uid is only guaranteed to have access when
* the provided OutcomeReceiver is called.
*
* @hide
*/
@RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
// OutcomeReceiver is not available on R, but the mainline version of this
// class is only available on S+.
@TargetApi(Build.VERSION_CODES.S)
public void setDelegateUid(int uid, @NonNull Executor executor,
@NonNull final OutcomeReceiver<Void, ServiceSpecificException> receiver) {
Objects.requireNonNull(executor);
Objects.requireNonNull(receiver);
try {
ICaptivePortal.Stub.asInterface(mBinder).setDelegateUid(
uid,
mLifetimeBinder,
new IIntResultListener.Stub() {
@Override
public void onResult(int resultCode) {
if (resultCode != 0) {
final String msg = "Fail to set the delegate UID " + uid
+ ", error: " + OsConstants.errnoName(resultCode);
executor.execute(() -> {
receiver.onError(new ServiceSpecificException(resultCode, msg));
});
} else {
executor.execute(() -> receiver.onResult(null));
}
}
});
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}

View file

@ -16,6 +16,9 @@
package android.net;
import android.net.IIntResultListener;
import android.os.IBinder;
/**
* Interface to inform NetworkMonitor of decisions of app handling captive portal.
* @hide
@ -23,4 +26,5 @@ package android.net;
oneway interface ICaptivePortal {
void appRequest(int request);
void appResponse(int response);
void setDelegateUid(int uid, IBinder binder, IIntResultListener listener);
}