1/* 2 * Copyright (C) 2012 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 17package android.support.v4.net; 18 19import static android.net.ConnectivityManager.TYPE_BLUETOOTH; 20import static android.net.ConnectivityManager.TYPE_ETHERNET; 21import static android.net.ConnectivityManager.TYPE_MOBILE; 22import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; 23import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; 24import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; 25import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; 26import static android.net.ConnectivityManager.TYPE_WIFI; 27import static android.net.ConnectivityManager.TYPE_WIMAX; 28import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 29 30import android.content.Intent; 31import android.net.ConnectivityManager; 32import android.net.NetworkInfo; 33import android.os.Build; 34import android.support.annotation.IntDef; 35import android.support.annotation.RequiresPermission; 36import android.support.annotation.RestrictTo; 37 38import java.lang.annotation.Retention; 39import java.lang.annotation.RetentionPolicy; 40 41/** 42 * Helper for accessing features in {@link ConnectivityManager}. 43 */ 44public final class ConnectivityManagerCompat { 45 /** @hide */ 46 @RestrictTo(LIBRARY_GROUP) 47 @Retention(RetentionPolicy.SOURCE) 48 @IntDef(value = { 49 RESTRICT_BACKGROUND_STATUS_DISABLED, 50 RESTRICT_BACKGROUND_STATUS_WHITELISTED, 51 RESTRICT_BACKGROUND_STATUS_ENABLED, 52 }) 53 public @interface RestrictBackgroundStatus { 54 } 55 56 /** 57 * Device is not restricting metered network activity while application is running on 58 * background. 59 */ 60 public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; 61 62 /** 63 * Device is restricting metered network activity while application is running on background, 64 * but application is allowed to bypass it. 65 * <p> 66 * In this state, application should take action to mitigate metered network access. 67 * For example, a music streaming application should switch to a low-bandwidth bitrate. 68 */ 69 public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; 70 71 /** 72 * Device is restricting metered network activity while application is running on background. 73 * <p> 74 * In this state, application should not try to use the network while running on background, 75 * because it would be denied. 76 */ 77 public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; 78 79 /** 80 * Returns if the currently active data network is metered. A network is 81 * classified as metered when the user is sensitive to heavy data usage on 82 * that connection due to monetary costs, data limitations or 83 * battery/performance issues. You should check this before doing large 84 * data transfers, and warn the user or delay the operation until another 85 * network is available. 86 * <p>This method requires the caller to hold the permission 87 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}. 88 * 89 * @return {@code true} if large transfers should be avoided, otherwise 90 * {@code false}. 91 */ 92 @SuppressWarnings("deprecation") 93 @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) 94 public static boolean isActiveNetworkMetered(ConnectivityManager cm) { 95 if (Build.VERSION.SDK_INT >= 16) { 96 return cm.isActiveNetworkMetered(); 97 } else { 98 final NetworkInfo info = cm.getActiveNetworkInfo(); 99 if (info == null) { 100 // err on side of caution 101 return true; 102 } 103 104 final int type = info.getType(); 105 switch (type) { 106 case TYPE_MOBILE: 107 case TYPE_MOBILE_DUN: 108 case TYPE_MOBILE_HIPRI: 109 case TYPE_MOBILE_MMS: 110 case TYPE_MOBILE_SUPL: 111 case TYPE_WIMAX: 112 return true; 113 case TYPE_WIFI: 114 case TYPE_BLUETOOTH: 115 case TYPE_ETHERNET: 116 return false; 117 default: 118 // err on side of caution 119 return true; 120 } 121 } 122 } 123 124 /** 125 * Return the {@link NetworkInfo} that caused the given 126 * {@link ConnectivityManager#CONNECTIVITY_ACTION} broadcast. This obtains 127 * the current state from {@link ConnectivityManager} instead of using the 128 * potentially-stale value from 129 * {@link ConnectivityManager#EXTRA_NETWORK_INFO}. May be {@code null}. 130 */ 131 @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) 132 public static NetworkInfo getNetworkInfoFromBroadcast(ConnectivityManager cm, Intent intent) { 133 final NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 134 if (info != null) { 135 return cm.getNetworkInfo(info.getType()); 136 } else { 137 return null; 138 } 139 } 140 141 /** 142 * Determines if the calling application is subject to metered network restrictions while 143 * running on background. 144 * 145 * @return {@link #RESTRICT_BACKGROUND_STATUS_DISABLED}, 146 * {@link #RESTRICT_BACKGROUND_STATUS_ENABLED}, 147 * or {@link #RESTRICT_BACKGROUND_STATUS_WHITELISTED} 148 */ 149 @RestrictBackgroundStatus 150 public static int getRestrictBackgroundStatus(ConnectivityManager cm) { 151 if (Build.VERSION.SDK_INT >= 24) { 152 return cm.getRestrictBackgroundStatus(); 153 } else { 154 return RESTRICT_BACKGROUND_STATUS_ENABLED; 155 } 156 } 157 158 private ConnectivityManagerCompat() {} 159} 160