• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.net.vcn;
17 
18 import static com.android.internal.annotations.VisibleForTesting.Visibility;
19 
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.content.Context;
23 import android.net.NetworkRequest;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.os.PersistableBundle;
27 import android.util.ArraySet;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 import com.android.internal.util.Preconditions;
31 import com.android.server.vcn.util.PersistableBundleUtils;
32 
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.Objects;
36 import java.util.Set;
37 
38 /**
39  * This class represents a configuration for a Virtual Carrier Network.
40  *
41  * <p>Each {@link VcnGatewayConnectionConfig} instance added represents a connection that will be
42  * brought up on demand based on active {@link NetworkRequest}(s).
43  *
44  * @see VcnManager for more information on the Virtual Carrier Network feature
45  */
46 public final class VcnConfig implements Parcelable {
47     @NonNull private static final String TAG = VcnConfig.class.getSimpleName();
48 
49     private static final String PACKAGE_NAME_KEY = "mPackageName";
50     @NonNull private final String mPackageName;
51 
52     private static final String GATEWAY_CONNECTION_CONFIGS_KEY = "mGatewayConnectionConfigs";
53     @NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs;
54 
55     private static final String IS_TEST_MODE_PROFILE_KEY = "mIsTestModeProfile";
56     private final boolean mIsTestModeProfile;
57 
VcnConfig( @onNull String packageName, @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs, boolean isTestModeProfile)58     private VcnConfig(
59             @NonNull String packageName,
60             @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs,
61             boolean isTestModeProfile) {
62         mPackageName = packageName;
63         mGatewayConnectionConfigs =
64                 Collections.unmodifiableSet(new ArraySet<>(gatewayConnectionConfigs));
65         mIsTestModeProfile = isTestModeProfile;
66 
67         validate();
68     }
69 
70     /**
71      * Deserializes a VcnConfig from a PersistableBundle.
72      *
73      * @hide
74      */
75     @VisibleForTesting(visibility = Visibility.PRIVATE)
VcnConfig(@onNull PersistableBundle in)76     public VcnConfig(@NonNull PersistableBundle in) {
77         mPackageName = in.getString(PACKAGE_NAME_KEY);
78 
79         final PersistableBundle gatewayConnectionConfigsBundle =
80                 in.getPersistableBundle(GATEWAY_CONNECTION_CONFIGS_KEY);
81         mGatewayConnectionConfigs =
82                 new ArraySet<>(
83                         PersistableBundleUtils.toList(
84                                 gatewayConnectionConfigsBundle, VcnGatewayConnectionConfig::new));
85         mIsTestModeProfile = in.getBoolean(IS_TEST_MODE_PROFILE_KEY);
86 
87         validate();
88     }
89 
validate()90     private void validate() {
91         Objects.requireNonNull(mPackageName, "packageName was null");
92         Preconditions.checkCollectionNotEmpty(
93                 mGatewayConnectionConfigs, "gatewayConnectionConfigs was empty");
94     }
95 
96     /**
97      * Retrieve the package name of the provisioning app.
98      *
99      * @hide
100      */
101     @NonNull
getProvisioningPackageName()102     public String getProvisioningPackageName() {
103         return mPackageName;
104     }
105 
106     /** Retrieves the set of configured GatewayConnection(s). */
107     @NonNull
getGatewayConnectionConfigs()108     public Set<VcnGatewayConnectionConfig> getGatewayConnectionConfigs() {
109         return Collections.unmodifiableSet(mGatewayConnectionConfigs);
110     }
111 
112     /**
113      * Returns whether or not this VcnConfig is restricted to test networks.
114      *
115      * @hide
116      */
isTestModeProfile()117     public boolean isTestModeProfile() {
118         return mIsTestModeProfile;
119     }
120 
121     /**
122      * Serializes this object to a PersistableBundle.
123      *
124      * @hide
125      */
126     @NonNull
toPersistableBundle()127     public PersistableBundle toPersistableBundle() {
128         final PersistableBundle result = new PersistableBundle();
129 
130         result.putString(PACKAGE_NAME_KEY, mPackageName);
131 
132         final PersistableBundle gatewayConnectionConfigsBundle =
133                 PersistableBundleUtils.fromList(
134                         new ArrayList<>(mGatewayConnectionConfigs),
135                         VcnGatewayConnectionConfig::toPersistableBundle);
136         result.putPersistableBundle(GATEWAY_CONNECTION_CONFIGS_KEY, gatewayConnectionConfigsBundle);
137         result.putBoolean(IS_TEST_MODE_PROFILE_KEY, mIsTestModeProfile);
138 
139         return result;
140     }
141 
142     @Override
hashCode()143     public int hashCode() {
144         return Objects.hash(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile);
145     }
146 
147     @Override
equals(@ullable Object other)148     public boolean equals(@Nullable Object other) {
149         if (!(other instanceof VcnConfig)) {
150             return false;
151         }
152 
153         final VcnConfig rhs = (VcnConfig) other;
154         return mPackageName.equals(rhs.mPackageName)
155                 && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs)
156                 && mIsTestModeProfile == rhs.mIsTestModeProfile;
157     }
158 
159     // Parcelable methods
160 
161     @Override
describeContents()162     public int describeContents() {
163         return 0;
164     }
165 
166     @Override
writeToParcel(@onNull Parcel out, int flags)167     public void writeToParcel(@NonNull Parcel out, int flags) {
168         out.writeParcelable(toPersistableBundle(), flags);
169     }
170 
171     @NonNull
172     public static final Parcelable.Creator<VcnConfig> CREATOR =
173             new Parcelable.Creator<VcnConfig>() {
174                 @NonNull
175                 public VcnConfig createFromParcel(Parcel in) {
176                     return new VcnConfig((PersistableBundle) in.readParcelable(null));
177                 }
178 
179                 @NonNull
180                 public VcnConfig[] newArray(int size) {
181                     return new VcnConfig[size];
182                 }
183             };
184 
185     /** This class is used to incrementally build {@link VcnConfig} objects. */
186     public static final class Builder {
187         @NonNull private final String mPackageName;
188 
189         @NonNull
190         private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs = new ArraySet<>();
191 
192         private boolean mIsTestModeProfile = false;
193 
Builder(@onNull Context context)194         public Builder(@NonNull Context context) {
195             Objects.requireNonNull(context, "context was null");
196 
197             mPackageName = context.getOpPackageName();
198         }
199 
200         /**
201          * Adds a configuration for an individual gateway connection.
202          *
203          * @param gatewayConnectionConfig the configuration for an individual gateway connection
204          * @return this {@link Builder} instance, for chaining
205          * @throws IllegalArgumentException if a VcnGatewayConnectionConfig has already been set for
206          *     this {@link VcnConfig} with the same GatewayConnection name (as returned via {@link
207          *     VcnGatewayConnectionConfig#getGatewayConnectionName()}).
208          */
209         @NonNull
addGatewayConnectionConfig( @onNull VcnGatewayConnectionConfig gatewayConnectionConfig)210         public Builder addGatewayConnectionConfig(
211                 @NonNull VcnGatewayConnectionConfig gatewayConnectionConfig) {
212             Objects.requireNonNull(gatewayConnectionConfig, "gatewayConnectionConfig was null");
213 
214             for (final VcnGatewayConnectionConfig vcnGatewayConnectionConfig :
215                     mGatewayConnectionConfigs) {
216                 if (vcnGatewayConnectionConfig
217                         .getGatewayConnectionName()
218                         .equals(gatewayConnectionConfig.getGatewayConnectionName())) {
219                     throw new IllegalArgumentException(
220                             "GatewayConnection for specified name already exists");
221                 }
222             }
223 
224             mGatewayConnectionConfigs.add(gatewayConnectionConfig);
225             return this;
226         }
227 
228         /**
229          * Restricts this VcnConfig to matching with test networks (only).
230          *
231          * <p>This method is for testing only, and must not be used by apps. Calling {@link
232          * VcnManager#setVcnConfig(ParcelUuid, VcnConfig)} with a VcnConfig where test-network usage
233          * is enabled will require the MANAGE_TEST_NETWORKS permission.
234          *
235          * @return this {@link Builder} instance, for chaining
236          * @hide
237          */
238         @NonNull
setIsTestModeProfile()239         public Builder setIsTestModeProfile() {
240             mIsTestModeProfile = true;
241             return this;
242         }
243 
244         /**
245          * Builds and validates the VcnConfig.
246          *
247          * @return an immutable VcnConfig instance
248          */
249         @NonNull
build()250         public VcnConfig build() {
251             return new VcnConfig(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile);
252         }
253     }
254 }
255