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

Commit f61101f6 authored by Wink Saville's avatar Wink Saville
Browse files

Add LinkCapabilities

Change-Id: Ia1599ade936b79f12526252c0a2e6b453abb136e
parent a9771206
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
/*
**
** Copyright (C) 2009 Qualcomm Innovation Center, Inc.  All Rights Reserved.
** Copyright (C) 2009 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 LinkCapabilities;
+362 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 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.os.Parcelable;
import android.os.Parcel;
import android.util.Log;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * A class representing the capabilities of a link
 *
 * @hide
 */
public class LinkCapabilities implements Parcelable {
    private static final String TAG = "LinkCapabilities";
    private static final boolean DBG = false;

    /** The Map of Keys to Values */
    private HashMap<Integer, String> mCapabilities;


    /**
     * The set of keys defined for a links capabilities.
     *
     * Keys starting with RW are read + write, i.e. the application
     * can request for a certain requirement corresponding to that key.
     * Keys starting with RO are read only, i.e. the the application
     * can read the value of that key from the socket but cannot request
     * a corresponding requirement.
     *
     * TODO: Provide a documentation technique for concisely and precisely
     * define the syntax for each value string associated with a key.
     */
    public static final class Key {
        /** No constructor */
        private Key() {}

        /**
         * An integer representing the network type.
         * @see ConnectivityManager
         */
        public final static int RO_NETWORK_TYPE = 1;

        /**
         * Desired minimum forward link (download) bandwidth for the
         * in kilobits per second (kbps). Values should be strings such
         * "50", "100", "1500", etc.
         */
        public final static int RW_DESIRED_FWD_BW = 2;

        /**
         * Required minimum forward link (download) bandwidth, in
         * per second (kbps), below which the socket cannot function.
         * Values should be strings such as "50", "100", "1500", etc.
         */
        public final static int RW_REQUIRED_FWD_BW = 3;

        /**
         * Available forward link (download) bandwidth for the socket.
         * This value is in kilobits per second (kbps).
         * Values will be strings such as "50", "100", "1500", etc.
         */
        public final static int RO_AVAILABLE_FWD_BW = 4;

        /**
         * Desired minimum reverse link (upload) bandwidth for the socket
         * in kilobits per second (kbps).
         * Values should be strings such as "50", "100", "1500", etc.
         * <p>
         * This key is set via the needs map.
         */
        public final static int RW_DESIRED_REV_BW = 5;

        /**
         * Required minimum reverse link (upload) bandwidth, in kilobits
         * per second (kbps), below which the socket cannot function.
         * If a rate is not specified, the default rate of kbps will be
         * Values should be strings such as "50", "100", "1500", etc.
         */
        public final static int RW_REQUIRED_REV_BW = 6;

        /**
         * Available reverse link (upload) bandwidth for the socket.
         * This value is in kilobits per second (kbps).
         * Values will be strings such as "50", "100", "1500", etc.
         */
        public final static int RO_AVAILABLE_REV_BW = 7;

        /**
         * Maximum latency for the socket, in milliseconds, above which
         * socket cannot function.
         * Values should be strings such as "50", "300", "500", etc.
         */
        public final static int RW_MAX_ALLOWED_LATENCY = 8;

        /**
         * Interface that the socket is bound to. This can be a virtual
         * interface (e.g. VPN or Mobile IP) or a physical interface
         * (e.g. wlan0 or rmnet0).
         * Values will be strings such as "wlan0", "rmnet0"
         */
        public final static int RO_BOUND_INTERFACE = 9;

        /**
         * Physical interface that the socket is routed on.
         * This can be different from BOUND_INTERFACE in cases such as
         * VPN or Mobile IP. The physical interface may change over time
         * if seamless mobility is supported.
         * Values will be strings such as "wlan0", "rmnet0"
         */
        public final static int RO_PHYSICAL_INTERFACE = 10;
    }

    /**
     * Role informs the LinkSocket about the data usage patterns of your
     * application.
     * <P>
     * {@code Role.DEFAULT} is the default role, and is used whenever
     * a role isn't set.
     */
    public static final class Role {
        /** No constructor */
        private Role() {}

        // examples only, discuss which roles should be defined, and then
        // code these to match

        /** Default Role */
        public static final String DEFAULT = "0";
        /** Bulk down load */
        public static final String BULK_DOWNLOAD = "bulk.download";
        /** Bulk upload */
        public static final String BULK_UPLOAD = "bulk.upload";

        /** VoIP Application at 24kbps */
        public static final String VOIP_24KBPS = "voip.24k";
        /** VoIP Application at 32kbps */
        public static final String VOIP_32KBPS = "voip.32k";

        /** Video Streaming at 480p */
        public static final String VIDEO_STREAMING_480P = "video.streaming.480p";
        /** Video Streaming at 720p */
        public static final String VIDEO_STREAMING_720I = "video.streaming.720i";

