Handle blacklisted apps on Data Saver whitelist.
am: c2ef27f
* commit 'c2ef27faf4afca6c4f6634b5de975a1bdadf0752':
Handle blacklisted apps on Data Saver whitelist.
Change-Id: Ia5027825b7292f15717a47ed82f242f252ac83d9
This commit is contained in:
@@ -7243,6 +7243,9 @@
|
||||
<!-- Button that leads to list of apps with unrestricted data access [CHAR LIMIT=60] -->
|
||||
<string name="unrestricted_data_saver">Unrestricted data access</string>
|
||||
|
||||
<!-- Description of message shown when app is blacklisted for background data access [CHAR LIMIT=NONE] -->
|
||||
<string name="restrict_background_blacklisted">Background data is turned off</string>
|
||||
|
||||
<!-- Summary for the Data Saver feature being on [CHAR LIMIT=NONE] -->
|
||||
<string name="data_saver_on">On</string>
|
||||
|
||||
|
@@ -73,6 +73,7 @@ import android.webkit.IWebViewUpdateService;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
@@ -81,6 +82,7 @@ import com.android.settings.AppHeader;
|
||||
import com.android.settings.DeviceAdminAdd;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.applications.PermissionsSummaryHelper.PermissionsResultCallback;
|
||||
import com.android.settings.datausage.AppDataUsage;
|
||||
@@ -741,14 +743,19 @@ public class InstalledAppDetails extends AppInfoBase
|
||||
}
|
||||
|
||||
private void startAppInfoFragment(Class<?> fragment, CharSequence title) {
|
||||
startAppInfoFragment(fragment, title, this, mAppEntry);
|
||||
}
|
||||
|
||||
public static void startAppInfoFragment(Class<?> fragment, CharSequence title,
|
||||
SettingsPreferenceFragment caller, AppEntry appEntry) {
|
||||
// start new fragment to display extended information
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_PACKAGE_NAME, mAppEntry.info.packageName);
|
||||
args.putInt(ARG_PACKAGE_UID, mAppEntry.info.uid);
|
||||
args.putString(ARG_PACKAGE_NAME, appEntry.info.packageName);
|
||||
args.putInt(ARG_PACKAGE_UID, appEntry.info.uid);
|
||||
args.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, true);
|
||||
|
||||
SettingsActivity sa = (SettingsActivity) getActivity();
|
||||
sa.startPreferencePanel(fragment.getName(), args, -1, title, this, SUB_INFO_FRAGMENT);
|
||||
SettingsActivity sa = (SettingsActivity) caller.getActivity();
|
||||
sa.startPreferencePanel(fragment.getName(), args, -1, title, caller, SUB_INFO_FRAGMENT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -216,7 +216,8 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference == mRestrictBackground) {
|
||||
setAppRestrictBackground(!(Boolean) newValue);
|
||||
mDataSaverBackend.setIsBlacklisted(mAppItem.key, mPackageName, !(Boolean) newValue);
|
||||
updatePrefs(); // TODO: should have been notified by NPMS instead
|
||||
return true;
|
||||
} else if (preference == mUnrestrictedData) {
|
||||
mDataSaverBackend.setIsWhitelisted(mAppItem.key, mPackageName, (Boolean) newValue);
|
||||
@@ -287,17 +288,6 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
||||
return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
|
||||
}
|
||||
|
||||
private void setAppRestrictBackground(boolean restrictBackground) {
|
||||
final int uid = mAppItem.key;
|
||||
services.mPolicyManager.setUidPolicy(
|
||||
uid, restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
|
||||
updatePrefs(); // TODO: should have been notified by NPMS instead
|
||||
if (restrictBackground) {
|
||||
MetricsLogger.action(getContext(),
|
||||
MetricsEvent.ACTION_DATA_SAVER_BLACKLIST, mPackageName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
@@ -37,20 +37,24 @@ public class AppStateDataUsageBridge extends AppStateBaseBridge {
|
||||
final int N = apps.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
AppEntry app = apps.get(i);
|
||||
app.extraInfo = new DataUsageState(mDataSaverBackend.isWhitelisted(app.info.uid));
|
||||
app.extraInfo = new DataUsageState(mDataSaverBackend.isWhitelisted(app.info.uid),
|
||||
mDataSaverBackend.isBlacklisted(app.info.uid));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
|
||||
app.extraInfo = new DataUsageState(mDataSaverBackend.isWhitelisted(uid));
|
||||
app.extraInfo = new DataUsageState(mDataSaverBackend.isWhitelisted(uid),
|
||||
mDataSaverBackend.isBlacklisted(uid));
|
||||
}
|
||||
|
||||
public static class DataUsageState {
|
||||
public boolean isDataSaverWhitelisted;
|
||||
public boolean isDataSaverBlacklisted;
|
||||
|
||||
public DataUsageState(boolean isDataSaverWhitelisted) {
|
||||
public DataUsageState(boolean isDataSaverWhitelisted, boolean isDataSaverBlacklisted) {
|
||||
this.isDataSaverWhitelisted = isDataSaverWhitelisted;
|
||||
this.isDataSaverBlacklisted = isDataSaverBlacklisted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -29,6 +29,9 @@ 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";
|
||||
@@ -40,6 +43,7 @@ public class DataSaverBackend {
|
||||
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) {
|
||||
@@ -121,6 +125,35 @@ public class DataSaverBackend {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -129,7 +162,8 @@ public class DataSaverBackend {
|
||||
|
||||
private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
|
||||
@Override
|
||||
public void onUidRulesChanged(int i, int i1) throws RemoteException {
|
||||
public void onUidRulesChanged(int uid, int uidRules) throws RemoteException {
|
||||
// TODO: update UI accordingly
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -70,6 +70,7 @@ public class DataSaverSummary extends SettingsPreferenceFragment
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mDataSaverBackend.refreshWhitelist();
|
||||
mDataSaverBackend.refreshBlacklist();
|
||||
mDataSaverBackend.addListener(this);
|
||||
mSession.resume();
|
||||
mDataUsageBridge.resume();
|
||||
|
@@ -24,10 +24,15 @@ import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.AppHeader;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.applications.AppStateBaseBridge;
|
||||
import com.android.settings.applications.InstalledAppDetails;
|
||||
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
@@ -40,6 +45,7 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
||||
|
||||
private static final int MENU_SHOW_SYSTEM = Menu.FIRST + 42;
|
||||
private static final String EXTRA_SHOW_SYSTEM = "show_system";
|
||||
|
||||
private ApplicationsState mApplicationsState;
|
||||
private AppStateDataUsageBridge mDataUsageBridge;
|
||||
private ApplicationsState.Session mSession;
|
||||
@@ -144,11 +150,11 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRebuildComplete(ArrayList<ApplicationsState.AppEntry> apps) {
|
||||
public void onRebuildComplete(ArrayList<AppEntry> apps) {
|
||||
cacheRemoveAllPrefs(getPreferenceScreen());
|
||||
final int N = apps.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
ApplicationsState.AppEntry entry = apps.get(i);
|
||||
AppEntry entry = apps.get(i);
|
||||
String key = entry.info.packageName + "|" + entry.info.uid;
|
||||
AccessPreference preference = (AccessPreference) getCachedPreference(key);
|
||||
if (preference == null) {
|
||||
@@ -202,32 +208,60 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
||||
boolean whitelisted = newValue == Boolean.TRUE;
|
||||
mDataSaverBackend.setIsWhitelisted(accessPreference.mEntry.info.uid,
|
||||
accessPreference.mEntry.info.packageName, whitelisted);
|
||||
((AppStateDataUsageBridge.DataUsageState) accessPreference.mEntry.extraInfo)
|
||||
.isDataSaverWhitelisted = whitelisted;
|
||||
accessPreference.mState.isDataSaverWhitelisted = whitelisted;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private class AccessPreference extends SwitchPreference {
|
||||
private final ApplicationsState.AppEntry mEntry;
|
||||
private final AppEntry mEntry;
|
||||
private final DataUsageState mState;
|
||||
|
||||
public AccessPreference(Context context, ApplicationsState.AppEntry entry) {
|
||||
public AccessPreference(final Context context, AppEntry entry) {
|
||||
super(context);
|
||||
mEntry = entry;
|
||||
mState = (DataUsageState) mEntry.extraInfo;
|
||||
mEntry.ensureLabel(getContext());
|
||||
setTitle(entry.label);
|
||||
final DataUsageState state = (DataUsageState) entry.extraInfo;
|
||||
setChecked(state != null && state.isDataSaverWhitelisted);
|
||||
setState();
|
||||
if (mEntry.icon != null) {
|
||||
setIcon(mEntry.icon);
|
||||
}
|
||||
setOnPreferenceClickListener( new OnPreferenceClickListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference pref) {
|
||||
if (mState.isDataSaverBlacklisted) {
|
||||
InstalledAppDetails.startAppInfoFragment(AppDataUsage.class,
|
||||
context.getString(R.string.app_data_usage),
|
||||
UnrestrictedDataAccess.this,
|
||||
mEntry);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
|
||||
// Sets UI state based on whitelist/blacklist status.
|
||||
private void setState() {
|
||||
setTitle(mEntry.label);
|
||||
// TODO: state is cached, so if blacklist/whitelist changes, it's not updated.
|
||||
// For example, if the initial state is blacklisted, the user taps the preference,
|
||||
// removes the blacklist, and then taps back, the state is not refreshed.
|
||||
// The proper fix for this problem is to implement onUidRulesChanged() on
|
||||
// DataSaverBackend and update the UI accordingly.
|
||||
if (mState != null) {
|
||||
setChecked(mState.isDataSaverWhitelisted);
|
||||
if (mState.isDataSaverBlacklisted) {
|
||||
setSummary(R.string.restrict_background_blacklisted);
|
||||
}
|
||||
// TODO: might need to reset summary once it listens to onUidRulesChanged()
|
||||
}
|
||||
}
|
||||
|
||||
public void reuse() {
|
||||
setTitle(mEntry.label);
|
||||
final DataUsageState state = (DataUsageState) mEntry.extraInfo;
|
||||
setChecked(state != null && state.isDataSaverWhitelisted);
|
||||
setState();
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -244,7 +278,10 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
||||
}
|
||||
});
|
||||
}
|
||||
holder.findViewById(android.R.id.widget_frame)
|
||||
.setVisibility(mState.isDataSaverBlacklisted ? View.INVISIBLE : View.VISIBLE);
|
||||
super.onBindViewHolder(holder);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user