blob: fdb4ba0738932694bf51a601b3fa281520a97b19 [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.
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.
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080047 * @hide
48 */
49@SystemApi
50public abstract class NetworkRecommendationProvider {
51 private static final String TAG = "NetworkRecProvider";
Jeremy Joslin4ad7ca02017-02-13 11:35:03 -080052 private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080053 private final IBinder mService;
54
55 /**
56 * Constructs a new instance.
Jeremy Joslin81605442017-02-21 16:20:35 -080057 * @param context the current context instance. Cannot be {@code null}.
58 * @param executor used to execute the incoming requests. Cannot be {@code null}.
59 */
60 public NetworkRecommendationProvider(Context context, Executor executor) {
61 Preconditions.checkNotNull(context);
62 Preconditions.checkNotNull(executor);
63 mService = new ServiceWrapper(context, executor);
64 }
65
66 /**
Jeremy Josline7f273d2016-12-13 16:11:51 -080067 * 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 */
73 public abstract void onRequestScores(NetworkKey[] networks);
74
75 /**
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080076 * Services that can handle {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} should
77 * return this Binder from their <code>onBind()</code> method.
78 */
79 public final IBinder getBinder() {
80 return mService;
81 }
82
Jeremy Joslin280f82c2016-12-08 10:24:02 -080083 /**
Jeremy Joslinc695a172017-01-31 11:51:25 -080084 * A wrapper around INetworkRecommendationProvider that dispatches to the provided Handler.
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080085 */
Jeremy Joslinc695a172017-01-31 11:51:25 -080086 private final class ServiceWrapper extends INetworkRecommendationProvider.Stub {
Jeremy Joslin81605442017-02-21 16:20:35 -080087 private final Context mContext;
88 private final Executor mExecutor;
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080089 private final Handler mHandler;
90
Jeremy Joslin81605442017-02-21 16:20:35 -080091 ServiceWrapper(Context context, Executor executor) {
92 mContext = context;
93 mExecutor = executor;
94 mHandler = null;
Jeremy Joslind1daf6d2016-11-28 17:47:35 -080095 }
96
97 @Override
Jeremy Joslinc695a172017-01-31 11:51:25 -080098 public void requestScores(final NetworkKey[] networks) throws RemoteException {
Jeremy Joslin81605442017-02-21 16:20:35 -080099 enforceCallingPermission();
Jeremy Josline7f273d2016-12-13 16:11:51 -0800100 if (networks != null && networks.length > 0) {
Jeremy Joslin81605442017-02-21 16:20:35 -0800101 execute(new Runnable() {
Jeremy Joslinc695a172017-01-31 11:51:25 -0800102 @Override
103 public void run() {
104 onRequestScores(networks);
105 }
106 });
Jeremy Josline7f273d2016-12-13 16:11:51 -0800107 }
108 }
Jeremy Joslin81605442017-02-21 16:20:35 -0800109
110 private void execute(Runnable command) {
111 if (mExecutor != null) {
112 mExecutor.execute(command);
113 } else {
114 mHandler.post(command);
115 }
116 }
117
118 private void enforceCallingPermission() {
119 if (mContext != null) {
120 mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES,
121 "Permission denied.");
122 }
123 }
Jeremy Joslind1daf6d2016-11-28 17:47:35 -0800124 }
125}