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

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

Async network recommendation requests.

Exposing a new hidden API method that allows network recommendations
to be requested asynchronously.

Test: Built & run.
BUG:33784158
Change-Id: I8d210b686138cb42bf69185f0b2f2d25dfcb9dd1
Merged-In: I8f84b09f43a6c5fae5d8f03ec01e75c25b4b62d6
parent a83222e4
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.net.NetworkKey;
import android.net.RecommendationRequest;
import android.net.RecommendationResult;
import android.net.ScoredNetwork;
import android.os.RemoteCallback;

/**
 * A service for updating network scores from a network scorer application.
@@ -117,4 +118,16 @@ interface INetworkScoreService
     *         scorer.
     */
    String getActiveScorerPackage();
    
    /**
     * 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 remoteCallback a {@link RemoteCallback} instance to invoke when the recommendation
     *                       is available.
     * @throws SecurityException if the caller is not the system
     */
    oneway void requestRecommendationAsync(in RecommendationRequest request,
                                           in RemoteCallback remoteCallback);
}
+56 −0
Original line number Diff line number Diff line
@@ -16,17 +16,24 @@

package android.net;

import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;

import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkScorerAppManager.NetworkScorerAppData;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -356,4 +363,53 @@ public class NetworkScoreManager {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Request a recommendation for which network to connect to.
     *
     * <p>The callback will be run on the thread associated with provided {@link Handler}.
     *
     * @param request a {@link RecommendationRequest} instance containing additional
     *                request details
     * @param callback a {@link RecommendationCallback} instance that will be invoked when
     *                 the {@link RecommendationResult} is available
     * @param handler a {@link Handler} instance representing the thread to run the callback on.
     * @throws SecurityException
     * @hide
     */
    public void requestRecommendation(
            final @NonNull RecommendationRequest request,
            final @NonNull RecommendationCallback callback,
            final @NonNull Handler handler) {
        Preconditions.checkNotNull(request, "RecommendationRequest cannot be null.");
        Preconditions.checkNotNull(callback, "RecommendationCallback cannot be null.");
        Preconditions.checkNotNull(handler, "Handler cannot be null.");

        RemoteCallback remoteCallback = new RemoteCallback(new RemoteCallback.OnResultListener() {
            @Override
            public void onResult(Bundle data) {
                RecommendationResult result = data.getParcelable(EXTRA_RECOMMENDATION_RESULT);
                callback.onRecommendationAvailable(result);
            }
        }, handler);

        try {
            mService.requestRecommendationAsync(request, remoteCallback);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Callers of {@link #requestRecommendation(RecommendationRequest, RecommendationCallback, Handler)}
     * must pass in an implementation of this class.
     * @hide
     */
    public abstract static class RecommendationCallback {
        /**
         * Invoked when a {@link RecommendationResult} is available.
         * @param result a {@link RecommendationResult} instance.
         */
        public abstract void onRecommendationAvailable(RecommendationResult result);
    }
}
+28 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -553,6 +554,33 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
        }
    }

    /**
     * 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 remoteCallback a {@link IRemoteCallback} instance to invoke when the recommendation
     *                       is available.
     * @throws SecurityException if the caller is not the system
     */
    @Override
    public void requestRecommendationAsync(RecommendationRequest request,
            RemoteCallback remoteCallback) {
        // TODO(jjoslin): 12/28/16 - Provide actual impl.

        final RecommendationResult result;
        if (request != null && request.getCurrentSelectedConfig() != null) {
            result = RecommendationResult.createConnectRecommendation(
                    request.getCurrentSelectedConfig());
        } else {
            result = RecommendationResult.createDoNotConnectRecommendation();
        }

        final Bundle data = new Bundle();
        data.putParcelable(EXTRA_RECOMMENDATION_RESULT, result);
        remoteCallback.sendResult(data);
    }

    @Override
    public boolean requestScores(NetworkKey[] networks) {
        mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);