diff options
author | Jeff Sharkey <jsharkey@android.com> | 2011-08-18 15:01:10 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-08-18 15:01:10 -0700 |
commit | 9a20fa54c9ba4bd19f2afd6e8cc6e9954e7cb739 (patch) | |
tree | 8191feeabfa1cb16f2e1567e2d9b4652bb439e8e /services | |
parent | 1797d6086f9acbea582cac6d484e749abafa1868 (diff) | |
parent | 3a844fcf5a0e70a19c38dc500306b9ebe4e1413b (diff) | |
download | frameworks_base-9a20fa54c9ba4bd19f2afd6e8cc6e9954e7cb739.zip frameworks_base-9a20fa54c9ba4bd19f2afd6e8cc6e9954e7cb739.tar.gz frameworks_base-9a20fa54c9ba4bd19f2afd6e8cc6e9954e7cb739.tar.bz2 |
Merge "Background data notification, API clean up."
Diffstat (limited to 'services')
-rw-r--r-- | services/java/com/android/server/ConnectivityService.java | 47 | ||||
-rw-r--r-- | services/java/com/android/server/net/NetworkPolicyManagerService.java | 127 |
2 files changed, 99 insertions, 75 deletions
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 22ce484..1341dd4 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -163,8 +163,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { private boolean mTestMode; private static ConnectivityService sServiceInstance; - private AtomicBoolean mBackgroundDataEnabled = new AtomicBoolean(true); - private INetworkManagementService mNetd; private INetworkPolicyManager mPolicyManager; @@ -213,13 +211,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { MAX_NETWORK_STATE_TRACKER_EVENT + 5; /** - * used internally to set the background data preference - * arg1 = TRUE for enabled, FALSE for disabled - */ - private static final int EVENT_SET_BACKGROUND_DATA = - MAX_NETWORK_STATE_TRACKER_EVENT + 6; - - /** * used internally to set enable/disable cellular data * arg1 = ENBALED or DISABLED */ @@ -317,9 +308,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { handlerThread.start(); mHandler = new MyHandler(handlerThread.getLooper()); - mBackgroundDataEnabled.set(Settings.Secure.getInt(context.getContentResolver(), - Settings.Secure.BACKGROUND_DATA, 1) == 1); - // setup our unique device name if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) { String id = Settings.Secure.getString(context.getContentResolver(), @@ -1209,35 +1197,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { } /** - * @see ConnectivityManager#getBackgroundDataSetting() - */ - public boolean getBackgroundDataSetting() { - return mBackgroundDataEnabled.get(); - } - - /** - * @see ConnectivityManager#setBackgroundDataSetting(boolean) - */ - public void setBackgroundDataSetting(boolean allowBackgroundDataUsage) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.CHANGE_BACKGROUND_DATA_SETTING, - "ConnectivityService"); - - mBackgroundDataEnabled.set(allowBackgroundDataUsage); - - mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_BACKGROUND_DATA, - (allowBackgroundDataUsage ? ENABLED : DISABLED), 0)); - } - - private void handleSetBackgroundData(boolean enabled) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.BACKGROUND_DATA, enabled ? 1 : 0); - Intent broadcast = new Intent( - ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); - mContext.sendBroadcast(broadcast); - } - - /** * @see ConnectivityManager#getMobileDataEnabled() */ public boolean getMobileDataEnabled() { @@ -2273,12 +2232,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { handleSetNetworkPreference(preference); break; } - case EVENT_SET_BACKGROUND_DATA: - { - boolean enabled = (msg.arg1 == ENABLED); - handleSetBackgroundData(enabled); - break; - } case EVENT_SET_MOBILE_DATA: { boolean enabled = (msg.arg1 == ENABLED); diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 9c3d166..14d9665 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -89,6 +89,7 @@ import android.os.IPowerManager; import android.os.Message; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.format.Formatter; import android.text.format.Time; @@ -168,6 +169,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final String ATTR_UID = "uid"; private static final String ATTR_POLICY = "policy"; + private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground"; + + // @VisibleForTesting + public static final String ACTION_ALLOW_BACKGROUND = + "com.android.server.action.ACTION_ALLOW_BACKGROUND"; + private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; private static final int MSG_RULES_CHANGED = 0x1; @@ -185,8 +192,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final Object mRulesLock = new Object(); - private boolean mScreenOn; - private boolean mRestrictBackground; + private volatile boolean mScreenOn; + private volatile boolean mRestrictBackground; /** Defined network policies. */ private HashMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = Maps.newHashMap(); @@ -265,6 +272,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (mRestrictBackground) { updateRulesForRestrictBackgroundLocked(); + updateNotificationsLocked(); } } @@ -309,6 +317,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mContext.registerReceiver( mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); + // listen for restrict background changes from notifications + final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); + mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler); + } private IProcessObserver mProcessObserver = new IProcessObserver.Stub() { @@ -402,6 +414,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { }; /** + * Receiver that watches for {@link Notification} control of + * {@link #mRestrictBackground}. + */ + private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + // on background handler thread, and verified MANAGE_NETWORK_POLICY + // permission above. + + setRestrictBackground(false); + } + }; + + /** * Observer that watches for {@link INetworkManagementService} alerts. */ private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() { @@ -494,6 +520,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { notifyUnderLimitLocked(policy.template); } } + + // ongoing notification when restricting background data + if (mRestrictBackground) { + enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND); + } else { + cancelNotification(TAG_ALLOW_BACKGROUND); + } } /** @@ -614,16 +647,52 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** + * Show ongoing notification to reflect that {@link #mRestrictBackground} + * has been enabled. + */ + private void enqueueRestrictedNotification(String tag) { + final Resources res = mContext.getResources(); + final Notification.Builder builder = new Notification.Builder(mContext); + + final CharSequence title = res.getText(R.string.data_usage_restricted_title); + final CharSequence body = res.getString(R.string.data_usage_restricted_body); + + builder.setOnlyAlertOnce(true); + builder.setOngoing(true); + builder.setSmallIcon(R.drawable.ic_menu_info_details); + builder.setTicker(title); + builder.setContentTitle(title); + builder.setContentText(body); + + final Intent intent = buildAllowBackgroundDataIntent(); + builder.setContentIntent( + PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + + // TODO: move to NotificationManager once we can mock it + try { + final String packageName = mContext.getPackageName(); + final int[] idReceived = new int[1]; + mNotifManager.enqueueNotificationWithTag(packageName, tag, + 0x0, builder.getNotification(), idReceived); + } catch (RemoteException e) { + Slog.w(TAG, "problem during enqueueNotification: " + e); + } + } + + /** * Cancel any notification for combined {@link NetworkPolicy} and specific * type, like {@link #TYPE_LIMIT}. */ private void cancelNotification(NetworkPolicy policy, int type) { - final String tag = buildNotificationTag(policy, type); + cancelNotification(buildNotificationTag(policy, type)); + } + private void cancelNotification(String tag) { // TODO: move to NotificationManager once we can mock it try { final String packageName = mContext.getPackageName(); - mNotifManager.cancelNotificationWithTag(packageName, tag, 0x0); + mNotifManager.cancelNotificationWithTag( + packageName, tag, 0x0); } catch (RemoteException e) { Slog.w(TAG, "problem during enqueueNotification: " + e); } @@ -731,15 +800,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; final boolean hasWarning = policy.warningBytes != WARNING_DISABLED; - if (hasLimit || hasWarning) { - final long quotaBytes; - if (hasLimit) { - // remaining "quota" is based on usage in current cycle - quotaBytes = Math.max(0, policy.limitBytes - total); - } else { - // to track warning alert later, use a high quota - quotaBytes = Long.MAX_VALUE; - } + if (hasLimit) { + // remaining "quota" is based on usage in current cycle + final long quotaBytes = Math.max(0, policy.limitBytes - total); if (ifaces.length > 1) { // TODO: switch to shared quota once NMS supports @@ -754,16 +817,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } - - if (hasWarning) { - final long alertBytes = Math.max(0, policy.warningBytes - total); - for (String iface : ifaces) { - removeInterfaceAlert(iface); - if (alertBytes > 0) { - setInterfaceAlert(iface, alertBytes); - } - } - } } // remove quota on any trailing interfaces @@ -839,11 +892,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mRestrictBackground = readBooleanAttribute( in, ATTR_RESTRICT_BACKGROUND); } else { - try { - mRestrictBackground = !mConnManager.getBackgroundDataSetting(); - } catch (RemoteException e) { - mRestrictBackground = false; - } + mRestrictBackground = false; } } else if (TAG_NETWORK_POLICY.equals(tag)) { @@ -879,6 +928,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } catch (FileNotFoundException e) { // missing policy is okay, probably first boot + upgradeLegacyBackgroundData(); } catch (IOException e) { Slog.e(TAG, "problem reading network stats", e); } catch (XmlPullParserException e) { @@ -888,6 +938,22 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } + /** + * Upgrade legacy background data flags, notifying listeners of one last + * change to always-true. + */ + private void upgradeLegacyBackgroundData() { + mRestrictBackground = Settings.Secure.getInt( + mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1; + + // kick off one last broadcast if restricted + if (mRestrictBackground) { + final Intent broadcast = new Intent( + ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); + mContext.sendBroadcast(broadcast); + } + } + private void writePolicyLocked() { if (LOGV) Slog.v(TAG, "writePolicyLocked()"); @@ -1057,6 +1123,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { synchronized (mRulesLock) { mRestrictBackground = restrictBackground; updateRulesForRestrictBackgroundLocked(); + updateNotificationsLocked(); writePolicyLocked(); } } @@ -1420,6 +1487,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return telephony.getSubscriberId(); } + private static Intent buildAllowBackgroundDataIntent() { + return new Intent(ACTION_ALLOW_BACKGROUND); + } + private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { final Intent intent = new Intent(); intent.setComponent(new ComponentName( |