Add tethering event callback API
Provide OnTetheringEventCallback for system app to know
tethering's upstream.
Bug: 125583822
Test: -build, flash, boot
-atest FrameworksNetTests
Change-Id: I7ca81b27c9b805cc01884509f5b20d9d0a24cd36
This commit is contained in:
@@ -56,6 +56,7 @@ import android.util.ArrayMap;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.telephony.ITelephony;
|
import com.android.internal.telephony.ITelephony;
|
||||||
import com.android.internal.telephony.PhoneConstants;
|
import com.android.internal.telephony.PhoneConstants;
|
||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
@@ -2541,6 +2542,94 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for use with {@link registerTetheringEventCallback} to find out tethering
|
||||||
|
* upstream status.
|
||||||
|
*
|
||||||
|
*@hide
|
||||||
|
*/
|
||||||
|
@SystemApi
|
||||||
|
public abstract static class OnTetheringEventCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when tethering upstream changed. This can be called multiple times and can be
|
||||||
|
* called any time.
|
||||||
|
*
|
||||||
|
* @param network the {@link Network} of tethering upstream. Null means tethering doesn't
|
||||||
|
* have any upstream.
|
||||||
|
*/
|
||||||
|
public void onUpstreamChanged(@Nullable Network network) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mTetheringEventCallbacks")
|
||||||
|
private final ArrayMap<OnTetheringEventCallback, ITetheringEventCallback>
|
||||||
|
mTetheringEventCallbacks = new ArrayMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start listening to tethering change events. Any new added callback will receive the last
|
||||||
|
* tethering status right away. If callback is registered when tethering loses its upstream or
|
||||||
|
* disabled, {@link OnTetheringEventCallback#onUpstreamChanged} will immediately be called
|
||||||
|
* with a null argument. The same callback object cannot be registered twice.
|
||||||
|
*
|
||||||
|
* @param executor the executor on which callback will be invoked.
|
||||||
|
* @param callback the callback to be called when tethering has change events.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi
|
||||||
|
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||||
|
public void registerTetheringEventCallback(
|
||||||
|
@NonNull @CallbackExecutor Executor executor,
|
||||||
|
@NonNull final OnTetheringEventCallback callback) {
|
||||||
|
Preconditions.checkNotNull(callback, "OnTetheringEventCallback cannot be null.");
|
||||||
|
|
||||||
|
synchronized (mTetheringEventCallbacks) {
|
||||||
|
Preconditions.checkArgument(!mTetheringEventCallbacks.containsKey(callback),
|
||||||
|
"callback was already registered.");
|
||||||
|
ITetheringEventCallback remoteCallback = new ITetheringEventCallback.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onUpstreamChanged(Network network) throws RemoteException {
|
||||||
|
Binder.withCleanCallingIdentity(() ->
|
||||||
|
executor.execute(() -> {
|
||||||
|
callback.onUpstreamChanged(network);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
String pkgName = mContext.getOpPackageName();
|
||||||
|
Log.i(TAG, "registerTetheringUpstreamCallback:" + pkgName);
|
||||||
|
mService.registerTetheringEventCallback(remoteCallback, pkgName);
|
||||||
|
mTetheringEventCallbacks.put(callback, remoteCallback);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove tethering event callback previously registered with
|
||||||
|
* {@link #registerTetheringEventCallback}.
|
||||||
|
*
|
||||||
|
* @param callback previously registered callback.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi
|
||||||
|
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
|
||||||
|
public void unregisterTetheringEventCallback(
|
||||||
|
@NonNull final OnTetheringEventCallback callback) {
|
||||||
|
synchronized (mTetheringEventCallbacks) {
|
||||||
|
ITetheringEventCallback remoteCallback = mTetheringEventCallbacks.remove(callback);
|
||||||
|
Preconditions.checkNotNull(remoteCallback, "callback was not registered.");
|
||||||
|
try {
|
||||||
|
String pkgName = mContext.getOpPackageName();
|
||||||
|
Log.i(TAG, "unregisterTetheringEventCallback:" + pkgName);
|
||||||
|
mService.unregisterTetheringEventCallback(remoteCallback, pkgName);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of regular expressions that define any tetherable
|
* Get the list of regular expressions that define any tetherable
|
||||||
* USB network interfaces. If USB tethering is not supported by the
|
* USB network interfaces. If USB tethering is not supported by the
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.net;
|
|||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.net.ConnectionInfo;
|
import android.net.ConnectionInfo;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
|
import android.net.ITetheringEventCallback;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
@@ -214,4 +215,7 @@ interface IConnectivityManager
|
|||||||
|
|
||||||
void getLatestTetheringEntitlementResult(int type, in ResultReceiver receiver,
|
void getLatestTetheringEntitlementResult(int type, in ResultReceiver receiver,
|
||||||
boolean showEntitlementUi, String callerPkg);
|
boolean showEntitlementUi, String callerPkg);
|
||||||
|
|
||||||
|
void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
|
||||||
|
void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ import android.net.INetworkMonitorCallbacks;
|
|||||||
import android.net.INetworkPolicyListener;
|
import android.net.INetworkPolicyListener;
|
||||||
import android.net.INetworkPolicyManager;
|
import android.net.INetworkPolicyManager;
|
||||||
import android.net.INetworkStatsService;
|
import android.net.INetworkStatsService;
|
||||||
|
import android.net.ITetheringEventCallback;
|
||||||
import android.net.InetAddresses;
|
import android.net.InetAddresses;
|
||||||
import android.net.IpPrefix;
|
import android.net.IpPrefix;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
@@ -3798,6 +3799,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mTethering.getLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
|
mTethering.getLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Register tethering event callback. */
|
||||||
|
@Override
|
||||||
|
public void registerTetheringEventCallback(ITetheringEventCallback callback,
|
||||||
|
String callerPkg) {
|
||||||
|
ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
|
||||||
|
mTethering.registerTetheringEventCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unregister tethering event callback. */
|
||||||
|
@Override
|
||||||
|
public void unregisterTetheringEventCallback(ITetheringEventCallback callback,
|
||||||
|
String callerPkg) {
|
||||||
|
ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
|
||||||
|
mTethering.unregisterTetheringEventCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
// Called when we lose the default network and have no replacement yet.
|
// Called when we lose the default network and have no replacement yet.
|
||||||
// This will automatically be cleared after X seconds or a new default network
|
// This will automatically be cleared after X seconds or a new default network
|
||||||
// becomes CONNECTED, whichever happens first. The timer is started by the
|
// becomes CONNECTED, whichever happens first. The timer is started by the
|
||||||
|
|||||||
Reference in New Issue
Block a user