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