Merge "Add a status bar icon for Ethernet." into mnc-dev

This commit is contained in:
Lorenzo Colitti
2015-05-04 01:01:47 +00:00
committed by Android (Google) Code Review
10 changed files with 279 additions and 3 deletions

View File

@@ -0,0 +1,30 @@
<!--
Copyright (C) 2015 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:autoMirrored="true"
android:width="18.77dp"
android:height="17dp"
android:viewportWidth="53.0"
android:viewportHeight="48.0">
<path
android:fillColor="?attr/singleToneColor"
android:pathData="M15.54 13.52l-3.08-2.55L1.64 24l10.82 13.04 3.08-2.55L6.84 24l8.7-10.48zM14 26h4v-4h-4v4zm20-4h-4v4h4v-4zm-12 4h4v-4h-4v4zm13.54-15.04l-3.08 2.55L41.16 24l-8.7 10.48 3.08 2.55L46.36 24 35.54 10.96z"/>
<path
android:fillColor="?attr/singleToneColor"
android:pathData="M49.000000,40.000000l4.000000,0.000000l0.000000,4.000000l-4.000000,0.000000z"/>
<path
android:fillColor="?attr/singleToneColor"
android:pathData="M49.000000,20.000000l4.000000,0.000000l0.000000,16.100000l-4.000000,0.000000z"/></vector>

View File

@@ -0,0 +1,24 @@
<!--
Copyright (C) 2015 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="18.77dp"
android:height="17dp"
android:viewportWidth="53.0"
android:viewportHeight="48.0">
<path
android:fillColor="?attr/singleToneColor"
android:pathData="M15.54 13.52l-3.08-2.55L1.64 24l10.82 13.04 3.08-2.55L6.84 24l8.7-10.48zM14 26h4v-4h-4v4zm20-4h-4v4h4v-4zm-12 4h4v-4h-4v4zm13.54-15.04l-3.08 2.55L41.16 24l-8.7 10.48 3.08 2.55L46.36 24 35.54 10.96z"/>
</vector>

View File

@@ -33,6 +33,25 @@
android:paddingEnd="6dp"
android:src="@drawable/stat_sys_vpn_ic"
/>
<FrameLayout
android:id="@+id/ethernet_combo"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
<com.android.systemui.statusbar.AlphaOptimizedImageView
android:theme="@style/DualToneLightTheme"
android:id="@+id/ethernet"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
<com.android.systemui.statusbar.AlphaOptimizedImageView
android:theme="@style/DualToneDarkTheme"
android:id="@+id/ethernet_dark"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:alpha="0.0"
/>
</FrameLayout>
<FrameLayout
android:id="@+id/wifi_combo"
android:layout_height="wrap_content"

View File

@@ -293,6 +293,11 @@
<!-- Content description of the WiMAX signal when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_wimax_signal_full">WiMAX signal full.</string>
<!-- Content description of the Ethernet connection when disconnected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_ethernet_disconnected">Ethernet disconnected.</string>
<!-- Content description of the Ethernet connection when connected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_ethernet_connected">Ethernet connected.</string>
<!-- Content description of an item with no signal for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_no_signal">No signal.</string>
<!-- Content description of an item with no signal and no connection for accessibility (not shown on the screen) [CHAR LIMIT=NONE] -->

View File

