diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java index 037614e1127..0bd0615789d 100644 --- a/src/com/android/settings/datausage/AppDataUsage.java +++ b/src/com/android/settings/datausage/AppDataUsage.java @@ -54,7 +54,8 @@ import com.android.settingslib.net.UidDetailProvider; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; -public class AppDataUsage extends DataUsageBase implements Preference.OnPreferenceChangeListener { +public class AppDataUsage extends DataUsageBase implements Preference.OnPreferenceChangeListener, + DataSaverBackend.Listener { public static final String ARG_APP_ITEM = "app_item"; public static final String ARG_NETWORK_TEMPLATE = "network_template"; @@ -207,17 +208,23 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen @Override public void onResume() { super.onResume(); + mDataSaverBackend.addListener(this); mPolicy = services.mPolicyEditor.getPolicy(mTemplate); getLoaderManager().restartLoader(LOADER_CHART_DATA, ChartDataLoader.buildArgs(mTemplate, mAppItem), mChartDataCallbacks); updatePrefs(); } + @Override + public void onPause() { + super.onPause(); + mDataSaverBackend.remListener(this); + } + @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (preference == mRestrictBackground) { 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); @@ -238,15 +245,19 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen } private void updatePrefs() { + updatePrefs(getAppRestrictBackground(), getUnrestrictData()); + } + + private void updatePrefs(boolean restrictBackground, boolean unrestrictData) { if (mRestrictBackground != null) { - mRestrictBackground.setChecked(!getAppRestrictBackground()); + mRestrictBackground.setChecked(!restrictBackground); } if (mUnrestrictedData != null) { - if (getAppRestrictBackground()) { + if (restrictBackground) { mUnrestrictedData.setVisible(false); } else { mUnrestrictedData.setVisible(true); - mUnrestrictedData.setChecked(mDataSaverBackend.isWhitelisted(mAppItem.key)); + mUnrestrictedData.setChecked(unrestrictData); } } } @@ -288,6 +299,10 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; } + private boolean getUnrestrictData() { + return mDataSaverBackend.isWhitelisted(mAppItem.key); + } + @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -368,4 +383,23 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen } } } + + @Override + public void onDataSaverChanged(boolean isDataSaving) { + + } + + @Override + public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) { + if (mAppItem.uids.get(uid, false)) { + updatePrefs(getAppRestrictBackground(), isWhitelisted); + } + } + + @Override + public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) { + if (mAppItem.uids.get(uid, false)) { + updatePrefs(isBlacklisted, getUnrestrictData()); + } + } } diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java index 55521a8775f..eb62ad7cb51 100644 --- a/src/com/android/settings/datausage/DataSaverBackend.java +++ b/src/com/android/settings/datausage/DataSaverBackend.java @@ -160,10 +160,46 @@ public class DataSaverBackend { } } + private void handleWhitelistChanged(int uid, boolean isWhitelisted) { + for (int i = 0; i < mListeners.size(); i++) { + mListeners.get(i).onWhitelistStatusChanged(uid, isWhitelisted); + } + } + + private void handleBlacklistChanged(int uid, boolean isBlacklisted) { + for (int i = 0; i < mListeners.size(); i++) { + mListeners.get(i).onBlacklistStatusChanged(uid, isBlacklisted); + } + } + private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() { @Override - public void onUidRulesChanged(int uid, int uidRules) throws RemoteException { - // TODO: update UI accordingly + public void onUidRulesChanged(final int uid, int uidRules) throws RemoteException { + if (mBlacklist == null) { + loadBlacklist(); + } + final boolean isBlacklisted = uidRules == POLICY_REJECT_METERED_BACKGROUND; + mBlacklist.put(uid, isBlacklisted); + mHandler.post(new Runnable() { + @Override + public void run() { + handleBlacklistChanged(uid, isBlacklisted); + } + }); + } + + @Override + public void onRestrictBackgroundWhitelistChanged(final int uid, final boolean whitelisted) { + if (mWhitelist == null) { + loadWhitelist(); + } + mWhitelist.put(uid, whitelisted); + mHandler.post(new Runnable() { + @Override + public void run() { + handleWhitelistChanged(uid, whitelisted); + } + }); } @Override @@ -183,5 +219,7 @@ public class DataSaverBackend { public interface Listener { void onDataSaverChanged(boolean isDataSaving); + void onWhitelistStatusChanged(int uid, boolean isWhitelisted); + void onBlacklistStatusChanged(int uid, boolean isBlacklisted); } } diff --git a/src/com/android/settings/datausage/DataSaverPreference.java b/src/com/android/settings/datausage/DataSaverPreference.java index c286d9583eb..13ef9d7c4f5 100644 --- a/src/com/android/settings/datausage/DataSaverPreference.java +++ b/src/com/android/settings/datausage/DataSaverPreference.java @@ -44,4 +44,12 @@ public class DataSaverPreference extends Preference implements DataSaverBackend. public void onDataSaverChanged(boolean isDataSaving) { setSummary(isDataSaving ? R.string.data_saver_on : R.string.data_saver_off); } + + @Override + public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) { + } + + @Override + public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) { + } } diff --git a/src/com/android/settings/datausage/DataSaverSummary.java b/src/com/android/settings/datausage/DataSaverSummary.java index 591f2c5b529..8dfbad5b9ca 100644 --- a/src/com/android/settings/datausage/DataSaverSummary.java +++ b/src/com/android/settings/datausage/DataSaverSummary.java @@ -99,6 +99,14 @@ public class DataSaverSummary extends SettingsPreferenceFragment mSwitchBar.setChecked(isDataSaving); } + @Override + public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) { + } + + @Override + public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) { + } + @Override public void onExtraInfoUpdated() { if (!isAdded()) { diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java index 650b0b21999..740fe068b19 100644 --- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java +++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java @@ -41,7 +41,8 @@ import com.android.settingslib.applications.ApplicationsState.AppFilter; import java.util.ArrayList; public class UnrestrictedDataAccess extends SettingsPreferenceFragment - implements ApplicationsState.Callbacks, AppStateBaseBridge.Callback, Preference.OnPreferenceChangeListener { + implements ApplicationsState.Callbacks, AppStateBaseBridge.Callback, + Preference.OnPreferenceChangeListener { private static final int MENU_SHOW_SYSTEM = Menu.FIRST + 42; private static final String EXTRA_SHOW_SYSTEM = "show_system"; @@ -214,7 +215,7 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment return false; } - private class AccessPreference extends SwitchPreference { + private class AccessPreference extends SwitchPreference implements DataSaverBackend.Listener { private final AppEntry mEntry; private final DataUsageState mState; @@ -229,6 +230,18 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment } } + @Override + public void onAttached() { + super.onAttached(); + mDataSaverBackend.addListener(this); + } + + @Override + public void onDetached() { + mDataSaverBackend.remListener(this); + super.onDetached(); + } + @Override protected void onClick() { if (mState.isDataSaverBlacklisted) { @@ -246,17 +259,13 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment // 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); + } else { + setSummary(""); } - // TODO: might need to reset summary once it listens to onUidRulesChanged() } } @@ -280,9 +289,30 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment }); } holder.findViewById(android.R.id.widget_frame) - .setVisibility(mState.isDataSaverBlacklisted ? View.INVISIBLE : View.VISIBLE); + .setVisibility(mState != null && mState.isDataSaverBlacklisted + ? View.INVISIBLE : View.VISIBLE); super.onBindViewHolder(holder); } + + @Override + public void onDataSaverChanged(boolean isDataSaving) { + } + + @Override + public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) { + if (mState != null && mEntry.info.uid == uid) { + mState.isDataSaverWhitelisted = isWhitelisted; + reuse(); + } + } + + @Override + public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) { + if (mState != null && mEntry.info.uid == uid) { + mState.isDataSaverBlacklisted = isBlacklisted; + reuse(); + } + } } }