summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2011-08-18 15:01:10 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-08-18 15:01:10 -0700
commit9a20fa54c9ba4bd19f2afd6e8cc6e9954e7cb739 (patch)
tree8191feeabfa1cb16f2e1567e2d9b4652bb439e8e /services
parent1797d6086f9acbea582cac6d484e749abafa1868 (diff)
parent3a844fcf5a0e70a19c38dc500306b9ebe4e1413b (diff)
downloadframeworks_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.java47
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java127
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(