Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1daf6d2 authored by Jeremy Joslin's avatar Jeremy Joslin
Browse files

API for requesting network recommendations.

Defining a new system API that will allow the system to request
network recommendations from a NetworkScoreService implementation.

Test: Coming in a future CL.
BUG: 32909424
Merged-In: I2d5c0a843b928b04e87c1862a78702a02fd54c31
Change-Id: Idd33095c6cd2f5b391796c900399f18a2c40fcc3
parent 9600df03
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ LOCAL_SRC_FILES += \
	core/java/android/net/INetworkManagementEventObserver.aidl \
	core/java/android/net/INetworkPolicyListener.aidl \
	core/java/android/net/INetworkPolicyManager.aidl \
	core/java/android/net/INetworkRecommendationProvider.aidl \
	core/java/android/net/INetworkScoreCache.aidl \
	core/java/android/net/INetworkScoreService.aidl \
	core/java/android/net/INetworkStatsService.aidl \
+31 −0
Original line number Diff line number Diff line
@@ -25493,6 +25493,14 @@ package android.net {
    field public final android.net.WifiKey wifiKey;
  }
  public abstract class NetworkRecommendationProvider {
    ctor public NetworkRecommendationProvider(android.os.Handler);
    method public final android.os.IBinder getBinder();
    method public abstract android.net.RecommendationResult onRequestRecommendation(android.net.RecommendationRequest);
    field public static final java.lang.String EXTRA_RECOMMENDATION_RESULT = "android.net.extra.RECOMMENDATION_RESULT";
    field public static final java.lang.String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
  }
  public class NetworkRequest implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