        /** Video Chat Application at 360p */
        public static final String VIDEO_CHAT_360P = "video.chat.360p";
        /** Video Chat Application at 480p */
        public static final String VIDEO_CHAT_480P = "video.chat.480i";
    }

    /**
     * Constructor
     */
    public LinkCapabilities() {
        mCapabilities = new HashMap<Integer, String>();
    }

    /**
     * Copy constructor.
     *
     * @param source
     */
    public LinkCapabilities(LinkCapabilities source) {
        if (source != null) {
            mCapabilities = new HashMap<Integer, String>(source.mCapabilities);
        } else {
            mCapabilities = new HashMap<Integer, String>();
        }
    }

    /**
     * Create the {@code LinkCapabilities} with values depending on role type.
     * @param applicationRole a {@code LinkSocket.Role}
     * @return the {@code LinkCapabilities} associated with the applicationRole, empty if none
     */
    public static LinkCapabilities createNeedsMap(String applicationRole) {
        if (DBG) log("createNeededCapabilities(applicationRole) EX");
        return new LinkCapabilities();
    }

    /**
     * Remove all capabilities
     */
    public void clear() {
        mCapabilities.clear();
    }

    /**
     * Returns whether this map is empty.
     */
    public boolean isEmpty() {
        return mCapabilities.isEmpty();
    }

    /**
     * Returns the number of elements in this map.
     *
     * @return the number of elements in this map.
     */
    public int size() {
        return mCapabilities.size();
    }

    /**
     * Given the key return the capability string
     *
     * @param key
     * @return the capability string
     */
    public String get(int key) {
        return mCapabilities.get(key);
    }

    /**
     * Store the key/value capability pair
     *
     * @param key
     * @param value
     */
    public void put(int key, String value) {
        mCapabilities.put(key, value);
    }

    /**
     * Returns whether this map contains the specified key.
     *
     * @param key to search for.
     * @return {@code true} if this map contains the specified key,
     *         {@code false} otherwise.
     */
    public boolean containsKey(int key) {
        return mCapabilities.containsKey(key);
    }

    /**
     * Returns whether this map contains the specified value.
     *
     * @param value to search for.
     * @return {@code true} if this map contains the specified value,
     *         {@code false} otherwise.
     */
    public boolean containsValue(String value) {
        return mCapabilities.containsValue(value);
    }

    /**
     * Returns a set containing all of the mappings in this map. Each mapping is
     * an instance of {@link Map.Entry}. As the set is backed by this map,
     * changes in one will be reflected in the other.
     *
     * @return a set of the mappings.
     */
    public Set<Entry<Integer, String>> entrySet() {
        return mCapabilities.entrySet();
    }

    /**
     * @return the set of the keys.
     */
    public Set<Integer> keySet() {
        return mCapabilities.keySet();
    }

    /**
     * @return the set of values
     */
    public Collection<String> values() {
        return mCapabilities.values();
    }

    /**
     * Implement the Parcelable interface
     * @hide
     */
    public int describeContents() {
        return 0;
    }

