QS: Basic cellular data detail panel.
Change-Id: I1f19a8bf3e01d7f1d49e82d7096a215c863eab61
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
|
||||
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
|
||||
|
||||
<!-- Physical hardware -->
|
||||
<uses-permission android:name="android.permission.MANAGE_USB" />
|
||||
|
||||
82
packages/SystemUI/res/layout/data_usage.xml
Normal file
82
packages/SystemUI/res/layout/data_usage.xml
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2014 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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.QS.DataUsage" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/usage_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.QS.DataUsage.Usage" />
|
||||
|
||||
<com.android.systemui.qs.DataUsageGraph
|
||||
android:id="@+id/usage_graph"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:layout_marginBottom="@dimen/qs_panel_padding"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/usage_carrier_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="@style/TextAppearance.QS.DataUsage" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/usage_info_top_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="@style/TextAppearance.QS.DataUsage" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/usage_period_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="@style/TextAppearance.QS.DataUsage.Secondary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/usage_info_bottom_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="@style/TextAppearance.QS.DataUsage.Secondary" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -36,12 +36,14 @@
|
||||
<color name="qs_batterymeter_frame_color">#FF404040</color>
|
||||
<color name="system_primary_color">#ff263238</color>
|
||||
<color name="system_secondary_color">#ff384248</color>
|
||||
<color name="system_accent_color">#ff7fcac3</color>
|
||||
<color name="system_accent_color">#ff80CBC4</color><!-- deep teal 200 -->
|
||||
<color name="system_error_color">#fff0592b</color>
|
||||
<color name="qs_tile_divider">#29ffffff</color><!-- 16% white -->
|
||||
<color name="qs_tile_text">#B3FFFFFF</color><!-- 70% white -->
|
||||
<color name="qs_subhead">#66FFFFFF</color><!-- 40% white -->
|
||||
<color name="status_bar_clock_color">#FFFFFFFF</color>
|
||||
<color name="data_usage_secondary">#99FFFFFF</color><!-- 60% white -->
|
||||
<color name="data_usage_graph_track">#33FFFFFF</color><!-- 20% white -->
|
||||
<color name="status_bar_clock_color">#33FFFFFF</color>
|
||||
|
||||
<!-- Tint color for the content on the notification overflow card. -->
|
||||
<color name="keyguard_overflow_content_color">#ff686868</color>
|
||||
|
||||
@@ -546,6 +546,10 @@
|
||||
<string name="quick_settings_notifications_label">Notifications</string>
|
||||
<!-- QuickSettings: Flashlight [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_flashlight_label">Flashlight</string>
|
||||
<!-- QuickSettings: Cellular detail panel title [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_cellular_detail_title">Cellular data</string>
|
||||
<!-- QuickSettings: Cellular detail panel, data usage title [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_cellular_detail_data_usage">Data usage</string>
|
||||
|
||||
<!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
|
||||
<string name="recents_empty_message">No recent apps</string>
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
<style name="TextAppearance.QS.DetailItemSecondary">
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textColor">#7fcac3</item>
|
||||
<item name="android:textColor">@color/system_accent_color</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.QS.DetailButton">
|
||||
@@ -196,6 +196,19 @@
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.QS.DataUsage">
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.QS.DataUsage.Usage">
|
||||
<item name="android:textSize">36sp</item>
|
||||
<item name="android:textColor">@color/system_accent_color</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.QS.DataUsage.Secondary">
|
||||
<item name="android:textColor">@color/data_usage_secondary</item>
|
||||
</style>
|
||||
|
||||
<style name="BaseBrightnessDialogContainer">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
public class DataUsageGraph extends View {
|
||||
|
||||
private final int mBackgroundColor;
|
||||
private final int mUsageColor;
|
||||
private final RectF mTmpRect = new RectF();
|
||||
private final Paint mTmpPaint = new Paint();
|
||||
|
||||
private long mMaxLevel = 1;
|
||||
private long mLimitLevel;
|
||||
private long mWarningLevel;
|
||||
private long mUsageLevel;
|
||||
|
||||
public DataUsageGraph(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mBackgroundColor = context.getResources().getColor(R.color.data_usage_graph_track);
|
||||
mUsageColor = context.getResources().getColor(R.color.system_accent_color);
|
||||
}
|
||||
|
||||
public void setLevels(long maxLevel, long limitLevel, long warningLevel, long usageLevel) {
|
||||
mMaxLevel = Math.max(maxLevel, 1);
|
||||
mLimitLevel = limitLevel;
|
||||
mWarningLevel = warningLevel;
|
||||
mUsageLevel = usageLevel;
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
final RectF r = mTmpRect;
|
||||
final Paint p = mTmpPaint;
|
||||
final int w = getWidth();
|
||||
final int h = getHeight();
|
||||
|
||||
// draw background
|
||||
r.set(0, 0, w, h);
|
||||
p.setColor(mBackgroundColor);
|
||||
canvas.drawRect(r, p);
|
||||
|
||||
// draw usage
|
||||
r.set(0, 0, w * mUsageLevel / (float) mMaxLevel, h);
|
||||
p.setColor(mUsageColor);
|
||||
canvas.drawRect(r, p);
|
||||
}
|
||||
}
|
||||
@@ -20,24 +20,34 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.qs.DataUsageGraph;
|
||||
import com.android.systemui.qs.QSTile;
|
||||
import com.android.systemui.qs.QSTileView;
|
||||
import com.android.systemui.qs.SignalTileView;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.DataUsageInfo;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/** Quick settings tile: Cellular **/
|
||||
public class CellularTile extends QSTile<QSTile.SignalState> {
|
||||
private static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
|
||||
"com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
|
||||
|
||||
private final NetworkController mController;
|
||||
private final CellularDetailAdapter mDetailAdapter;
|
||||
|
||||
public CellularTile(Host host) {
|
||||
super(host);
|
||||
mController = host.getNetworkController();
|
||||
mDetailAdapter = new CellularDetailAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,6 +55,11 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
|
||||
return new SignalState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DetailAdapter getDetailAdapter() {
|
||||
return mDetailAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
if (listening) {
|
||||
@@ -61,7 +76,11 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
|
||||
|
||||
@Override
|
||||
protected void handleClick() {
|
||||
mHost.startSettingsActivity(CELLULAR_SETTINGS);
|
||||
if (mController.isMobileDataSupported()) {
|
||||
showDetail(true);
|
||||
} else {
|
||||
mHost.startSettingsActivity(CELLULAR_SETTINGS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,5 +176,81 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
|
||||
public void onAirplaneModeChanged(boolean enabled) {
|
||||
// noop
|
||||
}
|
||||
|
||||
public void onMobileDataEnabled(boolean enabled) {
|
||||
mDetailAdapter.setMobileDataEnabled(enabled);
|
||||
}
|
||||
};
|
||||
|
||||
private final class CellularDetailAdapter implements DetailAdapter {
|
||||
private static final double KB = 1024;
|
||||
private static final double MB = 1024 * KB;
|
||||
private static final double GB = 1024 * MB;
|
||||
|
||||
private final DecimalFormat FORMAT = new DecimalFormat("#.##");
|
||||
|
||||
@Override
|
||||
public int getTitle() {
|
||||
return R.string.quick_settings_cellular_detail_title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getToggleState() {
|
||||
return mController.isMobileDataSupported() ? mController.isMobileDataEnabled() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getSettingsIntent() {
|
||||
return CELLULAR_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setToggleState(boolean state) {
|
||||
mController.setMobileDataEnabled(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View createDetailView(Context context, View convertView, ViewGroup parent) {
|
||||
final View v = convertView != null ? convertView : LayoutInflater.from(mContext)
|
||||
.inflate(R.layout.data_usage, parent, false);
|
||||
final DataUsageInfo info = mController.getDataUsageInfo();
|
||||
if (info == null) return v;
|
||||
final TextView title = (TextView) v.findViewById(android.R.id.title);
|
||||
title.setText(R.string.quick_settings_cellular_detail_data_usage);
|
||||
final TextView usage = (TextView) v.findViewById(R.id.usage_text);
|
||||
usage.setText(formatBytes(info.usageLevel));
|
||||
final DataUsageGraph graph = (DataUsageGraph) v.findViewById(R.id.usage_graph);
|
||||
graph.setLevels(info.maxLevel, info.limitLevel, info.warningLevel, info.usageLevel);
|
||||
final TextView carrier = (TextView) v.findViewById(R.id.usage_carrier_text);
|
||||
carrier.setText(info.carrier);
|
||||
final TextView period = (TextView) v.findViewById(R.id.usage_period_text);
|
||||
period.setText(info.period);
|
||||
final TextView infoTop = (TextView) v.findViewById(R.id.usage_info_top_text);
|
||||
// TODO
|
||||
final TextView infoBottom = (TextView) v.findViewById(R.id.usage_info_bottom_text);
|
||||
// TODO
|
||||
return v;
|
||||
}
|
||||
|
||||
public void setMobileDataEnabled(boolean enabled) {
|
||||
fireToggleStateChanged(enabled);
|
||||
}
|
||||
|
||||
private String formatBytes(long bytes) {
|
||||
final long b = Math.abs(bytes);
|
||||
double val;
|
||||
String suffix;
|
||||
if (b > 100 * MB) {
|
||||
val = b / GB;
|
||||
suffix = "GB";
|
||||
} else if (b > 100 * KB) {
|
||||
val = b / MB;
|
||||
suffix = "MB";
|
||||
} else {
|
||||
val = b / KB;
|
||||
suffix = "KB";
|
||||
}
|
||||
return FORMAT.format(val * (bytes < 0 ? -1 : 1)) + " " + suffix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,6 +192,11 @@ public class WifiTile extends QSTile<QSTile.SignalState> {
|
||||
public void onAirplaneModeChanged(boolean enabled) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMobileDataEnabled(boolean enabled) {
|
||||
// noop
|
||||
}
|
||||
};
|
||||
|
||||
private final class WifiDetailAdapter implements DetailAdapter,
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||
import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
|
||||
import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
|
||||
import static android.telephony.TelephonyManager.SIM_STATE_READY;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.INetworkStatsSession;
|
||||
import android.net.NetworkStatsHistory;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.systemui.statusbar.policy.NetworkController.DataUsageInfo;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class MobileDataController {
|
||||
private static final String TAG = "MobileDataController";
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
private static final SimpleDateFormat MMM_D = new SimpleDateFormat("MMM d");
|
||||
private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES;
|
||||
|
||||
private final Context mContext;
|
||||
private final TelephonyManager mTelephonyManager;
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final INetworkStatsService mStatsService;
|
||||
|
||||
private INetworkStatsSession mSession;
|
||||
private Callback mCallback;
|
||||
|
||||
public MobileDataController(Context context) {
|
||||
mContext = context;
|
||||
mTelephonyManager = TelephonyManager.from(context);
|
||||
mConnectivityManager = ConnectivityManager.from(context);
|
||||
mStatsService = INetworkStatsService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
|
||||
try {
|
||||
mSession = mStatsService.openSession();
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to open stats session");
|
||||
mSession = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallback(Callback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
private DataUsageInfo warn(String msg) {
|
||||
Log.w(TAG, "Failed to get data usage, " + msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
public DataUsageInfo getDataUsageInfo() {
|
||||
final String subscriberId = getActiveSubscriberId(mContext);
|
||||
if (subscriberId == null) {
|
||||
return warn("no subscriber id");
|
||||
}
|
||||
if (mSession == null) {
|
||||
return warn("no stats session");
|
||||
}
|
||||
final NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId);
|
||||
try {
|
||||
final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELDS);
|
||||
final long now = System.currentTimeMillis();
|
||||
// period = last 4 wks for now
|
||||
final long start = now - DateUtils.WEEK_IN_MILLIS * 4;
|
||||
final long end = now;
|
||||
final long callStart = System.currentTimeMillis();
|
||||
final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
|
||||
final long callEnd = System.currentTimeMillis();
|
||||
if (DEBUG) Log.d(TAG, String.format("history call from %s to %s now=%s took %sms: %s",
|
||||
new Date(start), new Date(end), new Date(now), callEnd - callStart,
|
||||
historyEntryToString(entry)));
|
||||
if (entry == null) {
|
||||
return warn("no entry data");
|
||||
}
|
||||
final long totalBytes = entry.rxBytes + entry.txBytes;
|
||||
final DataUsageInfo usage = new DataUsageInfo();
|
||||
usage.maxLevel = (long) (totalBytes / .4);
|
||||
usage.usageLevel = totalBytes;
|
||||
usage.period = MMM_D.format(new Date(start)) + " - " + MMM_D.format(new Date(end));
|
||||
return usage;
|
||||
} catch (RemoteException e) {
|
||||
return warn("remote call failed");
|
||||
}
|
||||
}
|
||||
|
||||
private static String historyEntryToString(NetworkStatsHistory.Entry entry) {
|
||||
return entry == null ? null : new StringBuilder("Entry[")
|
||||
.append("bucketDuration=").append(entry.bucketDuration)
|
||||
.append(",bucketStart=").append(entry.bucketStart)
|
||||
.append(",activeTime=").append(entry.activeTime)
|
||||
.append(",rxBytes=").append(entry.rxBytes)
|
||||
.append(",rxPackets=").append(entry.rxPackets)
|
||||
.append(",txBytes=").append(entry.txBytes)
|
||||
.append(",txPackets=").append(entry.txPackets)
|
||||
.append(",operations=").append(entry.operations)
|
||||
.append(']').toString();
|
||||
}
|
||||
|
||||
public void setMobileDataEnabled(boolean enabled) {
|
||||
mTelephonyManager.setDataEnabled(enabled);
|
||||
if (mCallback != null) {
|
||||
mCallback.onMobileDataEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMobileDataSupported() {
|
||||
// require both supported network and ready SIM
|
||||
return mConnectivityManager.isNetworkSupported(TYPE_MOBILE)
|
||||
&& mTelephonyManager.getSimState() == SIM_STATE_READY;
|
||||
}
|
||||
|
||||
public boolean isMobileDataEnabled() {
|
||||
return mTelephonyManager.getDataEnabled();
|
||||
}
|
||||
|
||||
private static String getActiveSubscriberId(Context context) {
|
||||
final TelephonyManager tele = TelephonyManager.from(context);
|
||||
final String actualSubscriberId = tele.getSubscriberId();
|
||||
return actualSubscriberId;
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void onMobileDataEnabled(boolean enabled);
|
||||
}
|
||||
}
|
||||
@@ -32,12 +32,17 @@ public interface NetworkController {
|
||||
boolean activityIn, boolean activityOut,
|
||||
String dataTypeContentDescriptionId, String description, boolean noSim);
|
||||
void onAirplaneModeChanged(boolean enabled);
|
||||
void onMobileDataEnabled(boolean enabled);
|
||||
}
|
||||
|
||||
void addAccessPointCallback(AccessPointCallback callback);
|
||||
void removeAccessPointCallback(AccessPointCallback callback);
|
||||
void scanForAccessPoints();
|
||||
void connect(AccessPoint ap);
|
||||
boolean isMobileDataSupported();
|
||||
boolean isMobileDataEnabled();
|
||||
void setMobileDataEnabled(boolean enabled);
|
||||
DataUsageInfo getDataUsageInfo();
|
||||
|
||||
public interface AccessPointCallback {
|
||||
void onAccessPointsChanged(AccessPoint[] accessPoints);
|
||||
@@ -52,4 +57,13 @@ public interface NetworkController {
|
||||
public boolean isConnected;
|
||||
public int level; // 0 - 5
|
||||
}
|
||||
|
||||
public static class DataUsageInfo {
|
||||
public String carrier;
|
||||
public String period;
|
||||
public long maxLevel;
|
||||
public long limitLevel;
|
||||
public long warningLevel;
|
||||
public long usageLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
}
|
||||
|
||||
private final WifiAccessPointController mAccessPoints;
|
||||
private final MobileDataController mMobileDataController;
|
||||
|
||||
/**
|
||||
* Construct this controller object and register for updates.
|
||||
@@ -240,6 +241,19 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
|
||||
mLastLocale = mContext.getResources().getConfiguration().locale;
|
||||
mAccessPoints = new WifiAccessPointController(mContext);
|
||||
mMobileDataController = new MobileDataController(mContext);
|
||||
mMobileDataController.setCallback(new MobileDataController.Callback() {
|
||||
@Override
|
||||
public void onMobileDataEnabled(boolean enabled) {
|
||||
notifyMobileDataEnabled(enabled);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void notifyMobileDataEnabled(boolean enabled) {
|
||||
for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
|
||||
cb.onMobileDataEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMobileDataFeature() {
|
||||
@@ -322,6 +336,28 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataUsageInfo getDataUsageInfo() {
|
||||
final DataUsageInfo info = mMobileDataController.getDataUsageInfo();
|
||||
info.carrier = mNetworkName;
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMobileDataSupported() {
|
||||
return mMobileDataController.isMobileDataSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMobileDataEnabled() {
|
||||
return mMobileDataController.isMobileDataEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMobileDataEnabled(boolean enabled) {
|
||||
mMobileDataController.setMobileDataEnabled(enabled);
|
||||
}
|
||||
|
||||
public void refreshSignalCluster(SignalCluster cluster) {
|
||||
if (mDemoMode) return;
|
||||
cluster.setWifiIndicators(
|
||||
|
||||
Reference in New Issue
Block a user