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 android.net; 18 19 import static android.content.pm.PackageManager.GET_SIGNATURES; 20 import static android.net.NetworkPolicy.CYCLE_NONE; 21 import static android.text.format.Time.MONTH_DAY; 22 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.pm.PackageManager; 26 import android.content.pm.PackageManager.NameNotFoundException; 27 import android.content.pm.Signature; 28 import android.os.RemoteException; 29 import android.os.UserHandle; 30 import android.text.format.Time; 31 import android.util.DebugUtils; 32 33 import com.google.android.collect.Sets; 34 35 import java.util.HashSet; 36 37 /** 38 * Manager for creating and modifying network policy rules. 39 * 40 * {@hide} 41 */ 42 public class NetworkPolicyManager { 43 44 /* POLICY_* are masks and can be ORed */ 45 /** No specific network policy, use system default. */ 46 public static final int POLICY_NONE = 0x0; 47 /** Reject network usage on metered networks when application in background. */ 48 public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1; 49 /** Allow network use (metered or not) in the background in battery save mode. */ 50 public static final int POLICY_ALLOW_BACKGROUND_BATTERY_SAVE = 0x2; 51 52 /* 53 * Rules defining whether an uid has access to a network given its type (metered / non-metered). 54 * 55 * These rules are bits and can be used in bitmask operations; in particular: 56 * - rule & RULE_MASK_METERED: returns the metered-networks status. 57 * - rule & RULE_MASK_ALL: returns the all-networks status. 58 * 59 * The RULE_xxx_ALL rules applies to all networks (metered or non-metered), but on 60 * metered networks, the RULE_xxx_METERED rules should be checked first. For example, 61 * if the device is on Battery Saver Mode and Data Saver Mode simulatenously, and a uid 62 * is whitelisted for the former but not the latter, its status would be 63 * RULE_REJECT_METERED | RULE_ALLOW_ALL, meaning it could have access to non-metered 64 * networks but not to metered networks. 65 * 66 * See network-policy-restrictions.md for more info. 67 */ 68 /** No specific rule was set */ 69 public static final int RULE_NONE = 0; 70 /** Allow traffic on metered networks. */ 71 public static final int RULE_ALLOW_METERED = 1 << 0; 72 /** Temporarily allow traffic on metered networks because app is on foreground. */ 73 public static final int RULE_TEMPORARY_ALLOW_METERED = 1 << 1; 74 /** Reject traffic on metered networks. */ 75 public static final int RULE_REJECT_METERED = 1 << 2; 76 /** Network traffic should be allowed on all networks (metered or non-metered), although 77 * metered-network restrictions could still apply. */ 78 public static final int RULE_ALLOW_ALL = 1 << 5; 79 /** Reject traffic on all networks. */ 80 public static final int RULE_REJECT_ALL = 1 << 6; 81 /** Mask used to get the {@code RULE_xxx_METERED} rules */ 82 public static final int MASK_METERED_NETWORKS = 0b00001111; 83 /** Mask used to get the {@code RULE_xxx_ALL} rules */ 84 public static final int MASK_ALL_NETWORKS = 0b11110000; 85 86 public static final int FIREWALL_RULE_DEFAULT = 0; 87 public static final int FIREWALL_RULE_ALLOW = 1; 88 public static final int FIREWALL_RULE_DENY = 2; 89 90 public static final int FIREWALL_TYPE_WHITELIST = 0; 91 public static final int FIREWALL_TYPE_BLACKLIST = 1; 92 93 public static final int FIREWALL_CHAIN_NONE = 0; 94 public static final int FIREWALL_CHAIN_DOZABLE = 1; 95 public static final int FIREWALL_CHAIN_STANDBY = 2; 96 public static final int FIREWALL_CHAIN_POWERSAVE = 3; 97 98 public static final String FIREWALL_CHAIN_NAME_NONE = "none"; 99 public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable"; 100 public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby"; 101 public static final String FIREWALL_CHAIN_NAME_POWERSAVE = "powersave"; 102 103 private static final boolean ALLOW_PLATFORM_APP_POLICY = true; 104 105 /** 106 * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it 107 * applies to. 108 */ 109 public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE"; 110 111 private final Context mContext; 112 private INetworkPolicyManager mService; 113 NetworkPolicyManager(Context context, INetworkPolicyManager service)114 public NetworkPolicyManager(Context context, INetworkPolicyManager service) { 115 if (service == null) { 116 throw new IllegalArgumentException("missing INetworkPolicyManager"); 117 } 118 mContext = context; 119 mService = service; 120 } 121 from(Context context)122 public static NetworkPolicyManager from(Context context) { 123 return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE); 124 } 125 126 /** 127 * Set policy flags for specific UID. 128 * 129 * @param policy {@link #POLICY_NONE} or combination of flags like 130 * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}. 131 */ setUidPolicy(int uid, int policy)132 public void setUidPolicy(int uid, int policy) { 133 try { 134 mService.setUidPolicy(uid, policy); 135 } catch (RemoteException e) { 136 throw e.rethrowFromSystemServer(); 137 } 138 } 139 140 /** 141 * Add policy flags for specific UID. The given policy bits will be set for 142 * the uid. Policy flags may be either 143 * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}. 144 */ addUidPolicy(int uid, int policy)145 public void addUidPolicy(int uid, int policy) { 146 try { 147 mService.addUidPolicy(uid, policy); 148 } catch (RemoteException e) { 149 throw e.rethrowFromSystemServer(); 150 } 151 } 152 153 /** 154 * Clear/remove policy flags for specific UID. The given policy bits will be set for 155 * the uid. Policy flags may be either 156 * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}. 157 */ removeUidPolicy(int uid, int policy)158 public void removeUidPolicy(int uid, int policy) { 159 try { 160 mService.removeUidPolicy(uid, policy); 161 } catch (RemoteException e) { 162 throw e.rethrowFromSystemServer(); 163 } 164 } 165 getUidPolicy(int uid)166 public int getUidPolicy(int uid) { 167 try { 168 return mService.getUidPolicy(uid); 169 } catch (RemoteException e) { 170 throw e.rethrowFromSystemServer(); 171 } 172 } 173 getUidsWithPolicy(int policy)174 public int[] getUidsWithPolicy(int policy) { 175 try { 176 return mService.getUidsWithPolicy(policy); 177 } catch (RemoteException e) { 178 throw e.rethrowFromSystemServer(); 179 } 180 } 181 registerListener(INetworkPolicyListener listener)182 public void registerListener(INetworkPolicyListener listener) { 183 try { 184 mService.registerListener(listener); 185 } catch (RemoteException e) { 186 throw e.rethrowFromSystemServer(); 187 } 188 } 189 unregisterListener(INetworkPolicyListener listener)190 public void unregisterListener(INetworkPolicyListener listener) { 191 try { 192 mService.unregisterListener(listener); 193 } catch (RemoteException e) { 194 throw e.rethrowFromSystemServer(); 195 } 196 } 197 setNetworkPolicies(NetworkPolicy[] policies)198 public void setNetworkPolicies(NetworkPolicy[] policies) { 199 try { 200 mService.setNetworkPolicies(policies); 201 } catch (RemoteException e) { 202 throw e.rethrowFromSystemServer(); 203 } 204 } 205 getNetworkPolicies()206 public NetworkPolicy[] getNetworkPolicies() { 207 try { 208 return mService.getNetworkPolicies(mContext.getOpPackageName()); 209 } catch (RemoteException e) { 210 throw e.rethrowFromSystemServer(); 211 } 212 } 213 setRestrictBackground(boolean restrictBackground)214 public void setRestrictBackground(boolean restrictBackground) { 215 try { 216 mService.setRestrictBackground(restrictBackground); 217 } catch (RemoteException e) { 218 throw e.rethrowFromSystemServer(); 219 } 220 } 221 getRestrictBackground()222 public boolean getRestrictBackground() { 223 try { 224 return mService.getRestrictBackground(); 225 } catch (RemoteException e) { 226 throw e.rethrowFromSystemServer(); 227 } 228 } 229 230 /** 231 * Resets network policy settings back to factory defaults. 232 * 233 * @hide 234 */ factoryReset(String subscriber)235 public void factoryReset(String subscriber) { 236 try { 237 mService.factoryReset(subscriber); 238 } catch (RemoteException e) { 239 throw e.rethrowFromSystemServer(); 240 } 241 } 242 243 /** 244 * Compute the last cycle boundary for the given {@link NetworkPolicy}. For 245 * example, if cycle day is 20th, and today is June 15th, it will return May 246 * 20th. When cycle day doesn't exist in current month, it snaps to the 1st 247 * of following month. 248 * 249 * @hide 250 */ computeLastCycleBoundary(long currentTime, NetworkPolicy policy)251 public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) { 252 if (policy.cycleDay == CYCLE_NONE) { 253 throw new IllegalArgumentException("Unable to compute boundary without cycleDay"); 254 } 255 256 final Time now = new Time(policy.cycleTimezone); 257 now.set(currentTime); 258 259 // first, find cycle boundary for current month 260 final Time cycle = new Time(now); 261 cycle.hour = cycle.minute = cycle.second = 0; 262 snapToCycleDay(cycle, policy.cycleDay); 263 264 if (Time.compare(cycle, now) >= 0) { 265 // cycle boundary is beyond now, use last cycle boundary; start by 266 // pushing ourselves squarely into last month. 267 final Time lastMonth = new Time(now); 268 lastMonth.hour = lastMonth.minute = lastMonth.second = 0; 269 lastMonth.monthDay = 1; 270 lastMonth.month -= 1; 271 lastMonth.normalize(true); 272 273 cycle.set(lastMonth); 274 snapToCycleDay(cycle, policy.cycleDay); 275 } 276 277 return cycle.toMillis(true); 278 } 279 280 /** {@hide} */ computeNextCycleBoundary(long currentTime, NetworkPolicy policy)281 public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) { 282 if (policy.cycleDay == CYCLE_NONE) { 283 throw new IllegalArgumentException("Unable to compute boundary without cycleDay"); 284 } 285 286 final Time now = new Time(policy.cycleTimezone); 287 now.set(currentTime); 288 289 // first, find cycle boundary for current month 290 final Time cycle = new Time(now); 291 cycle.hour = cycle.minute = cycle.second = 0; 292 snapToCycleDay(cycle, policy.cycleDay); 293 294 if (Time.compare(cycle, now) <= 0) { 295 // cycle boundary is before now, use next cycle boundary; start by 296 // pushing ourselves squarely into next month. 297 final Time nextMonth = new Time(now); 298 nextMonth.hour = nextMonth.minute = nextMonth.second = 0; 299 nextMonth.monthDay = 1; 300 nextMonth.month += 1; 301 nextMonth.normalize(true); 302 303 cycle.set(nextMonth); 304 snapToCycleDay(cycle, policy.cycleDay); 305 } 306 307 return cycle.toMillis(true); 308 } 309 310 /** 311 * Snap to the cycle day for the current month given; when cycle day doesn't 312 * exist, it snaps to last second of current month. 313 * 314 * @hide 315 */ snapToCycleDay(Time time, int cycleDay)316 public static void snapToCycleDay(Time time, int cycleDay) { 317 if (cycleDay > time.getActualMaximum(MONTH_DAY)) { 318 // cycle day isn't valid this month; snap to last second of month 319 time.month += 1; 320 time.monthDay = 1; 321 time.second = -1; 322 } else { 323 time.monthDay = cycleDay; 324 } 325 time.normalize(true); 326 } 327 328 /** 329 * Check if given UID can have a {@link #setUidPolicy(int, int)} defined, 330 * usually to protect critical system services. 331 */ 332 @Deprecated isUidValidForPolicy(Context context, int uid)333 public static boolean isUidValidForPolicy(Context context, int uid) { 334 // first, quick-reject non-applications 335 if (!UserHandle.isApp(uid)) { 336 return false; 337 } 338 339 if (!ALLOW_PLATFORM_APP_POLICY) { 340 final PackageManager pm = context.getPackageManager(); 341 final HashSet<Signature> systemSignature; 342 try { 343 systemSignature = Sets.newHashSet( 344 pm.getPackageInfo("android", GET_SIGNATURES).signatures); 345 } catch (NameNotFoundException e) { 346 throw new RuntimeException("problem finding system signature", e); 347 } 348 349 try { 350 // reject apps signed with platform cert 351 for (String packageName : pm.getPackagesForUid(uid)) { 352 final HashSet<Signature> packageSignature = Sets.newHashSet( 353 pm.getPackageInfo(packageName, GET_SIGNATURES).signatures); 354 if (packageSignature.containsAll(systemSignature)) { 355 return false; 356 } 357 } 358 } catch (NameNotFoundException e) { 359 } 360 } 361 362 // nothing found above; we can apply policy to UID 363 return true; 364 } 365 366 /* 367 * @hide 368 */ uidRulesToString(int uidRules)369 public static String uidRulesToString(int uidRules) { 370 final StringBuilder string = new StringBuilder().append(uidRules).append(" ("); 371 if (uidRules == RULE_NONE) { 372 string.append("NONE"); 373 } else { 374 string.append(DebugUtils.flagsToString(NetworkPolicyManager.class, "RULE_", uidRules)); 375 } 376 string.append(")"); 377 return string.toString(); 378 } 379 } 380