diff options
| -rw-r--r-- | Android.mk | 1 | ||||
| -rw-r--r-- | api/system-current.txt | 31 | ||||
| -rw-r--r-- | core/java/android/net/INetworkRecommendationProvider.aidl | 41 | ||||
| -rw-r--r-- | core/java/android/net/INetworkScoreService.aidl | 12 | ||||
| -rw-r--r-- | core/java/android/net/NetworkRecommendationProvider.java | 114 | ||||
| -rw-r--r-- | core/java/android/net/NetworkScoreManager.java | 26 | ||||
| -rw-r--r-- | core/java/android/net/RecommendationRequest.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/net/RecommendationRequest.java | 137 | ||||
| -rw-r--r-- | core/java/android/net/RecommendationResult.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/net/RecommendationResult.java | 75 | ||||
| -rw-r--r-- | core/java/android/net/ScoredNetwork.java | 61 | ||||
| -rw-r--r-- | services/core/java/com/android/server/NetworkScoreService.java | 13 |
12 files changed, 544 insertions, 5 deletions
diff --git a/Android.mk b/Android.mk index cdb3834e3043..7230cbff33d9 100644 --- a/Android.mk +++ b/Android.mk @@ -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 \ diff --git a/api/system-current.txt b/api/system-current.txt index 98c90bb21c19..266da4cde423 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -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; diff --git a/core/java/android/net/INetworkRecommendationProvider.aidl b/core/java/android/net/INetworkRecommendationProvider.aidl new file mode 100644 index 000000000000..5e455d3e33fe --- /dev/null +++ b/core/java/android/net/INetworkRecommendationProvider.aidl @@ -0,0 +1,41 @@ +/** + * 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 diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl index 438692643c6c..59cbf6e93894 100644 --- a/core/java/android/net/INetworkScoreService.aidl +++ b/core/java/android/net/INetworkScoreService.aidl @@ -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); + } diff --git a/core/java/android/net/NetworkRecommendationProvider.java b/core/java/android/net/NetworkRecommendationProvider.java new file mode 100644 index 000000000000..cd2ede84cfdc --- /dev/null +++ b/core/java/android/net/NetworkRecommendationProvider.java @@ -0,0 +1,114 @@ +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(); + } + } +} diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java index b93bf59d5ac4..c301fe3b73fe 100644 --- a/core/java/android/net/NetworkScoreManager.java +++ b/core/java/android/net/NetworkScoreManager.java @@ -117,6 +117,14 @@ public class NetworkScoreManager { public static final String ACTION_SCORER_CHANGED = "android.net.scoring.SCORER_CHANGED"; /** + * Service action: Used to discover and bind to a network recommendation provider. + * Implementations should return {@link NetworkRecommendationProvider#getBinder()} from + * their <code>onBind()</code> method. + */ + @SdkConstant(SdkConstantType.SERVICE_ACTION) + public static final String ACTION_RECOMMEND_NETWORKS = "android.net.action.RECOMMEND_NETWORKS"; + + /** * Extra used with {@link #ACTION_SCORER_CHANGED} to specify the newly selected scorer's package * name. Will be null if scoring was disabled. Can be obtained with * {@link android.content.Intent#getStringExtra(String)}. @@ -269,4 +277,22 @@ public class NetworkScoreManager { throw e.rethrowFromSystemServer(); } } + + /** + * Request a recommendation for which network to connect to. + * + * @param request a {@link RecommendationRequest} instance containing additional + * request details + * @return a {@link RecommendationResult} instance containing the recommended network + * to connect to + * @throws SecurityException + */ + public RecommendationResult requestRecommendation(RecommendationRequest request) + throws SecurityException { + try { + return mService.requestRecommendation(request); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/net/RecommendationRequest.aidl b/core/java/android/net/RecommendationRequest.aidl new file mode 100644 index 000000000000..76497b8a2270 --- /dev/null +++ b/core/java/android/net/RecommendationRequest.aidl @@ -0,0 +1,19 @@ +/** + * 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; + +parcelable RecommendationRequest; diff --git a/core/java/android/net/RecommendationRequest.java b/core/java/android/net/RecommendationRequest.java new file mode 100644 index 000000000000..05ca1aa437f9 --- /dev/null +++ b/core/java/android/net/RecommendationRequest.java @@ -0,0 +1,137 @@ +/* + * 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.annotation.SystemApi; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * A request for a network recommendation. + * + * @see {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}. + * @hide + */ +@SystemApi +public final class RecommendationRequest implements Parcelable { + private final ScanResult[] mScanResults; + private final WifiConfiguration mCurrentSelectedConfig; + private final NetworkCapabilities mRequiredCapabilities; + + /** + * Builder class for constructing {@link RecommendationRequest} instances. + * @hide + */ + public static final class Builder { + private ScanResult[] mScanResults; + private WifiConfiguration mCurrentConfig; + private NetworkCapabilities mNetworkCapabilities; + + public Builder setScanResults(ScanResult[] scanResults) { + mScanResults = scanResults; + return this; + } + + public Builder setCurrentRecommendedWifiConfig(WifiConfiguration config) { + this.mCurrentConfig = config; + return this; + } + + public Builder setNetworkCapabilities(NetworkCapabilities capabilities) { + mNetworkCapabilities = capabilities; + return this; + } + + public RecommendationRequest build() { + return new RecommendationRequest(mScanResults, mCurrentConfig, mNetworkCapabilities); + } + } + + /** + * @return the array of {@link ScanResult}s the recommendation must be constrained to i.e. if a + * non-null wifi config recommendation is returned then it must be able to connect to + * one of the networks in the results list. + * + * If the array is {@code null} or empty then there is no constraint. + */ + public ScanResult[] getScanResults() { + return mScanResults; + } + + /** + * @return The best recommendation at the time this {@code RecommendationRequest} instance + * was created. This may be null which indicates that no recommendation is available. + */ + public WifiConfiguration getCurrentSelectedConfig() { + return mCurrentSelectedConfig; + } + + /** + * + * @return The set of {@link NetworkCapabilities} the recommendation must be constrained to. + * This may be {@code null} which indicates that there are no constraints on the + * capabilities of the recommended network. + */ + public NetworkCapabilities getRequiredCapabilities() { + return mRequiredCapabilities; + } + + @VisibleForTesting + RecommendationRequest(ScanResult[] scanResults, + WifiConfiguration currentSelectedConfig, + NetworkCapabilities requiredCapabilities) { + mScanResults = scanResults; + mCurrentSelectedConfig = currentSelectedConfig; + mRequiredCapabilities = requiredCapabilities; + } + + protected RecommendationRequest(Parcel in) { + mScanResults = (ScanResult[]) in.readParcelableArray(ScanResult.class.getClassLoader()); + mCurrentSelectedConfig = in.readParcelable(WifiConfiguration.class.getClassLoader()); + mRequiredCapabilities = in.readParcelable(NetworkCapabilities.class.getClassLoader()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelableArray(mScanResults, flags); + dest.writeParcelable(mCurrentSelectedConfig, flags); + dest.writeParcelable(mRequiredCapabilities, flags); + } + + public static final Creator<RecommendationRequest> CREATOR = + new Creator<RecommendationRequest>() { + @Override + public RecommendationRequest createFromParcel(Parcel in) { + return new RecommendationRequest(in); + } + + @Override + public RecommendationRequest[] newArray(int size) { + return new RecommendationRequest[size]; + } + }; +} diff --git a/core/java/android/net/RecommendationResult.aidl b/core/java/android/net/RecommendationResult.aidl new file mode 100644 index 000000000000..f36995b8cc68 --- /dev/null +++ b/core/java/android/net/RecommendationResult.aidl @@ -0,0 +1,19 @@ +/** + * 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; + +parcelable RecommendationResult; diff --git a/core/java/android/net/RecommendationResult.java b/core/java/android/net/RecommendationResult.java new file mode 100644 index 000000000000..a330d8445151 --- /dev/null +++ b/core/java/android/net/RecommendationResult.java @@ -0,0 +1,75 @@ +/* + * 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.annotation.Nullable; +import android.annotation.SystemApi; +import android.net.wifi.WifiConfiguration; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * The result of a network recommendation. + * + * @see {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}. + * @hide + */ +@SystemApi +public final class RecommendationResult implements Parcelable { + private final WifiConfiguration mWifiConfiguration; + + public RecommendationResult(@Nullable WifiConfiguration wifiConfiguration) { + mWifiConfiguration = wifiConfiguration; + } + + private RecommendationResult(Parcel in) { + mWifiConfiguration = in.readParcelable(WifiConfiguration.class.getClassLoader()); + } + + /** + * @return The recommended {@link WifiConfiguration} to connect to. A {@code null} value + * indicates that no WiFi connection should be attempted at this time. + */ + public WifiConfiguration getWifiConfiguration() { + return mWifiConfiguration; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeParcelable(mWifiConfiguration, flags); + } + + public static final Creator<RecommendationResult> CREATOR = + new Creator<RecommendationResult>() { + @Override + public RecommendationResult createFromParcel(Parcel in) { + return new RecommendationResult(in); + } + + @Override + public RecommendationResult[] newArray(int size) { + return new RecommendationResult[size]; + } + }; +} diff --git a/core/java/android/net/ScoredNetwork.java b/core/java/android/net/ScoredNetwork.java index 85821506fa3e..0f3f957ca9bc 100644 --- a/core/java/android/net/ScoredNetwork.java +++ b/core/java/android/net/ScoredNetwork.java @@ -17,6 +17,7 @@ package android.net; import android.annotation.SystemApi; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -29,6 +30,20 @@ import java.util.Objects; */ @SystemApi public class ScoredNetwork implements Parcelable { + /** + * Extra used with {@link #attributes} to specify whether the + * network is believed to have a captive portal. + * <p> + * This data may be used, for example, to display a visual indicator + * in a network selection list. + * <p> + * Note that the this extra conveys the possible presence of a + * captive portal, not its state or the user's ability to open + * the portal. + * <p> + * If no value is associated with this key then it's unknown. + */ + public static final String EXTRA_HAS_CAPTIVE_PORTAL = "android.net.extra.HAS_CAPTIVE_PORTAL"; /** A {@link NetworkKey} uniquely identifying this network. */ public final NetworkKey networkKey; @@ -53,6 +68,14 @@ public class ScoredNetwork implements Parcelable { public final boolean meteredHint; /** + * An additional collection of optional attributes set by + * the Network Recommendation Provider. + * + * @see #EXTRA_HAS_CAPTIVE_PORTAL + */ + public final Bundle attributes; + + /** * Construct a new {@link ScoredNetwork}. * * @param networkKey the {@link NetworkKey} uniquely identifying this network. @@ -81,9 +104,29 @@ public class ScoredNetwork implements Parcelable { * metered. */ public ScoredNetwork(NetworkKey networkKey, RssiCurve rssiCurve, boolean meteredHint) { + this(networkKey, rssiCurve, false /* meteredHint */, null /* attributes */); + } + + /** + * Construct a new {@link ScoredNetwork}. + * + * @param networkKey the {@link NetworkKey} uniquely identifying this network + * @param rssiCurve the {@link RssiCurve} representing the scores for this network based on the + * RSSI. This field is optional, and may be skipped to represent a network which the scorer + * has opted not to score at this time. Passing a null value here is strongly preferred to + * not returning any {@link ScoredNetwork} for a given {@link NetworkKey} because it + * indicates to the system not to request scores for this network in the future, although + * the scorer may choose to issue an out-of-band update at any time. + * @param meteredHint a boolean value indicating whether or not the network is believed to be + * metered + * @param attributes optional provider specific attributes + */ + public ScoredNetwork(NetworkKey networkKey, RssiCurve rssiCurve, boolean meteredHint, + Bundle attributes) { this.networkKey = networkKey; this.rssiCurve = rssiCurve; this.meteredHint = meteredHint; + this.attributes = attributes; } private ScoredNetwork(Parcel in) { @@ -94,6 +137,7 @@ public class ScoredNetwork implements Parcelable { rssiCurve = null; } meteredHint = in.readByte() != 0; + attributes = in.readBundle(); } @Override @@ -111,6 +155,8 @@ public class ScoredNetwork implements Parcelable { out.writeByte((byte) 0); } out.writeByte((byte) (meteredHint ? 1 : 0)); + out.writeBundle(attributes); + } @Override @@ -121,19 +167,24 @@ public class ScoredNetwork implements Parcelable { ScoredNetwork that = (ScoredNetwork) o; return Objects.equals(networkKey, that.networkKey) - && Objects.equals(rssiCurve, that.rssiCurve) - && Objects.equals(meteredHint, that.meteredHint); + && Objects.equals(rssiCurve, that.rssiCurve) + && Objects.equals(meteredHint, that.meteredHint) + && Objects.equals(attributes, that.attributes); } @Override public int hashCode() { - return Objects.hash(networkKey, rssiCurve, meteredHint); + return Objects.hash(networkKey, rssiCurve, meteredHint, attributes); } @Override public String toString() { - return "ScoredNetwork[key=" + networkKey + ",score=" + rssiCurve - + ",meteredHint=" + meteredHint + "]"; + return "ScoredNetwork{" + + "networkKey=" + networkKey + + ", rssiCurve=" + rssiCurve + + ", meteredHint=" + meteredHint + + ", attributes=" + attributes + + '}'; } public static final Parcelable.Creator<ScoredNetwork> CREATOR = diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index 756cb301fefa..4e969bef864f 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -30,7 +30,10 @@ import android.net.INetworkScoreService; import android.net.NetworkScoreManager; import android.net.NetworkScorerAppManager; import android.net.NetworkScorerAppManager.NetworkScorerAppData; +import android.net.RecommendationRequest; +import android.net.RecommendationResult; import android.net.ScoredNetwork; +import android.net.wifi.WifiConfiguration; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; @@ -415,6 +418,16 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } @Override + public RecommendationResult requestRecommendation(RecommendationRequest request) { + // TODO(jjoslin): 11/25/16 - Update with real impl. + WifiConfiguration selectedConfig = null; + if (request != null) { + selectedConfig = request.getCurrentSelectedConfig(); + } + return new RecommendationResult(selectedConfig); + } + + @Override protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG); NetworkScorerAppData currentScorer = mNetworkScorerAppManager.getActiveScorer(); |