/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package android.net; import android.Manifest.permission; import android.annotation.SystemApi; import android.content.Context; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import com.android.internal.util.Preconditions; import java.util.concurrent.Executor; /** * The base class for implementing a network recommendation provider. *
* A network recommendation provider is any application which: *
* Implementations are required to implement the abstract methods in this class and return the
* result of {@link #getBinder()} from the onBind()
method in their Service.
*
* The default network recommendation provider is controlled via the
* config_defaultNetworkRecommendationProviderPackage
config key.
* @hide
*/
@SystemApi
public abstract class NetworkRecommendationProvider {
private static final String TAG = "NetworkRecProvider";
private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
private final IBinder mService;
/**
* Constructs a new instance.
* @param context the current context instance. Cannot be {@code null}.
* @param executor used to execute the incoming requests. Cannot be {@code null}.
*/
public NetworkRecommendationProvider(Context context, Executor executor) {
Preconditions.checkNotNull(context);
Preconditions.checkNotNull(executor);
mService = new ServiceWrapper(context, executor);
}
/**
* Invoked when network scores have been requested.
*
* Use {@link NetworkScoreManager#updateScores(ScoredNetwork[])} to respond to score requests.
*
* @param networks a non-empty array of {@link NetworkKey}s to score.
*/
public abstract void onRequestScores(NetworkKey[] networks);
/**
* Services that can handle {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} should
* return this Binder from their onBind()
method.
*/
public final IBinder getBinder() {
return mService;
}
/**
* A wrapper around INetworkRecommendationProvider that dispatches to the provided Handler.
*/
private final class ServiceWrapper extends INetworkRecommendationProvider.Stub {
private final Context mContext;
private final Executor mExecutor;
private final Handler mHandler;
ServiceWrapper(Context context, Executor executor) {
mContext = context;
mExecutor = executor;
mHandler = null;
}
@Override
public void requestScores(final NetworkKey[] networks) throws RemoteException {
enforceCallingPermission();
if (networks != null && networks.length > 0) {
execute(new Runnable() {
@Override
public void run() {
onRequestScores(networks);
}
});
}
}
private void execute(Runnable command) {
if (mExecutor != null) {
mExecutor.execute(command);
} else {
mHandler.post(command);
}
}
private void enforceCallingPermission() {
if (mContext != null) {
mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES,
"Permission denied.");
}
}
}
}