• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 com.google.android.car.networking.preferenceupdater.components;
17 
18 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
19 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
20 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
21 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
22 
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.content.Context;
26 import android.net.ConnectivityManager;
27 import android.net.OemNetworkPreferences;
28 import android.util.Log;
29 import android.util.SparseArray;
30 
31 import java.util.Set;
32 import java.util.concurrent.CompletableFuture;
33 import java.util.concurrent.TimeUnit;
34 
35 /** Class wraps OemNetworkPreferences (PANS) APIs and routine around it */
36 public final class OemNetworkPreferencesAdapter {
37     private static final String TAG = OemNetworkPreferencesAdapter.class.getSimpleName();
38 
39     // Seconds to wait for setOemNetworkPreference() call to complete
40     private static final int PANS_CALL_TIMEOUT_SEC = 5;
41     public static final int[] OEM_NETWORK_PREFERENCE_ARRAY =
42             new int[] {
43                 OEM_NETWORK_PREFERENCE_OEM_PAID,
44                 OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK,
45                 OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY,
46                 OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY,
47             };
48 
49     private final ConnectivityManager mConnectivityManager;
50     private final Context mContext;
51 
52     private static class OemListenerCallback implements Runnable {
53         final CompletableFuture<Object> mDone = new CompletableFuture<>();
54 
55         @Override
run()56         public void run() {
57             mDone.complete(new Object());
58         }
59 
expectOnComplete()60         void expectOnComplete() throws Exception {
61             mDone.get(PANS_CALL_TIMEOUT_SEC, TimeUnit.SECONDS);
62         }
63     }
64 
OemNetworkPreferencesAdapter(Context ctx)65     public OemNetworkPreferencesAdapter(Context ctx) {
66         mConnectivityManager = ctx.getSystemService(ConnectivityManager.class);
67         mContext = ctx;
68     }
69 
70     /**
71      * Accepts mapping <OemNetworkPreference.<id>> -> <Set of applications> and calls PANS APIs to
72      * apply them.
73      */
applyPreference(@ullable SparseArray<Set<String>> preference)74     public void applyPreference(@Nullable SparseArray<Set<String>> preference) {
75         // We want to create listener and wait for the call to end before proceeding further.
76         // To address that better, we will use CompletableFuture.
77         final OemListenerCallback listener = new OemListenerCallback();
78         mConnectivityManager.setOemNetworkPreference(
79                 generatePrefsFrom(preference), r -> r.run(), listener);
80         // We don't want to be blocked and wait for results forver, thus we will wait for 5 seconds
81         // before cancelling future.
82         try {
83             listener.expectOnComplete();
84             Log.d(TAG, "New OEM Network Preferences are now applied.");
85         } catch (Exception ex) {
86             /**
87              * From 4 potential exceptions: - CancellationException - if this future was cancelled -
88              * ExecutionException - if this future completed exceptionally - InterruptedException -
89              * if the current thread was interrupted while waiting - TimeoutException - if the wait
90              * timed out For now since we are not handling exceptions customly, we simply print the
91              * exception and silence it.
92              *
93              * TODO(b/183749278): Improve exceptoin handling in this case.
94              */
95             Log.e(TAG, "Call into setOemNetworkPreference() has failed with exception", ex);
96         }
97     }
98 
99     /**
100      * This should reset the OEM Network preferences set by this application or by any other
101      * application which calls into setOemNetworkPreferences() API.
102      */
resetNetworkPreferences()103     public void resetNetworkPreferences() {
104         // Considering that applyPreference will call into setOemNetworkPreference() all we need
105         // is to pass null and it will delete PersonalStorage data and will reset PANS.
106         applyPreference(null);
107     }
108 
generatePrefsFrom(@ullable SparseArray<Set<String>> preference)109     private OemNetworkPreferences generatePrefsFrom(@Nullable SparseArray<Set<String>> preference) {
110         OemNetworkPreferences.Builder builder = new OemNetworkPreferences.Builder();
111 
112         // Iterate through all available oem network preference types
113         for (int type : OEM_NETWORK_PREFERENCE_ARRAY) {
114             Set<String> apps =
115                     preference == null
116                             ? OemAppsManager.getDefaultAppsFor(mContext, type)
117                             : preference.get(type);
118             addPreferenceFromAppsSet(type, builder, apps);
119         }
120         return builder.build();
121     }
122 
addPreferenceFromAppsSet( int type, @NonNull OemNetworkPreferences.Builder builder, @NonNull Set<String> apps)123     private void addPreferenceFromAppsSet(
124             int type, @NonNull OemNetworkPreferences.Builder builder, @NonNull Set<String> apps) {
125         for (String app : apps) {
126             builder.addNetworkPreference(app, type);
127         }
128     }
129 }
130