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