Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.net;
     18 
     19 import android.net.NetworkIdentity;
     20 
     21 import java.io.DataInputStream;
     22 import java.io.DataOutputStream;
     23 import java.io.IOException;
     24 import java.util.HashSet;
     25 
     26 import static android.net.ConnectivityManager.TYPE_MOBILE;
     27 
     28 /**
     29  * Identity of a {@code iface}, defined by the set of {@link NetworkIdentity}
     30  * active on that interface.
     31  *
     32  * @hide
     33  */
     34 public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
     35         Comparable<NetworkIdentitySet> {
     36     private static final int VERSION_INIT = 1;
     37     private static final int VERSION_ADD_ROAMING = 2;
     38     private static final int VERSION_ADD_NETWORK_ID = 3;
     39     private static final int VERSION_ADD_METERED = 4;
     40 
     41     public NetworkIdentitySet() {
     42     }
     43 
     44     public NetworkIdentitySet(DataInputStream in) throws IOException {
     45         final int version = in.readInt();
     46         final int size = in.readInt();
     47         for (int i = 0; i < size; i++) {
     48             if (version <= VERSION_INIT) {
     49                 final int ignored = in.readInt();
     50             }
     51             final int type = in.readInt();
     52             final int subType = in.readInt();
     53             final String subscriberId = readOptionalString(in);
     54             final String networkId;
     55             if (version >= VERSION_ADD_NETWORK_ID) {
     56                 networkId = readOptionalString(in);
     57             } else {
     58                 networkId = null;
     59             }
     60             final boolean roaming;
     61             if (version >= VERSION_ADD_ROAMING) {
     62                 roaming = in.readBoolean();
     63             } else {
     64                 roaming = false;
     65             }
     66 
     67             final boolean metered;
     68             if (version >= VERSION_ADD_METERED) {
     69                 metered = in.readBoolean();
     70             } else {
     71                 // If this is the old data and the type is mobile, treat it as metered. (Note that
     72                 // if this is a mobile network, TYPE_MOBILE is the only possible type that could be
     73                 // used.)
     74                 metered = (type == TYPE_MOBILE);
     75             }
     76 
     77             add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered));
     78         }
     79     }
     80 
     81     public void writeToStream(DataOutputStream out) throws IOException {
     82         out.writeInt(VERSION_ADD_METERED);
     83         out.writeInt(size());
     84         for (NetworkIdentity ident : this) {
     85             out.writeInt(ident.getType());
     86             out.writeInt(ident.getSubType());
     87             writeOptionalString(out, ident.getSubscriberId());
     88             writeOptionalString(out, ident.getNetworkId());
     89             out.writeBoolean(ident.getRoaming());
     90             out.writeBoolean(ident.getMetered());
     91         }
     92     }
     93 
     94     /** @return whether any {@link NetworkIdentity} in this set is considered roaming. */
     95     public boolean isAnyMemberRoaming() {
     96         if (isEmpty()) {
     97             return false;
     98         }
     99         for (NetworkIdentity ident : this) {
    100             if (ident.getRoaming()) {
    101                 return true;
    102             }
    103         }
    104         return false;
    105     }
    106 
    107     private static void writeOptionalString(DataOutputStream out, String value) throws IOException {
    108         if (value != null) {
    109             out.writeByte(1);
    110             out.writeUTF(value);
    111         } else {
    112             out.writeByte(0);
    113         }
    114     }
    115 
    116     private static String readOptionalString(DataInputStream in) throws IOException {
    117         if (in.readByte() != 0) {
    118             return in.readUTF();
    119         } else {
    120             return null;
    121         }
    122     }
    123 
    124     @Override
    125     public int compareTo(NetworkIdentitySet another) {
    126         if (isEmpty()) return -1;
    127         if (another.isEmpty()) return 1;
    128 
    129         final NetworkIdentity ident = iterator().next();
    130         final NetworkIdentity anotherIdent = another.iterator().next();
    131         return ident.compareTo(anotherIdent);
    132     }
    133 }
    134