All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.net.ScoredNetwork Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 15-robolectric-12650502
Show newest version
/*
 * Copyright (C) 2014 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.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Objects;
import java.util.Set;

/**
 * A network identifier along with a score for the quality of that network.
 *
 * @hide
 */
@SystemApi
public class ScoredNetwork implements Parcelable {

  /**
     * Key used with the {@link #attributes} bundle to define the badging curve.
     *
     * 

The badging curve is a {@link RssiCurve} used to map different RSSI values to {@link * NetworkBadging.Badging} enums. */ public static final String ATTRIBUTES_KEY_BADGING_CURVE = "android.net.attributes.key.BADGING_CURVE"; /** * Extra used with {@link #attributes} to specify whether the * network is believed to have a captive portal. *

* This data may be used, for example, to display a visual indicator * in a network selection list. *

* 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. *

* If no value is associated with this key then it's unknown. */ public static final String ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL = "android.net.attributes.key.HAS_CAPTIVE_PORTAL"; /** * Key used with the {@link #attributes} bundle to define the rankingScoreOffset int value. * *

The rankingScoreOffset is used when calculating the ranking score used to rank networks * against one another. See {@link #calculateRankingScore} for more information. */ public static final String ATTRIBUTES_KEY_RANKING_SCORE_OFFSET = "android.net.attributes.key.RANKING_SCORE_OFFSET"; /** A {@link NetworkKey} uniquely identifying this network. */ public final NetworkKey networkKey; /** * The {@link RssiCurve} representing the scores for this network based on the RSSI. * *

This field is optional and may be set to null to indicate that no score is available for * this network at this time. Such networks, along with networks for which the scorer has not * responded, are always prioritized below scored networks, regardless of the score. */ public final RssiCurve rssiCurve; /** * A boolean value that indicates whether or not the network is believed to be metered. * *

A network can be classified as metered if the user would be * sensitive to heavy data usage on that connection due to monetary costs, * data limitations or battery/performance issues. A typical example would * be a wifi connection where the user would be charged for usage. */ public final boolean meteredHint; /** * An additional collection of optional attributes set by * the Network Recommendation Provider. * * @see #ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL * @see #ATTRIBUTES_KEY_RANKING_SCORE_OFFSET */ @Nullable public final Bundle 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. */ public ScoredNetwork(NetworkKey networkKey, RssiCurve rssiCurve) { this(networkKey, rssiCurve, false /* meteredHint */); } /** * 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. */ public ScoredNetwork(NetworkKey networkKey, RssiCurve rssiCurve, boolean meteredHint) { this(networkKey, rssiCurve, 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, @Nullable Bundle attributes) { this.networkKey = networkKey; this.rssiCurve = rssiCurve; this.meteredHint = meteredHint; this.attributes = attributes; } private ScoredNetwork(Parcel in) { networkKey = NetworkKey.CREATOR.createFromParcel(in); if (in.readByte() == 1) { rssiCurve = RssiCurve.CREATOR.createFromParcel(in); } else { rssiCurve = null; } meteredHint = (in.readByte() == 1); attributes = in.readBundle(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out, int flags) { networkKey.writeToParcel(out, flags); if (rssiCurve != null) { out.writeByte((byte) 1); rssiCurve.writeToParcel(out, flags); } else { out.writeByte((byte) 0); } out.writeByte((byte) (meteredHint ? 1 : 0)); out.writeBundle(attributes); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ScoredNetwork that = (ScoredNetwork) o; return Objects.equals(networkKey, that.networkKey) && Objects.equals(rssiCurve, that.rssiCurve) && Objects.equals(meteredHint, that.meteredHint) && bundleEquals(attributes, that.attributes); } private boolean bundleEquals(Bundle bundle1, Bundle bundle2) { if (bundle1 == bundle2) { return true; } if (bundle1 == null || bundle2 == null) { return false; } if (bundle1.size() != bundle2.size()) { return false; } Set keys = bundle1.keySet(); for (String key : keys) { Object value1 = bundle1.get(key); Object value2 = bundle2.get(key); if (!Objects.equals(value1, value2)) { return false; } } return true; } @Override public int hashCode() { return Objects.hash(networkKey, rssiCurve, meteredHint, attributes); } @Override public String toString() { StringBuilder out = new StringBuilder( "ScoredNetwork{" + "networkKey=" + networkKey + ", rssiCurve=" + rssiCurve + ", meteredHint=" + meteredHint); // calling isEmpty will unparcel the bundle so its contents can be converted to a string if (attributes != null && !attributes.isEmpty()) { out.append(", attributes=" + attributes); } out.append('}'); return out.toString(); } /** * Returns true if a ranking score can be calculated for this network. * * @hide */ public boolean hasRankingScore() { return (rssiCurve != null) || (attributes != null && attributes.containsKey(ATTRIBUTES_KEY_RANKING_SCORE_OFFSET)); } /** * Returns a ranking score for a given RSSI which can be used to comparatively * rank networks. * *

The score obtained by the rssiCurve is bitshifted left by 8 bits to expand it to an * integer and then the offset is added. If the addition operation overflows or underflows, * Integer.MAX_VALUE and Integer.MIN_VALUE will be returned respectively. * *

{@link #hasRankingScore} should be called first to ensure this network is capable * of returning a ranking score. * * @throws UnsupportedOperationException if there is no RssiCurve and no rankingScoreOffset * for this network (hasRankingScore returns false). * * @hide */ public int calculateRankingScore(int rssi) throws UnsupportedOperationException { if (!hasRankingScore()) { throw new UnsupportedOperationException( "Either rssiCurve or rankingScoreOffset is required to calculate the " + "ranking score"); } int offset = 0; if (attributes != null) { offset += attributes.getInt(ATTRIBUTES_KEY_RANKING_SCORE_OFFSET, 0 /* default */); } int score = (rssiCurve == null) ? 0 : rssiCurve.lookupScore(rssi) << Byte.SIZE; try { return Math.addExact(score, offset); } catch (ArithmeticException e) { return (score < 0) ? Integer.MIN_VALUE : Integer.MAX_VALUE; } } /** * Return the {@link NetworkBadging.Badging} enum for this network for the given RSSI, derived from the * badging curve. * *

If no badging curve is present, {@link #BADGE_NONE} will be returned. * * @param rssi The rssi level for which the badge should be calculated */ @NetworkBadging.Badging public int calculateBadge(int rssi) { if (attributes != null && attributes.containsKey(ATTRIBUTES_KEY_BADGING_CURVE)) { RssiCurve badgingCurve = attributes.getParcelable(ATTRIBUTES_KEY_BADGING_CURVE); return badgingCurve.lookupScore(rssi); } return NetworkBadging.BADGING_NONE; } public static final @android.annotation.NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public ScoredNetwork createFromParcel(Parcel in) { return new ScoredNetwork(in); } @Override public ScoredNetwork[] newArray(int size) { return new ScoredNetwork[size]; } }; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy