blob: a70c97bac10cf7cd401f86717a02cfec9cdf530e [file] [log] [blame]
Jeremy Joslin546a45c2017-04-25 15:43:13 -07001/*
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
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080017package android.net;
18
Jeremy Joslin81605442017-02-21 16:20:35 -080019import android.Manifest.permission;
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080020import android.annotation.SystemApi;
Jeremy Joslin81605442017-02-21 16:20:35 -080021import android.content.Context;
Jeremy Joslin4ad7ca02017-02-13 11:35:03 -080022import android.os.Build;
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080023import android.os.Handler;
24import android.os.IBinder;
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080025import android.os.RemoteException;
26import android.util.Log;
27
Jeremy Joslin81605442017-02-21 16:20:35 -080028import com.android.internal.util.Preconditions;
Jeremy Joslin280f82c2016-12-08 10:24:02 -080029
Jeremy Joslin81605442017-02-21 16:20:35 -080030import java.util.concurrent.Executor;
Jeremy Joslin280f82c2016-12-08 10:24:02 -080031
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080032/**
33 * The base class for implementing a network recommendation provider.
Jeremy Joslinf7909cc2017-04-13 10:33:26 -070034 * <p>
35 * A network recommendation provider is any application which:
36 * <ul>
37 * <li>Is granted the {@link permission#SCORE_NETWORKS} permission.
Jeremy Joslind816abe2017-07-14 15:00:53 -070038 * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission.
Jeremy Joslinf7909cc2017-04-13 10:33:26 -070039 * <li>Includes a Service for the {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} intent
40 * which is protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} permission.
41 * </ul>
42 * <p>
43 * Implementations are required to implement the abstract methods in this class and return the
44 * result of {@link #getBinder()} from the <code>onBind()</code> method in their Service.
45 * <p>
46 * The default network recommendation provider is controlled via the
47 * <code>config_defaultNetworkRecommendationProviderPackage</code> config key.
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080048 * @hide
49 */
50@SystemApi
51public abstract class NetworkRecommendationProvider {
52 private static final String TAG = "NetworkRecProvider";
Jeremy Joslin4ad7ca02017-02-13 11:35:03 -080053 private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080054 private final IBinder mService;
55
56 /**
57 * Constructs a new instance.
Jeremy Joslin81605442017-02-21 16:20:35 -080058 * @param context the current context instance. Cannot be {@code null}.
59 * @param executor used to execute the incoming requests. Cannot be {@code null}.
60 */
61 public NetworkRecommendationProvider(Context context, Executor executor) {
62 Preconditions.checkNotNull(context);
63 Preconditions.checkNotNull(executor);
64 mService = new ServiceWrapper(context, executor);
65 }
66
67 /**
Jeremy Josline7f273d2016-12-13 16:11:51 -080068 * Invoked when network scores have been requested.
69 * <p>
70 * Use {@link NetworkScoreManager#updateScores(ScoredNetwork[])} to respond to score requests.
71 *
72 * @param networks a non-empty array of {@link NetworkKey}s to score.
73 */
74 public abstract void onRequestScores(NetworkKey[] networks);
75
76 /**
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080077 * Services that can handle {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} should
78 * return this Binder from their <code>onBind()</code> method.
79 */
80 public final IBinder getBinder() {
81 return mService;
82 }
83
Jeremy Joslin280f82c2016-12-08 10:24:02 -080084 /**
Jeremy Joslinc695a172017-01-31 11:51:25 -080085 * A wrapper around INetworkRecommendationProvider that dispatches to the provided Handler.
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080086 */
Jeremy Joslinc695a172017-01-31 11:51:25 -080087 private final class ServiceWrapper extends INetworkRecommendationProvider.Stub {
Jeremy Joslin81605442017-02-21 16:20:35 -080088 private final Context mContext;
89 private final Executor mExecutor;
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080090 private final Handler mHandler;
91
Jeremy Joslin81605442017-02-21 16:20:35 -080092 ServiceWrapper(Context context, Executor executor) {
93 mContext = context;
94 mExecutor = executor;
95 mHandler = null;
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080096 }
97
98 @Override
Jeremy Joslinc695a172017-01-31 11:51:25 -080099 public void requestScores(final NetworkKey[] networks) throws RemoteException {
Jeremy Joslin81605442017-02-21 16:20:35 -0800100 enforceCallingPermission();
Jeremy Josline7f273d2016-12-13 16:11:51 -0800101 if (networks != null && networks.length > 0) {
Jeremy Joslin81605442017-02-21 16:20:35 -0800102 execute(new Runnable() {
Jeremy Joslinc695a172017-01-31 11:51:25 -0800103 @Override
104 public void run() {
105 onRequestScores(networks);
106 }
107 });
Jeremy Josline7f273d2016-12-13 16:11:51 -0800108 }
109 }
Jeremy Joslin81605442017-02-21 16:20:35 -0800110
111 private void execute(Runnable command) {
112 if (mExecutor != null) {
113 mExecutor.execute(command);
114 } else {
115 mHandler.post(command);
116 }
117 }
118
119 private void enforceCallingPermission() {
120 if (mContext != null) {
121 mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES,
122 "Permission denied.");
123 }
124 }
Jeremy Joslind1daf6d2016-11-28 17:47:35 -0800125 }
126}