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