1 /*
2  * Copyright (C) 2014 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 
17 package android.net;
18 
19 import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.content.Context;
24 import android.os.Looper;
25 import android.os.Message;
26 import android.util.Log;
27 
28 import com.android.internal.annotations.VisibleForTesting;
29 
30 import java.io.FileDescriptor;
31 import java.io.PrintWriter;
32 
33 /**
34  * A NetworkFactory is an entity that creates NetworkAgent objects.
35  * The bearers register with ConnectivityService using {@link #register} and
36  * their factory will start receiving scored NetworkRequests.  NetworkRequests
37  * can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by
38  * overridden function.  All of these can be dynamic - changing NetworkCapabilities
39  * or score forces re-evaluation of all current requests.
40  *
41  * If any requests pass the filter some overrideable functions will be called.
42  * If the bearer only cares about very simple start/stopNetwork callbacks, those
43  * functions can be overridden.  If the bearer needs more interaction, it can
44  * override addNetworkRequest and removeNetworkRequest which will give it each
45  * request that passes their current filters.
46  *
47  * This class is mostly a shim which delegates to one of two implementations depending
48  * on the SDK level of the device it's running on.
49  *
50  * @hide
51  **/
52 public class NetworkFactory {
53     static final boolean DBG = true;
54     static final boolean VDBG = false;
55 
56     final NetworkFactoryShim mImpl;
57 
58     private final String LOG_TAG;
59 
60     // Ideally the filter argument would be non-null, but null has historically meant to see
61     // no requests and telephony passes null.
NetworkFactory(Looper looper, Context context, String logTag, @Nullable final NetworkCapabilities filter)62     public NetworkFactory(Looper looper, Context context, String logTag,
63             @Nullable final NetworkCapabilities filter) {
64         LOG_TAG = logTag;
65         if (isAtLeastS()) {
66             mImpl = new NetworkFactoryImpl(this, looper, context, filter);
67         } else {
68             mImpl = new NetworkFactoryLegacyImpl(this, looper, context, filter);
69         }
70     }
71 
72     // TODO : these two constants and the method are only used by telephony tests. Replace it in
73     // the tests and remove them and the associated code.
74     public static final int CMD_REQUEST_NETWORK = 1;
75     public static final int CMD_CANCEL_REQUEST = 2;
76     /** Like Handler#obtainMessage */
77     @VisibleForTesting
obtainMessage(final int what, final int arg1, final int arg2, final @Nullable Object obj)78     public Message obtainMessage(final int what, final int arg1, final int arg2,
79             final @Nullable Object obj) {
80         return mImpl.obtainMessage(what, arg1, arg2, obj);
81     }
82 
83     // Called by BluetoothNetworkFactory
getLooper()84     public final Looper getLooper() {
85         return mImpl.getLooper();
86     }
87 
88     // Refcount for simple mode requests
89     private int mRefCount = 0;
90 
91     /* Registers this NetworkFactory with the system. May only be called once per factory. */
register()92     public void register() {
93         mImpl.register(LOG_TAG);
94     }
95 
96     /**
97      * Registers this NetworkFactory with the system ignoring the score filter. This will let
98      * the factory always see all network requests matching its capabilities filter.
99      * May only be called once per factory.
100      */
registerIgnoringScore()101     public void registerIgnoringScore() {
102         mImpl.registerIgnoringScore(LOG_TAG);
103     }
104 
105     /** Unregisters this NetworkFactory. After this call, the object can no longer be used. */
terminate()106     public void terminate() {
107         mImpl.terminate();
108     }
109 
reevaluateAllRequests()110     protected final void reevaluateAllRequests() {
111         mImpl.reevaluateAllRequests();
112     }
113 
114     /**
115      * Overridable function to provide complex filtering.
116      * Called for every request every time a new NetworkRequest is seen
117      * and whenever the filterScore or filterNetworkCapabilities change.
118      *
119      * acceptRequest can be overridden to provide complex filter behavior
120      * for the incoming requests
121      *
122      * For output, this class will call {@link #needNetworkFor} and
123      * {@link #releaseNetworkFor} for every request that passes the filters.
124      * If you don't need to see every request, you can leave the base
125      * implementations of those two functions and instead override
126      * {@link #startNetwork} and {@link #stopNetwork}.
127      *
128      * If you want to see every score fluctuation on every request, set
129      * your score filter to a very high number and watch {@link #needNetworkFor}.
130      *
131      * @return {@code true} to accept the request.
132      */
acceptRequest(@onNull final NetworkRequest request)133     public boolean acceptRequest(@NonNull final NetworkRequest request) {
134         return true;
135     }
136 
137     /**
138      * Can be called by a factory to release a request as unfulfillable: the request will be
139      * removed, and the caller will get a
140      * {@link ConnectivityManager.NetworkCallback#onUnavailable()} callback after this function
141      * returns.
142      *
143      * Note: this should only be called by factory which KNOWS that it is the ONLY factory which
144      * is able to fulfill this request!
145      */
releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r)146     protected void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) {
147         mImpl.releaseRequestAsUnfulfillableByAnyFactory(r);
148     }
149 
150     // override to do simple mode (request independent)
startNetwork()151     protected void startNetwork() { }
stopNetwork()152     protected void stopNetwork() { }
153 
154     // override to do fancier stuff
needNetworkFor(@onNull final NetworkRequest networkRequest)155     protected void needNetworkFor(@NonNull final NetworkRequest networkRequest) {
156         if (++mRefCount == 1) startNetwork();
157     }
158 
releaseNetworkFor(@onNull final NetworkRequest networkRequest)159     protected void releaseNetworkFor(@NonNull final NetworkRequest networkRequest) {
160         if (--mRefCount == 0) stopNetwork();
161     }
162 
163     /**
164      * @deprecated this method was never part of the API (system or public) and is only added
165      *   for migration of existing clients.
166      */
167     @Deprecated
setScoreFilter(final int score)168     public void setScoreFilter(final int score) {
169         mImpl.setScoreFilter(score);
170     }
171 
172     /**
173      * Set a score filter for this factory.
174      *
175      * This should include the transports the factory knows its networks will have, and
176      * an optimistic view of the attributes it may have. This does not commit the factory
177      * to being able to bring up such a network ; it only lets it avoid hearing about
178      * requests that it has no chance of fulfilling.
179      *
180      * @param score the filter
181      */
setScoreFilter(@onNull final NetworkScore score)182     public void setScoreFilter(@NonNull final NetworkScore score) {
183         mImpl.setScoreFilter(score);
184     }
185 
setCapabilityFilter(NetworkCapabilities netCap)186     public void setCapabilityFilter(NetworkCapabilities netCap) {
187         mImpl.setCapabilityFilter(netCap);
188     }
189 
190     @VisibleForTesting
getRequestCount()191     protected int getRequestCount() {
192         return mImpl.getRequestCount();
193     }
194 
getSerialNumber()195     public int getSerialNumber() {
196         return mImpl.getSerialNumber();
197     }
198 
getProvider()199     public NetworkProvider getProvider() {
200         return mImpl.getProvider();
201     }
202 
log(String s)203     protected void log(String s) {
204         Log.d(LOG_TAG, s);
205     }
206 
dump(FileDescriptor fd, PrintWriter writer, String[] args)207     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
208         mImpl.dump(fd, writer, args);
209     }
210 
211     @Override
toString()212     public String toString() {
213         return "{" + LOG_TAG + " " + mImpl.toString() + "}";
214     }
215 }
216