diff options
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/net/vcn/IVcnManagementService.aidl | 4 | ||||
| -rw-r--r-- | core/java/android/net/vcn/IVcnStatusCallback.aidl | 22 | ||||
| -rw-r--r-- | core/java/android/net/vcn/VcnManager.java | 120 |
3 files changed, 145 insertions, 1 deletions
diff --git a/core/java/android/net/vcn/IVcnManagementService.aidl b/core/java/android/net/vcn/IVcnManagementService.aidl index 4f293eeb3c3b..6a3cb42ed75d 100644 --- a/core/java/android/net/vcn/IVcnManagementService.aidl +++ b/core/java/android/net/vcn/IVcnManagementService.aidl @@ -18,6 +18,7 @@ package android.net.vcn; import android.net.LinkProperties; import android.net.NetworkCapabilities; +import android.net.vcn.IVcnStatusCallback; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.VcnConfig; import android.net.vcn.VcnUnderlyingNetworkPolicy; @@ -33,4 +34,7 @@ interface IVcnManagementService { void addVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener); void removeVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener); VcnUnderlyingNetworkPolicy getUnderlyingNetworkPolicy(in NetworkCapabilities nc, in LinkProperties lp); + + void registerVcnStatusCallback(in ParcelUuid subscriptionGroup, in IVcnStatusCallback callback, in String opPkgName); + void unregisterVcnStatusCallback(in IVcnStatusCallback callback); } diff --git a/core/java/android/net/vcn/IVcnStatusCallback.aidl b/core/java/android/net/vcn/IVcnStatusCallback.aidl new file mode 100644 index 000000000000..a7386718d5ae --- /dev/null +++ b/core/java/android/net/vcn/IVcnStatusCallback.aidl @@ -0,0 +1,22 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.vcn; + +/** @hide */ +interface IVcnStatusCallback { + void onEnteredSafeMode(); +}
\ No newline at end of file diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java index 467043665da3..aed64de52cd0 100644 --- a/core/java/android/net/vcn/VcnManager.java +++ b/core/java/android/net/vcn/VcnManager.java @@ -23,6 +23,7 @@ import android.annotation.SystemService; import android.content.Context; import android.net.LinkProperties; import android.net.NetworkCapabilities; +import android.os.Binder; import android.os.ParcelUuid; import android.os.RemoteException; import android.os.ServiceSpecificException; @@ -261,6 +262,100 @@ public class VcnManager { } } + // TODO: make VcnStatusCallback @SystemApi + /** + * VcnStatusCallback is the interface for Carrier apps to receive updates for their VCNs. + * + * <p>VcnStatusCallbacks may be registered before {@link VcnConfig}s are provided for a + * subscription group. + * + * @hide + */ + public abstract static class VcnStatusCallback { + private VcnStatusCallbackBinder mCbBinder; + + /** + * Invoked when the VCN for this Callback's subscription group enters safe mode. + * + * <p>A VCN will be put into safe mode if any of the gateway connections were unable to + * establish a connection within a system-determined timeout (while underlying networks were + * available). + * + * <p>A VCN-configuring app may opt to exit safe mode by (re)setting the VCN configuration + * via {@link #setVcnConfig(ParcelUuid, VcnConfig)}. + */ + public abstract void onEnteredSafeMode(); + } + + /** + * Registers the given callback to receive status updates for the specified subscription. + * + * <p>Callbacks can be registered for a subscription before {@link VcnConfig}s are set for it. + * + * <p>A {@link VcnStatusCallback} may only be registered for one subscription at a time. {@link + * VcnStatusCallback}s may be reused once unregistered. + * + * <p>A {@link VcnStatusCallback} will only be invoked if the registering package has carrier + * privileges for the specified subscription at the time of invocation. + * + * @param subscriptionGroup The subscription group to match for callbacks + * @param executor The {@link Executor} to be used for invoking callbacks + * @param callback The VcnStatusCallback to be registered + * @throws IllegalStateException if callback is currently registered with VcnManager + * @hide + */ + public void registerVcnStatusCallback( + @NonNull ParcelUuid subscriptionGroup, + @NonNull Executor executor, + @NonNull VcnStatusCallback callback) { + requireNonNull(subscriptionGroup, "subscriptionGroup must not be null"); + requireNonNull(executor, "executor must not be null"); + requireNonNull(callback, "callback must not be null"); + + synchronized (callback) { + if (callback.mCbBinder != null) { + throw new IllegalStateException("callback is already registered with VcnManager"); + } + callback.mCbBinder = new VcnStatusCallbackBinder(executor, callback); + + try { + mService.registerVcnStatusCallback( + subscriptionGroup, callback.mCbBinder, mContext.getOpPackageName()); + } catch (RemoteException e) { + callback.mCbBinder = null; + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Unregisters the given callback. + * + * <p>Once unregistered, the callback will stop receiving status updates for the subscription it + * was registered with. + * + * @param callback The callback to be unregistered + * @hide + */ + public void unregisterVcnStatusCallback(@NonNull VcnStatusCallback callback) { + requireNonNull(callback, "callback must not be null"); + + synchronized (callback) { + if (callback.mCbBinder == null) { + // no Binder attached to this callback, so it's not currently registered + return; + } + + try { + mService.unregisterVcnStatusCallback(callback.mCbBinder); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } finally { + callback.mCbBinder = null; + } + } + } + /** * Binder wrapper for added VcnUnderlyingNetworkPolicyListeners to receive signals from System * Server. @@ -280,7 +375,30 @@ public class VcnManager { @Override public void onPolicyChanged() { - mExecutor.execute(() -> mListener.onPolicyChanged()); + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> mListener.onPolicyChanged())); + } + } + + /** + * Binder wrapper for VcnStatusCallbacks to receive signals from VcnManagementService. + * + * @hide + */ + private class VcnStatusCallbackBinder extends IVcnStatusCallback.Stub { + @NonNull private final Executor mExecutor; + @NonNull private final VcnStatusCallback mCallback; + + private VcnStatusCallbackBinder( + @NonNull Executor executor, @NonNull VcnStatusCallback callback) { + mExecutor = executor; + mCallback = callback; + } + + @Override + public void onEnteredSafeMode() { + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> mCallback.onEnteredSafeMode())); } } } |