@@ -53,18 +53,21 @@ public class SignalClusterView
private boolean mNoSimsVisible = false;
private boolean mVpnVisible = false;
private boolean mEthernetVisible = false;
private int mEthernetIconId = 0;
private boolean mWifiVisible = false;
private int mWifiStrengthId = 0;
private boolean mIsAirplaneMode = false;
private int mAirplaneIconId = 0;
private int mAirplaneContentDescription;
private String mWifiDescription;
private String mEthernetDescription;
private ArrayList<PhoneState> mPhoneStates = new ArrayList<PhoneState>();
private int mIconTint = Color.WHITE;
private float mDarkIntensity;
ViewGroup mWifiGroup;
ImageView mVpn, mWifi, mAirplane, mNoSims, mWifiDark, mNoSimsDark;
ViewGroup mEthernetGroup, mWifiGroup;
ImageView mVpn, mEthernet, mWifi, mAirplane, mNoSims, mEthernetDark, mWifiDark, mNoSimsDark;
View mWifiAirplaneSpacer;
View mWifiSignalSpacer;
LinearLayout mMobileSignalGroup;
@@ -116,6 +119,9 @@ public class SignalClusterView
super.onAttachedToWindow();
mVpn = (ImageView) findViewById(R.id.vpn);
mEthernetGroup = (ViewGroup) findViewById(R.id.ethernet_combo);
mEthernet = (ImageView) findViewById(R.id.ethernet);
mEthernetDark = (ImageView) findViewById(R.id.ethernet_dark);
mWifiGroup = (ViewGroup) findViewById(R.id.wifi_combo);
mWifi = (ImageView) findViewById(R.id.wifi_signal);
mWifiDark = (ImageView) findViewById(R.id.wifi_signal_dark);
@@ -136,6 +142,8 @@ public class SignalClusterView
@Override
protected void onDetachedFromWindow() {
mVpn = null;
mEthernetGroup = null;
mEthernet = null;
mWifiGroup = null;
mWifi = null;
mAirplane = null;
@@ -182,6 +190,15 @@ public class SignalClusterView
apply();
}
@Override
public void setEthernetIndicators(boolean visible, int icon, String contentDescription) {
mEthernetVisible = visible;
mEthernetIconId = icon;
mEthernetDescription = contentDescription;
apply();
}
@Override
public void setNoSims(boolean show) {
mNoSimsVisible = show;
@@ -234,6 +251,9 @@ public class SignalClusterView
public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
// Standard group layout onPopulateAccessibilityEvent() implementations
// ignore content description, so populate manually
if (mEthernetVisible && mEthernetGroup != null &&
mEthernetGroup.getContentDescription() != null)
event.getText().add(mEthernetGroup.getContentDescription());
if (mWifiVisible && mWifiGroup != null && mWifiGroup.getContentDescription() != null)
event.getText().add(mWifiGroup.getContentDescription());
for (PhoneState state : mPhoneStates) {
@@ -246,6 +266,10 @@ public class SignalClusterView
public void onRtlPropertiesChanged(int layoutDirection) {
super.onRtlPropertiesChanged(layoutDirection);
if (mEthernet != null) {
mEthernet.setImageDrawable(null);
}
if (mWifi != null) {
mWifi.setImageDrawable(null);
}
@@ -277,6 +301,21 @@ public class SignalClusterView
mVpn.setVisibility(mVpnVisible ? View.VISIBLE : View.GONE);
if (DEBUG) Log.d(TAG, String.format("vpn: %s", mVpnVisible ? "VISIBLE" : "GONE"));
if (mEthernetVisible) {
mEthernet.setImageResource(mEthernetIconId);
mEthernetDark.setImageResource(mEthernetIconId);
mEthernetGroup.setContentDescription(mEthernetDescription);
mEthernetGroup.setVisibility(View.VISIBLE);
} else {
mEthernetGroup.setVisibility(View.GONE);
}
if (DEBUG) Log.d(TAG,
String.format("ethernet: %s",
(mEthernetVisible ? "VISIBLE" : "GONE")));
if (mWifiVisible) {
mWifi.setImageResource(mWifiStrengthId);
mWifiDark.setImageResource(mWifiStrengthId);
@@ -327,7 +366,7 @@ public class SignalClusterView
mNoSimsDark.setVisibility(mNoSimsVisible ? View.VISIBLE : View.GONE);
boolean anythingVisible = mNoSimsVisible || mWifiVisible || mIsAirplaneMode
|| anyMobileVisible || mVpnVisible;
|| anyMobileVisible || mVpnVisible || mEthernetVisible;
setPaddingRelative(0, 0, anythingVisible ? mEndPadding : mEndPaddingNothingVisible, 0);
}
@@ -345,6 +384,7 @@ public class SignalClusterView
setTint(mAirplane, mIconTint);
applyDarkIntensity(mDarkIntensity, mNoSims, mNoSimsDark);
applyDarkIntensity(mDarkIntensity, mWifi, mWifiDark);
applyDarkIntensity(mDarkIntensity, mEthernet, mEthernetDark);
for (int i = 0; i < mPhoneStates.size(); i++) {
mPhoneStates.get(i).setIconTint(mIconTint, mDarkIntensity);
}

View File

@@ -35,4 +35,9 @@ public class AccessibilityContentDescriptions {
};
static final int WIFI_NO_CONNECTION = R.string.accessibility_no_wifi;
static final int[] ETHERNET_CONNECTION_VALUES = {
R.string.accessibility_ethernet_disconnected,
R.string.accessibility_ethernet_connected,
};
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2015 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 com.android.systemui.R;
class EthernetIcons {
static final int[][] ETHERNET_ICONS = {
{ R.drawable.stat_sys_ethernet },
{ R.drawable.stat_sys_ethernet_fully },
};
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2015 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.NetworkCapabilities;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
import java.util.List;
import java.util.Objects;
public class EthernetSignalController extends
SignalController<SignalController.State, SignalController.IconGroup> {
public EthernetSignalController(Context context,
List<NetworkSignalChangedCallback> signalCallbacks,
List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
super("EthernetSignalController", context, NetworkCapabilities.TRANSPORT_ETHERNET,
signalCallbacks, signalClusters, networkController);
mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
"Ethernet Icons",
EthernetIcons.ETHERNET_ICONS,
null,
AccessibilityContentDescriptions.ETHERNET_CONNECTION_VALUES,
0, 0, 0, 0,
AccessibilityContentDescriptions.ETHERNET_CONNECTION_VALUES[0]);
}
@Override
public void notifyListeners() {
boolean ethernetVisible = mCurrentState.connected;
String contentDescription = getStringIfExists(getContentDescription());
// TODO: wire up data transfer using WifiSignalPoller.
int signalClustersLength = mSignalClusters.size();
for (int i = 0; i < signalClustersLength; i++) {
mSignalClusters.get(i).setEthernetIndicators(ethernetVisible, getCurrentIconId(),
contentDescription);
}
}
@Override
public SignalController.State cleanState() {
return new SignalController.State();
}
public void setConnected(boolean connected) {
mCurrentState.connected = connected;
notifyListenersIfNecessary();
}
}

View File

@@ -73,6 +73,10 @@ public class NetworkControllerImpl extends BroadcastReceiver
// Subcontrollers.
@VisibleForTesting
final WifiSignalController mWifiSignalController;
@VisibleForTesting
final EthernetSignalController mEthernetSignalController;
@VisibleForTesting
final Map<Integer, MobileSignalController> mMobileSignalControllers =
new HashMap<Integer, MobileSignalController>();
@@ -154,6 +158,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
mSignalsChangedCallbacks, mSignalClusters, this);
mEthernetSignalController = new EthernetSignalController(mContext, mSignalsChangedCallbacks,
mSignalClusters, this);
// AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
updateAirplaneMode(true /* force callback */);
}
@@ -281,6 +288,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
R.string.accessibility_airplane_mode);
cluster.setNoSims(mHasNoSims);
mWifiSignalController.notifyListeners();
mEthernetSignalController.notifyListeners();
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
mobileSignalController.notifyListeners();
}
@@ -291,6 +299,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
cb.onAirplaneModeChanged(mAirplaneMode);
cb.onNoSimVisibleChanged(mHasNoSims);
mWifiSignalController.notifyListeners();
mEthernetSignalController.notifyListeners();
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
mobileSignalController.notifyListeners();
}
@@ -501,6 +510,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
mobileSignalController.notifyListeners();
}
mWifiSignalController.notifyListeners();
mEthernetSignalController.notifyListeners();
}
/**
@@ -560,6 +570,11 @@ public class NetworkControllerImpl extends BroadcastReceiver
}
mWifiSignalController.setInetCondition(
mValidatedTransports.get(mWifiSignalController.getTransportType()) ? 1 : 0);
mEthernetSignalController.setConnected(
mConnectedTransports.get(mEthernetSignalController.getTransportType()));
mEthernetSignalController.setInetCondition(
mValidatedTransports.get(mEthernetSignalController.getTransportType()) ? 1 : 0);
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -586,6 +601,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
}
mWifiSignalController.dump(pw);
mEthernetSignalController.dump(pw);
mAccessPoints.dump(pw);
}
@@ -731,6 +748,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
void setSubs(List<SubscriptionInfo> subs);
void setNoSims(boolean show);
void setEthernetIndicators(boolean visible, int icon, String contentDescription);
void setIsAirplaneMode(boolean is, int airplaneIcon, int contentDescription);
}

View File

@@ -0,0 +1,40 @@
package com.android.systemui.statusbar.policy;
import android.net.NetworkCapabilities;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
public class NetworkControllerEthernetTest extends NetworkControllerBaseTest {
public void testEthernetIcons() {
verifyLastEthernetIcon(false, 0);
setEthernetState(true, false); // Connected, unvalidated.
verifyLastEthernetIcon(true, EthernetIcons.ETHERNET_ICONS[0][0]);
setEthernetState(true, true); // Connected, validated.
verifyLastEthernetIcon(true, EthernetIcons.ETHERNET_ICONS[1][0]);
setEthernetState(true, false); // Connected, unvalidated.
verifyLastEthernetIcon(true, EthernetIcons.ETHERNET_ICONS[0][0]);
setEthernetState(false, false); // Disconnected.
verifyLastEthernetIcon(false, 0);
}
protected void setEthernetState(boolean connected, boolean validated) {
setConnectivity(validated ? 100 : 0, NetworkCapabilities.TRANSPORT_ETHERNET, connected);
}
protected void verifyLastEthernetIcon(boolean visible, int icon) {
ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setEthernetIndicators(
visibleArg.capture(), iconArg.capture(),
ArgumentCaptor.forClass(String.class).capture());
assertEquals("Ethernet visible, in status bar", visible, (boolean) visibleArg.getValue());
assertEquals("Ethernet icon, in status bar", icon, (int) iconArg.getValue());
}
}