When user blacklists an app for background data access, the "Unrestricted data access" list should not display the whitelist toggle option, but rather explain background access is turned off and offer the option to open the app's data usage screen to turn it back on. It still does not handle changed received by DataSaverBackend, so the UI will be stale when the user removes a blacklist and navigates back to the list. BUG: 27481520 Change-Id: I9d0fa9f0180a69ce9bd1417921bf89ec3ba31f01
188 lines
6.0 KiB
Java
188 lines
6.0 KiB
Java
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the
|
|
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*/
|
|
|
|
package com.android.settings.datausage;
|
|
|
|
import android.content.Context;
|
|
import android.net.INetworkPolicyListener;
|
|
import android.net.INetworkPolicyManager;
|
|
import android.net.NetworkPolicyManager;
|
|
import android.os.Handler;
|
|
import android.os.RemoteException;
|
|
import android.os.ServiceManager;
|
|
import android.util.Log;
|
|
import android.util.SparseBooleanArray;
|
|
|
|
import com.android.internal.logging.MetricsLogger;
|
|
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import static android.net.NetworkPolicyManager.POLICY_NONE;
|
|
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
|
|
|
public class DataSaverBackend {
|
|
|
|
private static final String TAG = "DataSaverBackend";
|
|
|
|
private final Context mContext;
|
|
|
|
private final Handler mHandler = new Handler();
|
|
private final NetworkPolicyManager mPolicyManager;
|
|
private final INetworkPolicyManager mIPolicyManager;
|
|
private final ArrayList<Listener> mListeners = new ArrayList<>();
|
|
private SparseBooleanArray mWhitelist;
|
|
private SparseBooleanArray mBlacklist;
|
|
|
|
// TODO: Staticize into only one.
|
|
public DataSaverBackend(Context context) {
|
|
mContext = context;
|
|
mIPolicyManager = INetworkPolicyManager.Stub.asInterface(
|
|
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
|
|
mPolicyManager = NetworkPolicyManager.from(context);
|
|
}
|
|
|
|
public void addListener(Listener listener) {
|
|
mListeners.add(listener);
|
|
if (mListeners.size() == 1) {
|
|
mPolicyManager.registerListener(mPolicyListener);
|
|
}
|
|
listener.onDataSaverChanged(isDataSaverEnabled());
|
|
}
|
|
|
|
public void remListener(Listener listener) {
|
|
mListeners.remove(listener);
|
|
if (mListeners.size() == 0) {
|
|
mPolicyManager.unregisterListener(mPolicyListener);
|
|
}
|
|
}
|
|
|
|
public boolean isDataSaverEnabled() {
|
|
return mPolicyManager.getRestrictBackground();
|
|
}
|
|
|
|
public void setDataSaverEnabled(boolean enabled) {
|
|
mPolicyManager.setRestrictBackground(enabled);
|
|
MetricsLogger.action(mContext, MetricsEvent.ACTION_DATA_SAVER_MODE, enabled ? 1 : 0);
|
|
}
|
|
|
|
public void refreshWhitelist() {
|
|
loadWhitelist();
|
|
}
|
|
|
|
public void setIsWhitelisted(int uid, String packageName, boolean whitelisted) {
|
|
mWhitelist.put(uid, whitelisted);
|
|
try {
|
|
if (whitelisted) {
|
|
mIPolicyManager.addRestrictBackgroundWhitelistedUid(uid);
|
|
} else {
|
|
mIPolicyManager.removeRestrictBackgroundWhitelistedUid(uid);
|
|
}
|
|
} catch (RemoteException e) {
|
|
Log.w(TAG, "Can't reach policy manager", e);
|
|
}
|
|
MetricsLogger.action(mContext, MetricsEvent.ACTION_DATA_SAVER_WHITELIST, packageName);
|
|
}
|
|
|
|
public boolean isWhitelisted(int uid) {
|
|
if (mWhitelist == null) {
|
|
loadWhitelist();
|
|
}
|
|
return mWhitelist.get(uid);
|
|
}
|
|
|
|
public int getWhitelistedCount() {
|
|
int count = 0;
|
|
if (mWhitelist == null) {
|
|
loadWhitelist();
|
|
}
|
|
for (int i = 0; i < mWhitelist.size(); i++) {
|
|
if (mWhitelist.valueAt(i)) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
private void loadWhitelist() {
|
|
mWhitelist = new SparseBooleanArray();
|
|
try {
|
|
for (int uid : mIPolicyManager.getRestrictBackgroundWhitelistedUids()) {
|
|
mWhitelist.put(uid, true);
|
|
}
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
public void refreshBlacklist() {
|
|
loadBlacklist();
|
|
}
|
|
|
|
public void setIsBlacklisted(int uid, String packageName, boolean blacklisted) {
|
|
mPolicyManager.setUidPolicy(
|
|
uid, blacklisted ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
|
|
if (blacklisted) {
|
|
MetricsLogger.action(mContext, MetricsEvent.ACTION_DATA_SAVER_BLACKLIST, packageName);
|
|
}
|
|
}
|
|
|
|
public boolean isBlacklisted(int uid) {
|
|
if (mBlacklist == null) {
|
|
loadBlacklist();
|
|
}
|
|
return mBlacklist.get(uid);
|
|
}
|
|
|
|
private void loadBlacklist() {
|
|
mBlacklist = new SparseBooleanArray();
|
|
try {
|
|
for (int uid : mIPolicyManager.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
|
|
mBlacklist.put(uid, true);
|
|
}
|
|
} catch (RemoteException e) {
|
|
}
|
|
}
|
|
|
|
private void handleRestrictBackgroundChanged(boolean isDataSaving) {
|
|
for (int i = 0; i < mListeners.size(); i++) {
|
|
mListeners.get(i).onDataSaverChanged(isDataSaving);
|
|
}
|
|
}
|
|
|
|
private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
|
|
@Override
|
|
public void onUidRulesChanged(int uid, int uidRules) throws RemoteException {
|
|
// TODO: update UI accordingly
|
|
}
|
|
|
|
@Override
|
|
public void onMeteredIfacesChanged(String[] strings) throws RemoteException {
|
|
}
|
|
|
|
@Override
|
|
public void onRestrictBackgroundChanged(final boolean isDataSaving) throws RemoteException {
|
|
mHandler.post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
handleRestrictBackgroundChanged(isDataSaving);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
public interface Listener {
|
|
void onDataSaverChanged(boolean isDataSaving);
|
|
}
|
|
}
|