Merge "Background data notification, API clean up."
This commit is contained in:
@@ -11431,7 +11431,7 @@ package android.net {
|
||||
method public android.net.NetworkInfo getActiveNetworkInfo();
|
||||
method public android.net.NetworkQuotaInfo getActiveNetworkQuotaInfo();
|
||||
method public android.net.NetworkInfo[] getAllNetworkInfo();
|
||||
method public boolean getBackgroundDataSetting();
|
||||
method public deprecated boolean getBackgroundDataSetting();
|
||||
method public android.net.NetworkInfo getNetworkInfo(int);
|
||||
method public int getNetworkPreference();
|
||||
method public static boolean isNetworkTypeValid(int);
|
||||
@@ -17087,7 +17087,7 @@ package android.provider {
|
||||
field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
|
||||
field public static final java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
|
||||
field public static final java.lang.String ANDROID_ID = "android_id";
|
||||
field public static final java.lang.String BACKGROUND_DATA = "background_data";
|
||||
field public static final deprecated java.lang.String BACKGROUND_DATA = "background_data";
|
||||
field public static final java.lang.String BLUETOOTH_ON = "bluetooth_on";
|
||||
field public static final android.net.Uri CONTENT_URI;
|
||||
field public static final java.lang.String DATA_ROAMING = "data_roaming";
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.os.Binder;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import java.net.InetAddress;
|
||||
@@ -503,16 +504,19 @@ public class ConnectivityManager {
|
||||
* <p>
|
||||
* All applications that have background services that use the network
|
||||
* should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
|
||||
* <p>
|
||||
* As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
|
||||
* background data depends on several combined factors, and this method will
|
||||
* always return {@code true}. Instead, when background data is unavailable,
|
||||
* {@link #getActiveNetworkInfo()} will now appear disconnected.
|
||||
*
|
||||
* @return Whether background data usage is allowed.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean getBackgroundDataSetting() {
|
||||
try {
|
||||
return mService.getBackgroundDataSetting();
|
||||
} catch (RemoteException e) {
|
||||
// Err on the side of safety
|
||||
return false;
|
||||
}
|
||||
// assume that background data is allowed; final authority is
|
||||
// NetworkInfo which may be blocked.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -525,11 +529,9 @@ public class ConnectivityManager {
|
||||
* @see #getBackgroundDataSetting()
|
||||
* @hide
|
||||
*/
|
||||
@Deprecated
|
||||
public void setBackgroundDataSetting(boolean allowBackgroundData) {
|
||||
try {
|
||||
mService.setBackgroundDataSetting(allowBackgroundData);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
// ignored
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,10 +63,6 @@ interface IConnectivityManager
|
||||
|
||||
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
|
||||
|
||||
boolean getBackgroundDataSetting();
|
||||
|
||||
void setBackgroundDataSetting(boolean allowBackgroundData);
|
||||
|
||||
boolean getMobileDataEnabled();
|
||||
|
||||
void setMobileDataEnabled(boolean enabled);
|
||||
|
||||
@@ -3081,6 +3081,7 @@ public final class Settings {
|
||||
* Whether background data usage is allowed by the user. See
|
||||
* ConnectivityManager for more info.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String BACKGROUND_DATA = "background_data";
|
||||
|
||||
/**
|
||||
|
||||
@@ -3099,7 +3099,7 @@
|
||||
<!-- Notification title when mobile data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
|
||||
<string name="data_usage_mobile_limit_title">Mobile data disabled</string>
|
||||
<!-- Notification body when data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
|
||||
<string name="data_usage_limit_body">tap to enable</string>
|
||||
<string name="data_usage_limit_body">Touch to enable</string>
|
||||
|
||||
<!-- Notification title when 2G-3G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
|
||||
<string name="data_usage_3g_limit_snoozed_title">2G-3G data limit exceeded</string>
|
||||
@@ -3110,6 +3110,11 @@
|
||||
<!-- Notification body when data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
|
||||
<string name="data_usage_limit_snoozed_body"><xliff:g id="size" example="3.8GB">%s</xliff:g> over specified limit</string>
|
||||
|
||||
<!-- Notification title when background data usage is limited. [CHAR LIMIT=32] -->
|
||||
<string name="data_usage_restricted_title">Background data restricted</string>
|
||||
<!-- Notification body when background data usage is limited. [CHAR LIMIT=32] -->
|
||||
<string name="data_usage_restricted_body">Touch to remove restriction</string>
|
||||
|
||||
<!-- SSL Certificate dialogs -->
|
||||
<!-- Title for an SSL Certificate dialog -->
|
||||
<string name="ssl_certificate">Security certificate</string>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -212,13 +210,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
private static final int EVENT_INET_CONDITION_HOLD_END =
|
||||
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(),
|
||||
@@ -1208,35 +1196,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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()
|
||||
*/
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
@@ -401,6 +413,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.
|
||||
*/
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel any notification for combined {@link NetworkPolicy} and specific
|
||||
* type, like {@link #TYPE_LIMIT}.
|
||||
* Show ongoing notification to reflect that {@link #mRestrictBackground}
|
||||
* has been enabled.
|
||||
*/
|
||||
private void cancelNotification(NetworkPolicy policy, int type) {
|
||||
final String tag = buildNotificationTag(policy, type);
|
||||
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();
|
||||
mNotifManager.cancelNotificationWithTag(packageName, tag, 0x0);
|
||||
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) {
|
||||
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);
|
||||
} 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(
|
||||
|
||||
Reference in New Issue
Block a user