    /**
     * Convert to string for debugging
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        boolean firstTime = true;
        for (Entry<Integer, String> entry : mCapabilities.entrySet()) {
            if (firstTime) {
                firstTime = false;
            } else {
                sb.append(",");
            }
            sb.append(entry.getKey());
            sb.append(":\"");
            sb.append(entry.getValue());
            sb.append("\"");
            return mCapabilities.toString();
        }
        return sb.toString();
    }

    /**
     * Implement the Parcelable interface.
     * @hide
     */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mCapabilities.size());
        for (Entry<Integer, String> entry : mCapabilities.entrySet()) {
            dest.writeInt(entry.getKey().intValue());
            dest.writeString(entry.getValue());
        }
    }

    /**
     * Implement the Parcelable interface.
     * @hide
     */
    public static final Creator<LinkCapabilities> CREATOR =
        new Creator<LinkCapabilities>() {
            public LinkCapabilities createFromParcel(Parcel in) {
                LinkCapabilities capabilities = new LinkCapabilities();
                int size = in.readInt();
                while (size-- != 0) {
                    int key = in.readInt();
                    String value = in.readString();
                    capabilities.mCapabilities.put(key, value);
                }
                return capabilities;
            }

            public LinkCapabilities[] newArray(int size) {
                return new LinkCapabilities[size];
            }
        };

    /**
     * Debug logging
     */
    protected static void log(String s) {
        Log.d(TAG, s);
    }
}
+19 −2
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ public class MobileDataStateTracker implements NetworkStateTracker {
    private Handler mTarget;
    private Context mContext;
    private LinkProperties mLinkProperties;
    private LinkCapabilities mLinkCapabilities;
    private boolean mPrivateDnsRouteSet = false;
    private int mDefaultGatewayAddr = 0;
    private boolean mDefaultRouteSet = false;
@@ -231,8 +232,14 @@ public class MobileDataStateTracker implements NetworkStateTracker {
                            mLinkProperties = intent.getParcelableExtra(
                                    Phone.DATA_LINK_PROPERTIES_KEY);
                            if (mLinkProperties == null) {
                                Log.d(TAG,
                                        "CONNECTED event did not supply link properties.");
                                Log.d(TAG, "CONNECTED event did not supply link properties.");
                                mLinkProperties = new LinkProperties();
                            }
                            mLinkCapabilities = intent.getParcelableExtra(
                                    Phone.DATA_LINK_CAPABILITIES_KEY);
                            if (mLinkCapabilities == null) {
                                Log.d(TAG, "CONNECTED event did not supply link capabilities.");
                                mLinkCapabilities = new LinkCapabilities();
                            }
                            setDetailedState(DetailedState.CONNECTED, reason, apnName);
                            break;
@@ -517,7 +524,17 @@ public class MobileDataStateTracker implements NetworkStateTracker {
        }
    }

    /**
     * @see android.net.NetworkStateTracker#getLinkProperties()
     */
    public LinkProperties getLinkProperties() {
        return new LinkProperties(mLinkProperties);
    }

    /**
     * @see android.net.NetworkStateTracker#getLinkCapabilities()
     */
    public LinkCapabilities getLinkCapabilities() {
        return new LinkCapabilities(mLinkCapabilities);
    }
}
+11 −1
Original line number Diff line number Diff line
@@ -103,10 +103,20 @@ public interface NetworkStateTracker {
    public NetworkInfo getNetworkInfo();

    /**
     * Fetch LinkProperties for the network
     * Return the LinkProperties for the connection.
     *
     * @return a copy of the LinkProperties, is never null.
     */
    public LinkProperties getLinkProperties();

    /**
     * A capability is an Integer/String pair, the capabilities
     * are defined in the class LinkSocket#Key.
     *
     * @return a copy of this connections capabilities, may be empty but never null.
     */
    public LinkCapabilities getLinkCapabilities();

    /**
     * Return the system properties name associated with the tcp buffer sizes
     * for this network.
+15 −7
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
import android.os.Binder;
import android.os.Bundle;
@@ -92,7 +93,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {

    private ArrayList<String> mConnectedApns;

    private LinkProperties mDataConnectionProperties;
    private LinkProperties mDataConnectionLinkProperties;

    private LinkCapabilities mDataConnectionLinkCapabilities;

    private Bundle mCellLocation = new Bundle();

@@ -356,7 +359,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {

    public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
            String reason, String apn, String apnType, LinkProperties linkProperties,
            int networkType) {
            LinkCapabilities linkCapabilities, int networkType) {
        if (!checkNotifyPermission("notifyDataConnection()" )) {
            return;
        }
@@ -382,8 +385,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
            }
            mDataConnectionPossible = isDataConnectivityPossible;
            mDataConnectionReason = reason;
            mDataConnectionApn = apn;
            mDataConnectionProperties = linkProperties;
            mDataConnectionLinkProperties = linkProperties;
            mDataConnectionLinkCapabilities = linkCapabilities;
            if (mDataConnectionNetworkType != networkType) {
                mDataConnectionNetworkType = networkType;
                modified = true;
@@ -403,7 +406,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
            }
        }
        broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
                apnType, linkProperties);
                apnType, linkProperties, linkCapabilities);
    }

    public void notifyDataConnectionFailed(String reason, String apnType) {
@@ -490,7 +493,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
            pw.println("  mDataConnectionPossible=" + mDataConnectionPossible);
            pw.println("  mDataConnectionReason=" + mDataConnectionReason);
            pw.println("  mDataConnectionApn=" + mDataConnectionApn);
            pw.println("  mDataConnectionProperties=" + mDataConnectionProperties);
            pw.println("  mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
            pw.println("  mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
            pw.println("  mCellLocation=" + mCellLocation);
            pw.println("registrations: count=" + recordCount);
            for (Record r : mRecords) {
@@ -564,7 +568,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {

    private void broadcastDataConnectionStateChanged(int state,
            boolean isDataConnectivityPossible,
            String reason, String apn, String apnType, LinkProperties linkProperties) {
            String reason, String apn, String apnType, LinkProperties linkProperties,
            LinkCapabilities linkCapabilities) {
        // Note: not reporting to the battery stats service here, because the
        // status bar takes care of that after taking into account all of the
        // required info.
@@ -584,6 +589,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
                intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface.getName());
            }
        }
        if (linkCapabilities != null) {
            intent.putExtra(Phone.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
        }
        intent.putExtra(Phone.DATA_APN_KEY, apn);
        intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
        mContext.sendStickyBroadcast(intent);
Loading