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:
Felipe Leme
2016-04-18 22:38:26 +00:00
committed by android-build-merger
7 changed files with 108 additions and 32 deletions

View File

@@ -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>

View File

@@ -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);
}
/*

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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);
}
}
}