am 6d7af4b7: Merge "DO NOT MERGE Allow a custom component to handle network policy notifications" into cw-e-dev
* commit '6d7af4b795501edfc4558163b8566a8694830a02': DO NOT MERGE Allow a custom component to handle network policy notifications
This commit is contained in:
@@ -48,6 +48,9 @@ interface INetworkPolicyManager {
|
||||
/** Snooze limit on policy matching given template. */
|
||||
void snoozeLimit(in NetworkTemplate template);
|
||||
|
||||
/** Snooze warning on policy matching given template. */
|
||||
void snoozeWarning(in NetworkTemplate template);
|
||||
|
||||
/** Control if background data is restricted system-wide. */
|
||||
void setRestrictBackground(boolean restrictBackground);
|
||||
boolean getRestrictBackground();
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.GET_SIGNATURES;
|
||||
import static android.net.NetworkPolicy.CYCLE_NONE;
|
||||
import static android.text.format.Time.MONTH_DAY;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -80,6 +81,54 @@ public class NetworkPolicyManager {
|
||||
*/
|
||||
public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE";
|
||||
|
||||
/**
|
||||
* Broadcast intent action for informing a custom component about a network policy
|
||||
* notification.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String ACTION_SHOW_NETWORK_POLICY_NOTIFICATION =
|
||||
"android.net.action.SHOW_NETWORK_POLICY_NOTIFICATION";
|
||||
|
||||
/**
|
||||
* The sequence number associated with the notification - a higher number
|
||||
* indicates previous notifications may be disregarded.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String EXTRA_NOTIFICATION_SEQUENCE_NUMBER =
|
||||
"android.net.extra.NOTIFICATION_SEQUENCE_NUMBER";
|
||||
|
||||
/**
|
||||
* The type of notification that should be presented to the user.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String EXTRA_NOTIFICATION_TYPE = "android.net.extra.NOTIFICATION_TYPE";
|
||||
|
||||
@SystemApi
|
||||
public static final int NOTIFICATION_TYPE_NONE = 0;
|
||||
@SystemApi
|
||||
public static final int NOTIFICATION_TYPE_USAGE_WARNING = 1;
|
||||
@SystemApi
|
||||
public static final int NOTIFICATION_TYPE_USAGE_REACHED_LIMIT = 2;
|
||||
@SystemApi
|
||||
public static final int NOTIFICATION_TYPE_USAGE_EXCEEDED_LIMIT = 3;
|
||||
|
||||
/**
|
||||
* The number of bytes used on the network in the notification.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String EXTRA_BYTES_USED = "android.net.extra.BYTES_USED";
|
||||
|
||||
/**
|
||||
* The network policy for the network in the notification.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final String EXTRA_NETWORK_POLICY = "android.net.extra.NETWORK_POLICY";
|
||||
|
||||
private final Context mContext;
|
||||
private INetworkPolicyManager mService;
|
||||
|
||||
|
||||
@@ -320,6 +320,8 @@
|
||||
<protected-broadcast android:name="android.internal.policy.action.BURN_IN_PROTECTION" />
|
||||
<protected-broadcast android:name="android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" />
|
||||
<protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" />
|
||||
|
||||
<protected-broadcast android:name="android.net.action.SHOW_NETWORK_POLICY_NOTIFICATION" />
|
||||
<!-- ====================================================================== -->
|
||||
<!-- RUNTIME PERMISSIONS -->
|
||||
<!-- ====================================================================== -->
|
||||
|
||||
@@ -2275,4 +2275,8 @@
|
||||
<!-- The OEM specified sensor string type for the gesture to launch camera app, this value
|
||||
must match the value of config_cameraLaunchGestureSensorType in OEM's HAL -->
|
||||
<string translatable="false" name="config_cameraLaunchGestureSensorStringType"></string>
|
||||
|
||||
<!-- Name of the component to handle network policy notifications. If present,
|
||||
disables NetworkPolicyManagerService's presentation of data-usage notifications. -->
|
||||
<string translatable="false" name="config_networkPolicyNotificationComponent"></string>
|
||||
</resources>
|
||||
|
||||
@@ -2321,4 +2321,6 @@
|
||||
<!-- Gesture -->
|
||||
<java-symbol type="integer" name="config_cameraLaunchGestureSensorType" />
|
||||
<java-symbol type="string" name="config_cameraLaunchGestureSensorStringType" />
|
||||
|
||||
<java-symbol type="string" name="config_networkPolicyNotificationComponent" />
|
||||
</resources>
|
||||
|
||||
@@ -108,6 +108,7 @@ import android.net.LinkProperties;
|
||||
import android.net.NetworkIdentity;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.NetworkPolicy;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkQuotaInfo;
|
||||
import android.net.NetworkState;
|
||||
import android.net.NetworkTemplate;
|
||||
@@ -200,6 +201,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
private static final int VERSION_SWITCH_UID = 10;
|
||||
private static final int VERSION_LATEST = VERSION_SWITCH_UID;
|
||||
|
||||
@VisibleForTesting
|
||||
public static final int TYPE_NONE = 0;
|
||||
@VisibleForTesting
|
||||
public static final int TYPE_WARNING = 0x1;
|
||||
@VisibleForTesting
|
||||
@@ -260,6 +263,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
private PowerManagerInternal mPowerManagerInternal;
|
||||
private IDeviceIdleController mDeviceIdleController;
|
||||
|
||||
private final ComponentName mNotificationComponent;
|
||||
private int mNotificationSequenceNumber;
|
||||
|
||||
final Object mRulesLock = new Object();
|
||||
|
||||
volatile boolean mSystemReady;
|
||||
@@ -357,6 +363,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
|
||||
|
||||
mAppOps = context.getSystemService(AppOpsManager.class);
|
||||
|
||||
final String notificationComponent = context.getString(
|
||||
R.string.config_networkPolicyNotificationComponent);
|
||||
mNotificationComponent = notificationComponent != null
|
||||
? ComponentName.unflattenFromString(notificationComponent) : null;
|
||||
}
|
||||
|
||||
public void bindConnectivityManager(IConnectivityManager connManager) {
|
||||
@@ -778,6 +789,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs);
|
||||
mActiveNotifs.clear();
|
||||
|
||||
// increment the sequence number so custom components know
|
||||
// this update is new
|
||||
mNotificationSequenceNumber++;
|
||||
boolean hasNotifications = false;
|
||||
|
||||
// TODO: when switching to kernel notifications, compute next future
|
||||
// cycle boundary to recompute notifications.
|
||||
|
||||
@@ -794,6 +810,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
final long totalBytes = getTotalBytes(policy.template, start, end);
|
||||
|
||||
if (policy.isOverLimit(totalBytes)) {
|
||||
hasNotifications = true;
|
||||
if (policy.lastLimitSnooze >= start) {
|
||||
enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
|
||||
} else {
|
||||
@@ -806,10 +823,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
|
||||
if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) {
|
||||
enqueueNotification(policy, TYPE_WARNING, totalBytes);
|
||||
hasNotifications = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// right now we don't care about restricted background notifications
|
||||
// in the custom notification component, so trigger an update now
|
||||
// if we didn't update anything this pass
|
||||
if (!hasNotifications) {
|
||||
sendNotificationToCustomComponent(null, TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
// ongoing notification when restricting background data
|
||||
if (mRestrictBackground) {
|
||||
enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND);
|
||||
@@ -856,6 +881,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
* {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
|
||||
*/
|
||||
private void notifyOverLimitLocked(NetworkTemplate template) {
|
||||
if (mNotificationComponent != null) {
|
||||
// It is the job of the notification component to handle UI,
|
||||
// so we do nothing here
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mOverLimitNotified.contains(template)) {
|
||||
mContext.startActivity(buildNetworkOverLimitIntent(template));
|
||||
mOverLimitNotified.add(template);
|
||||
@@ -874,11 +905,55 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
return TAG + ":" + policy.template.hashCode() + ":" + type;
|
||||
}
|
||||
|
||||
private boolean sendNotificationToCustomComponent(
|
||||
NetworkPolicy policy,
|
||||
int type,
|
||||
long totalBytes) {
|
||||
if (mNotificationComponent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
intent.setComponent(mNotificationComponent);
|
||||
|
||||
int notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_NONE;
|
||||
switch (type) {
|
||||
case TYPE_WARNING:
|
||||
notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_WARNING;
|
||||
break;
|
||||
case TYPE_LIMIT:
|
||||
notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_REACHED_LIMIT;
|
||||
break;
|
||||
case TYPE_LIMIT_SNOOZED:
|
||||
notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_EXCEEDED_LIMIT;
|
||||
break;
|
||||
}
|
||||
|
||||
intent.setAction(NetworkPolicyManager.ACTION_SHOW_NETWORK_POLICY_NOTIFICATION);
|
||||
intent.putExtra(NetworkPolicyManager.EXTRA_NOTIFICATION_TYPE, notificationType);
|
||||
intent.putExtra(
|
||||
NetworkPolicyManager.EXTRA_NOTIFICATION_SEQUENCE_NUMBER,
|
||||
mNotificationSequenceNumber);
|
||||
|
||||
if (notificationType != NetworkPolicyManager.NOTIFICATION_TYPE_NONE) {
|
||||
intent.putExtra(NetworkPolicyManager.EXTRA_NETWORK_POLICY, policy);
|
||||
intent.putExtra(NetworkPolicyManager.EXTRA_BYTES_USED, totalBytes);
|
||||
}
|
||||
|
||||
mContext.sendBroadcast(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notification for combined {@link NetworkPolicy} and specific type,
|
||||
* like {@link #TYPE_LIMIT}. Okay to call multiple times.
|
||||
*/
|
||||
private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
|
||||
if (sendNotificationToCustomComponent(policy, type, totalBytes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String tag = buildNotificationTag(policy, type);
|
||||
final Notification.Builder builder = new Notification.Builder(mContext);
|
||||
builder.setOnlyAlertOnce(true);
|
||||
@@ -1738,6 +1813,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snoozeWarning(NetworkTemplate template) {
|
||||
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
|
||||
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
// TODO: this seems like a race condition? (along with snoozeLimit above)
|
||||
performSnooze(template, TYPE_WARNING);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
void performSnooze(NetworkTemplate template, int type) {
|
||||
maybeRefreshTrustedTime();
|
||||
final long currentTime = currentTimeMillis();
|
||||
|
||||
Reference in New Issue
Block a user