diff options
10 files changed, 240 insertions, 1 deletions
diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml new file mode 100644 index 000000000000..426238c05f4b --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_data_saver.xml @@ -0,0 +1,28 @@ +<!-- + 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData=" + M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z + m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z + m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z + m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml new file mode 100644 index 000000000000..0713548fcd4d --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_data_saver_off.xml @@ -0,0 +1,28 @@ +<!-- + 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#4DFFFFFF" + android:pathData=" + M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z + m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z + m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z + m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/> +</vector> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 814e7eae0474..faf36eca176f 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1333,4 +1333,13 @@ <!-- Explanation of the status bar section of the tuner [CHAR LIMIT=NONE] --> <string name="tuner_status_bar_explanation">Enable or disable icons from being shown in the status bar.</string> + <!-- Label for quick settings tile for data saver [CHAR LIMIT=30] --> + <string name="data_saver">Data Saver</string> + + <!-- Accessibility description for data saver being on [CHAR LIMIT=NONE] --> + <string name="accessibility_data_saver_on">Data Saver is on</string> + + <!-- Accessibility description for data saver being off [CHAR LIMIT=NONE] --> + <string name="accessibility_data_saver_off">Data Saver is off</string> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index 6e22dde542d0..543a2f32b090 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -73,7 +73,7 @@ public class TileAdapter extends BaseAdapter { mCurrentTiles = tileSpecs; final TileGroup group = new TileGroup("com.android.settings", mContext); String possible = mContext.getString(R.string.quick_settings_tiles_default) - + ",user,hotspot,inversion"; + + ",user,hotspot,inversion,saver"; String[] possibleTiles = possible.split(","); for (int i = 0; i < possibleTiles.length; i++) { final String spec = possibleTiles[i]; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java new file mode 100644 index 000000000000..1aeb0fe6c9dd --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -0,0 +1,73 @@ +/* + * 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.systemui.qs.tiles; + +import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.systemui.R; +import com.android.systemui.qs.QSTile; +import com.android.systemui.statusbar.policy.DataSaverController; + +public class DataSaverTile extends QSTile<QSTile.BooleanState> implements + DataSaverController.Listener{ + + private final DataSaverController mDataSaverController; + + public DataSaverTile(Host host) { + super(host); + mDataSaverController = host.getNetworkController().getDataSaverController(); + } + + @Override + protected BooleanState newTileState() { + return new BooleanState(); + } + + @Override + public void setListening(boolean listening) { + if (listening) { + mDataSaverController.addListener(this); + } else { + mDataSaverController.remListener(this); + } + } + + @Override + protected void handleClick() { + mState.value = !mDataSaverController.isDataSaverEnabled(); + mDataSaverController.setDataSaverEnabled(mState.value); + refreshState(mState.value); + } + + @Override + protected void handleUpdateState(BooleanState state, Object arg) { + state.value = arg instanceof Boolean ? (Boolean) arg + : mDataSaverController.isDataSaverEnabled(); + state.label = mContext.getString(R.string.data_saver); + state.contentDescription = mContext.getString(state.value ? + R.string.accessibility_data_saver_on : R.string.accessibility_data_saver_off); + state.icon = ResourceIcon.get(state.value ? R.drawable.ic_data_saver + : R.drawable.ic_data_saver_off); + } + + @Override + public int getMetricsCategory() { + return MetricsEvent.QS_DATA_SAVER; + } + + @Override + public void onDataSaverChanged(boolean isDataSaving) { + refreshState(isDataSaving); + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java index 7e278560ba55..9c2159be1b98 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java @@ -38,6 +38,7 @@ import com.android.systemui.qs.tiles.BluetoothTile; import com.android.systemui.qs.tiles.CastTile; import com.android.systemui.qs.tiles.CellularTile; import com.android.systemui.qs.tiles.ColorInversionTile; +import com.android.systemui.qs.tiles.DataSaverTile; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.FlashlightTile; import com.android.systemui.qs.tiles.HotspotTile; @@ -346,6 +347,7 @@ public final class QSTileHost implements QSTile.Host, Tunable { else if (tileSpec.equals("hotspot")) return new HotspotTile(this); else if (tileSpec.equals("user")) return new UserTile(this); else if (tileSpec.equals("battery")) return new BatteryTile(this); + else if (tileSpec.equals("saver")) return new DataSaverTile(this); else if (tileSpec.equals(ColorMatrixTile.COLOR_MATRIX_SPEC)) return new ColorMatrixTile(this); // Intent tiles. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java new file mode 100644 index 000000000000..186e8b51d58c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java @@ -0,0 +1,89 @@ +/* + * 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.systemui.statusbar.policy; + +import android.content.Context; +import android.net.INetworkPolicyListener; +import android.net.NetworkPolicyManager; +import android.os.Handler; +import android.os.RemoteException; + +import java.util.ArrayList; + +public class DataSaverController { + + private final Handler mHandler = new Handler(); + private final ArrayList<Listener> mListeners = new ArrayList<>(); + private final NetworkPolicyManager mPolicyManager; + + public DataSaverController(Context context) { + mPolicyManager = NetworkPolicyManager.from(context); + } + + private void handleRestrictBackgroundChanged(boolean isDataSaving) { + final int N = mListeners.size(); + for (int i = 0; i < N; i++) { + mListeners.get(i).onDataSaverChanged(isDataSaving); + } + } + + 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); + } + + private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() { + @Override + public void onUidRulesChanged(int i, int i1) throws RemoteException { + } + + @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); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index b2bcde3db937..755a5b3f511d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -33,6 +33,7 @@ public interface NetworkController { void onUserSwitched(int newUserId); AccessPointController getAccessPointController(); DataUsageController getMobileDataController(); + DataSaverController getDataSaverController(); public interface SignalCallback { void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 3385c820a64f..dbb0295e7029 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -78,6 +78,7 @@ public class NetworkControllerImpl extends BroadcastReceiver private final SubscriptionManager mSubscriptionManager; private final boolean mHasMobileDataFeature; private final SubscriptionDefaults mSubDefaults; + private final DataSaverController mDataSaverController; private Config mConfig; // Subcontrollers. @@ -156,6 +157,7 @@ public class NetworkControllerImpl extends BroadcastReceiver mConfig = config; mReceiverHandler = new Handler(bgLooper); mCallbackHandler = callbackHandler; + mDataSaverController = new DataSaverController(context); mSubscriptionManager = subManager; mSubDefaults = defaultsHandler; @@ -189,6 +191,10 @@ public class NetworkControllerImpl extends BroadcastReceiver updateAirplaneMode(true /* force callback */); } + public DataSaverController getDataSaverController() { + return mDataSaverController; + } + private void registerListeners() { for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { mobileSignalController.registerListener(); diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 88e55ddb4fda..697777c718a3 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -339,5 +339,8 @@ message MetricsEvent { // Logged when the user calls an emergency contact. ACTION_CALL_EMERGENCY_CONTACT = 283; + + // QS Tile for Data Saver. + QS_DATA_SAVER = 284; } } |