• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 android.Manifest.permission;
20 import android.annotation.SystemApi;
21 import android.content.Context;
22 import android.os.Build;
23 import android.os.Handler;
24 import android.os.IBinder;
25 import android.os.RemoteException;
26 import android.util.Log;
27 
28 import com.android.internal.util.Preconditions;
29 
30 import java.util.concurrent.Executor;
31 
32 /**
33  * The base class for implementing a network recommendation provider.
34  * <p>
35  * A network recommendation provider is any application which:
36  * <ul>
37  * <li>Is granted the {@link permission#SCORE_NETWORKS} permission.
38  * <li>Includes a Service for the {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} intent
39  *     which is protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} permission.
40  * </ul>
41  * <p>
42  * Implementations are required to implement the abstract methods in this class and return the
43  * result of {@link #getBinder()} from the <code>onBind()</code> method in their Service.
44  * <p>
45  * The default network recommendation provider is controlled via the
46  * <code>config_defaultNetworkRecommendationProviderPackage</code> config key.
47  * @hide
48  */
49 @SystemApi
50 public abstract class NetworkRecommendationProvider {
51     private static final String TAG = "NetworkRecProvider";
52     private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
53     private final IBinder mService;
54 
55     /**
56      * Constructs a new instance.
57      * @param context the current context instance. Cannot be {@code null}.
58      * @param executor used to execute the incoming requests. Cannot be {@code null}.
59      */
NetworkRecommendationProvider(Context context, Executor executor)60     public NetworkRecommendationProvider(Context context, Executor executor) {
61         Preconditions.checkNotNull(context);
62         Preconditions.checkNotNull(executor);
63         mService = new ServiceWrapper(context, executor);
64     }
65 
66     /**
67      * Invoked when network scores have been requested.
68      * <p>
69      * Use {@link NetworkScoreManager#updateScores(ScoredNetwork[])} to respond to score requests.
70      *
71      * @param networks a non-empty array of {@link NetworkKey}s to score.
72      */
onRequestScores(NetworkKey[] networks)73     public abstract void onRequestScores(NetworkKey[] networks);
74 
75     /**
76      * Services that can handle {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} should
77      * return this Binder from their <code>onBind()</code> method.
78      */
getBinder()79     public final IBinder getBinder() {
80         return mService;
81     }
82 
83     /**
84      * A wrapper around INetworkRecommendationProvider that dispatches to the provided Handler.
85      */
86     private final class ServiceWrapper extends INetworkRecommendationProvider.Stub {
87         private final Context mContext;
88         private final Executor mExecutor;
89         private final Handler mHandler;
90 
ServiceWrapper(Context context, Executor executor)91         ServiceWrapper(Context context, Executor executor) {
92             mContext = context;
93             mExecutor = executor;
94             mHandler = null;
95         }
96 
97         @Override
requestScores(final NetworkKey[] networks)98         public void requestScores(final NetworkKey[] networks) throws RemoteException {
99             enforceCallingPermission();
100             if (networks != null && networks.length > 0) {
101                 execute(new Runnable() {
102                     @Override
103                     public void run() {
104                         onRequestScores(networks);
105                     }
106                 });
107             }
108         }
109 
execute(Runnable command)110         private void execute(Runnable command) {
111             if (mExecutor != null) {
112                 mExecutor.execute(command);
113             } else {
114                 mHandler.post(command);
115             }
116         }
117 
enforceCallingPermission()118         private void enforceCallingPermission() {
119             if (mContext != null) {
120                 mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES,
121                         "Permission denied.");
122             }
123         }
124     }
125 }
126