@@ -25513,10 +25521,12 @@ package android.net {
    method public boolean clearScores() throws java.lang.SecurityException;
    method public void disableScoring() throws java.lang.SecurityException;
    method public java.lang.String getActiveScorerPackage();
    method public android.net.RecommendationResult requestRecommendation(android.net.RecommendationRequest) throws java.lang.SecurityException;
    method public boolean setActiveScorer(java.lang.String) throws java.lang.SecurityException;
    method public boolean updateScores(android.net.ScoredNetwork[]) throws java.lang.SecurityException;
    field public static final java.lang.String ACTION_CHANGE_ACTIVE = "android.net.scoring.CHANGE_ACTIVE";
    field public static final java.lang.String ACTION_CUSTOM_ENABLE = "android.net.scoring.CUSTOM_ENABLE";
    field public static final java.lang.String ACTION_RECOMMEND_NETWORKS = "android.net.action.RECOMMEND_NETWORKS";
    field public static final java.lang.String ACTION_SCORER_CHANGED = "android.net.scoring.SCORER_CHANGED";
    field public static final java.lang.String ACTION_SCORE_NETWORKS = "android.net.scoring.SCORE_NETWORKS";
    field public static final java.lang.String EXTRA_NETWORKS_TO_SCORE = "networksToScore";
@@ -25564,6 +25574,24 @@ package android.net {
    field public static final int MAX_KEY_LENGTH_BYTES = 256; // 0x100
  }
  public final class RecommendationRequest implements android.os.Parcelable {
    ctor protected RecommendationRequest(android.os.Parcel);
    method public int describeContents();
    method public android.net.wifi.WifiConfiguration getCurrentSelectedConfig();
    method public android.net.NetworkCapabilities getRequiredCapabilities();
    method public android.net.wifi.ScanResult[] getScanResults();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.net.RecommendationRequest> CREATOR;
  }
  public final class RecommendationResult implements android.os.Parcelable {
    ctor public RecommendationResult(android.net.wifi.WifiConfiguration);
    method public int describeContents();
    method public android.net.wifi.WifiConfiguration getWifiConfiguration();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.net.RecommendationResult> CREATOR;
  }
  public final class RouteInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.net.IpPrefix getDestination();
@@ -25617,9 +25645,12 @@ package android.net {
  public class ScoredNetwork implements android.os.Parcelable {
    ctor public ScoredNetwork(android.net.NetworkKey, android.net.RssiCurve);
    ctor public ScoredNetwork(android.net.NetworkKey, android.net.RssiCurve, boolean);
    ctor public ScoredNetwork(android.net.NetworkKey, android.net.RssiCurve, boolean, android.os.Bundle);
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.net.ScoredNetwork> CREATOR;
    field public static final java.lang.String EXTRA_HAS_CAPTIVE_PORTAL = "android.net.extra.HAS_CAPTIVE_PORTAL";
    field public final android.os.Bundle attributes;
    field public final boolean meteredHint;
    field public final android.net.NetworkKey networkKey;
    field public final android.net.RssiCurve rssiCurve;
+41 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2016, 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.net.RecommendationRequest;
import android.os.IRemoteCallback;

/**
 * The service responsible for answering network recommendation requests.
 * @hide
 */
oneway interface INetworkRecommendationProvider {

    /**
     * Request a recommendation for the best network to connect to
     * taking into account the inputs from the {@link RecommendationRequest}.
     *
     * @param request a {@link RecommendationRequest} instance containing the details of the request
     * @param callback a {@link IRemoteCallback} instance to invoke when the recommendation
     *                 is available
     * @param sequence an internal number used for tracking the request
     * @hide
     */
    void requestRecommendation(in RecommendationRequest request,
                               in IRemoteCallback callback,
                               int sequence);
}
 No newline at end of file
+12 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package android.net;

import android.net.INetworkScoreCache;
import android.net.RecommendationRequest;
import android.net.RecommendationResult;
import android.net.ScoredNetwork;

/**
@@ -64,4 +66,14 @@ interface INetworkScoreService
     */
    void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache);

    /**
     * Request a recommendation for the best network to connect to
     * taking into account the inputs from the {@link RecommendationRequest}.
     *
     * @param request a {@link RecommendationRequest} instance containing the details of the request
     * @return a {@link RecommendationResult} containing the recommended network to connect to
     * @throws SecurityException if the caller is not the system
     */
    RecommendationResult requestRecommendation(in RecommendationRequest request);

}
+114 −0
Original line number Diff line number Diff line
package android.net;

import android.annotation.SystemApi;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

/**
 * The base class for implementing a network recommendation provider.
 * @hide
 */
@SystemApi
public abstract class NetworkRecommendationProvider {
    private static final String TAG = "NetworkRecProvider";
    /** The key into the callback Bundle where the RecommendationResult will be found. */
    public static final String EXTRA_RECOMMENDATION_RESULT =
            "android.net.extra.RECOMMENDATION_RESULT";
    /** The key into the callback Bundle where the sequence will be found. */
    public static final String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
    private static final String EXTRA_RECOMMENDATION_REQUEST =
            "android.net.extra.RECOMMENDATION_REQUEST";
    private final IBinder mService;

    /**
     * Constructs a new instance.
     * @param handler indicates which thread to use when handling requests. Cannot be {@code null}.
     */
    public NetworkRecommendationProvider(Handler handler) {
        if (handler == null) {
            throw new IllegalArgumentException("The provided handler cannot be null.");
        }
        mService = new ServiceWrapper(new ServiceHandler(handler.getLooper()));
    }

    /**
     * Invoked when a recommendation has been requested.
     *
     * @param request a {@link RecommendationRequest} instance containing additional
     *                request details
     * @return a {@link RecommendationResult} instance containing the recommended
     *         network to connect to
     */
    public abstract RecommendationResult onRequestRecommendation(RecommendationRequest request);


    /**
     * Services that can handle {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} should
     * return this Binder from their <code>onBind()</code> method.
     */
    public final IBinder getBinder() {
        return mService;
    }

    private final class ServiceHandler extends Handler {
        static final int MSG_GET_RECOMMENDATION = 1;

        ServiceHandler(Looper looper) {
            super(looper, null /*callback*/, true /*async*/);
        }

        @Override
        public void handleMessage(Message msg) {
            final int what = msg.what;
            switch (what) {
                case MSG_GET_RECOMMENDATION:
                    final IRemoteCallback callback = (IRemoteCallback) msg.obj;
                    final int seq = msg.arg1;
                    final RecommendationRequest request =
                            msg.getData().getParcelable(EXTRA_RECOMMENDATION_REQUEST);
                    final RecommendationResult result = onRequestRecommendation(request);
                    final Bundle data = new Bundle();
                    data.putInt(EXTRA_SEQUENCE, seq);
                    data.putParcelable(EXTRA_RECOMMENDATION_RESULT, result);
                    try {
                        callback.sendResult(data);
                    } catch (RemoteException e) {
                        Log.w(TAG, "Callback failed for seq: " + seq, e);
                    }

                    break;

                default:
                    throw new IllegalArgumentException("Unknown message: " + what);
            }
        }
    }

    /**
     * A wrapper around INetworkRecommendationProvider that sends calls to the internal Handler.
     */
    private static final class ServiceWrapper extends INetworkRecommendationProvider.Stub {
        private final Handler mHandler;

        ServiceWrapper(Handler handler) {
            mHandler = handler;
        }

        @Override
        public void requestRecommendation(RecommendationRequest request, IRemoteCallback callback,
                int sequence) throws RemoteException {
            final Message msg = mHandler.obtainMessage(
                    ServiceHandler.MSG_GET_RECOMMENDATION, sequence, 0 /*arg2*/, callback);
            final Bundle data = new Bundle();
            data.putParcelable(EXTRA_RECOMMENDATION_REQUEST, request);
            msg.setData(data);
            msg.sendToTarget();
        }
    }
}
Loading