Merge "QS: Add transient icon for hotspot" into oc-dev
am: cf6fa5e951
Change-Id: Idc3873203538e1927c778ba1a2a34351921101e6
This commit is contained in:
@@ -105,6 +105,7 @@ public interface QSTile {
|
|||||||
public CharSequence dualLabelContentDescription;
|
public CharSequence dualLabelContentDescription;
|
||||||
public boolean disabledByPolicy;
|
public boolean disabledByPolicy;
|
||||||
public boolean dualTarget = false;
|
public boolean dualTarget = false;
|
||||||
|
public boolean isTransient = false;
|
||||||
public String expandedAccessibilityClassName;
|
public String expandedAccessibilityClassName;
|
||||||
|
|
||||||
public boolean copyTo(State other) {
|
public boolean copyTo(State other) {
|
||||||
@@ -119,6 +120,7 @@ public interface QSTile {
|
|||||||
expandedAccessibilityClassName)
|
expandedAccessibilityClassName)
|
||||||
|| !Objects.equals(other.disabledByPolicy, disabledByPolicy)
|
|| !Objects.equals(other.disabledByPolicy, disabledByPolicy)
|
||||||
|| !Objects.equals(other.state, state)
|
|| !Objects.equals(other.state, state)
|
||||||
|
|| !Objects.equals(other.isTransient, isTransient)
|
||||||
|| !Objects.equals(other.dualTarget, dualTarget);
|
|| !Objects.equals(other.dualTarget, dualTarget);
|
||||||
other.icon = icon;
|
other.icon = icon;
|
||||||
other.label = label;
|
other.label = label;
|
||||||
@@ -128,6 +130,7 @@ public interface QSTile {
|
|||||||
other.disabledByPolicy = disabledByPolicy;
|
other.disabledByPolicy = disabledByPolicy;
|
||||||
other.state = state;
|
other.state = state;
|
||||||
other.dualTarget = dualTarget;
|
other.dualTarget = dualTarget;
|
||||||
|
other.isTransient = isTransient;
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +148,7 @@ public interface QSTile {
|
|||||||
sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName);
|
sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName);
|
||||||
sb.append(",disabledByPolicy=").append(disabledByPolicy);
|
sb.append(",disabledByPolicy=").append(disabledByPolicy);
|
||||||
sb.append(",dualTarget=").append(dualTarget);
|
sb.append(",dualTarget=").append(dualTarget);
|
||||||
|
sb.append(",isTransient=").append(isTransient);
|
||||||
sb.append(",state=").append(state);
|
sb.append(",state=").append(state);
|
||||||
return sb.append(']');
|
return sb.append(']');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<set
|
||||||
|
android:ordering="sequentially" >
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="266"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="1.0"
|
||||||
|
android:valueTo="1.0"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="16"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="1.0"
|
||||||
|
android:valueTo="0.5"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="433"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="0.5"
|
||||||
|
android:valueTo="0.5"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="16"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="0.5"
|
||||||
|
android:valueTo="1.0"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
</set>
|
||||||
|
</set>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<set
|
||||||
|
android:ordering="sequentially" >
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="133"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="1.0"
|
||||||
|
android:valueTo="1.0"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="16"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="1.0"
|
||||||
|
android:valueTo="0.5"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="433"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="0.5"
|
||||||
|
android:valueTo="0.5"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="16"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="0.5"
|
||||||
|
android:valueTo="1.0"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
</set>
|
||||||
|
</set>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<set
|
||||||
|
android:ordering="sequentially" >
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="16"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="1.0"
|
||||||
|
android:valueTo="0.5"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="433"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="0.5"
|
||||||
|
android:valueTo="0.5"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
<objectAnimator
|
||||||
|
android:duration="16"
|
||||||
|
android:propertyName="fillAlpha"
|
||||||
|
android:valueFrom="0.5"
|
||||||
|
android:valueTo="1.0"
|
||||||
|
android:valueType="floatType"
|
||||||
|
android:interpolator="@android:interpolator/linear" />
|
||||||
|
</set>
|
||||||
|
</set>
|
||||||
50
packages/SystemUI/res/drawable/ic_hotspot_transient.xml
Normal file
50
packages/SystemUI/res/drawable/ic_hotspot_transient.xml
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animated-vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:drawable="@drawable/ic_hotspot_transient" >
|
||||||
|
<target
|
||||||
|
android:name="circle_3"
|
||||||
|
android:animation="@anim/ic_hotspot_transient_circle_3_animation" />
|
||||||
|
<target
|
||||||
|
android:name="circle_2"
|
||||||
|
android:animation="@anim/ic_hotspot_transient_circle_2_animation" />
|
||||||
|
<target
|
||||||
|
android:name="circle_1"
|
||||||
|
android:animation="@anim/ic_hotspot_transient_circle_1_animation" />
|
||||||
|
</animated-vector>
|
||||||
@@ -22,6 +22,8 @@ import android.content.res.ColorStateList;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.Animatable;
|
import android.graphics.drawable.Animatable;
|
||||||
|
import android.graphics.drawable.Animatable2;
|
||||||
|
import android.graphics.drawable.Animatable2.AnimationCallback;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@@ -96,11 +98,16 @@ public class QSIconViewImpl extends QSIconView {
|
|||||||
iv.setImageDrawable(d);
|
iv.setImageDrawable(d);
|
||||||
iv.setTag(R.id.qs_icon_tag, state.icon);
|
iv.setTag(R.id.qs_icon_tag, state.icon);
|
||||||
iv.setPadding(0, padding, 0, padding);
|
iv.setPadding(0, padding, 0, padding);
|
||||||
if (d instanceof Animatable && iv.isShown()) {
|
if (d instanceof Animatable2) {
|
||||||
Animatable a = (Animatable) d;
|
Animatable2 a = (Animatable2) d;
|
||||||
a.start();
|
a.start();
|
||||||
if (!iv.isShown()) {
|
if (state.isTransient) {
|
||||||
a.stop(); // skip directly to end state
|
a.registerAnimationCallback(new AnimationCallback() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Drawable drawable) {
|
||||||
|
a.start();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import android.provider.Settings.Global;
|
|||||||
import android.service.quicksettings.Tile;
|
import android.service.quicksettings.Tile;
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
@@ -43,6 +42,7 @@ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> {
|
|||||||
private final AnimationIcon mEnable =
|
private final AnimationIcon mEnable =
|
||||||
new AnimationIcon(R.drawable.ic_hotspot_enable_animation,
|
new AnimationIcon(R.drawable.ic_hotspot_enable_animation,
|
||||||
R.drawable.ic_hotspot_disable);
|
R.drawable.ic_hotspot_disable);
|
||||||
|
private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot_disable);
|
||||||
private final AnimationIcon mDisable =
|
private final AnimationIcon mDisable =
|
||||||
new AnimationIcon(R.drawable.ic_hotspot_disable_animation,
|
new AnimationIcon(R.drawable.ic_hotspot_disable_animation,
|
||||||
R.drawable.ic_hotspot_enable);
|
R.drawable.ic_hotspot_enable);
|
||||||
@@ -124,10 +124,15 @@ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> {
|
|||||||
} else {
|
} else {
|
||||||
state.value = mController.isHotspotEnabled();
|
state.value = mController.isHotspotEnabled();
|
||||||
}
|
}
|
||||||
state.icon = state.value ? mEnable : mDisable;
|
state.icon = !state.value ? mDisable
|
||||||
|
: state.isTransient ? mEnabledStatic
|
||||||
|
: mEnable;
|
||||||
boolean wasAirplane = state.isAirplaneMode;
|
boolean wasAirplane = state.isAirplaneMode;
|
||||||
state.isAirplaneMode = mAirplaneMode.getValue() != 0;
|
state.isAirplaneMode = mAirplaneMode.getValue() != 0;
|
||||||
if (state.isAirplaneMode) {
|
state.isTransient = mController.isHotspotTransient();
|
||||||
|
if (state.isTransient) {
|
||||||
|
state.icon = ResourceIcon.get(R.drawable.ic_hotspot_transient_animation);
|
||||||
|
} else if (state.isAirplaneMode) {
|
||||||
state.icon = mUnavailable;
|
state.icon = mUnavailable;
|
||||||
} else if (wasAirplane) {
|
} else if (wasAirplane) {
|
||||||
state.icon = mDisableNoAnimation;
|
state.icon = mDisableNoAnimation;
|
||||||
@@ -135,7 +140,7 @@ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> {
|
|||||||
state.expandedAccessibilityClassName = Switch.class.getName();
|
state.expandedAccessibilityClassName = Switch.class.getName();
|
||||||
state.contentDescription = state.label;
|
state.contentDescription = state.label;
|
||||||
state.state = state.isAirplaneMode ? Tile.STATE_UNAVAILABLE
|
state.state = state.isAirplaneMode ? Tile.STATE_UNAVAILABLE
|
||||||
: state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
|
: state.value || state.isTransient ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import com.android.systemui.statusbar.policy.HotspotController.Callback;
|
|||||||
|
|
||||||
public interface HotspotController extends CallbackController<Callback>, Dumpable {
|
public interface HotspotController extends CallbackController<Callback>, Dumpable {
|
||||||
boolean isHotspotEnabled();
|
boolean isHotspotEnabled();
|
||||||
|
boolean isHotspotTransient();
|
||||||
|
|
||||||
void setHotspotEnabled(boolean enabled);
|
void setHotspotEnabled(boolean enabled);
|
||||||
boolean isHotspotSupported();
|
boolean isHotspotSupported();
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ public class HotspotControllerImpl implements HotspotController {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
private int mHotspotState;
|
private int mHotspotState;
|
||||||
|
private boolean mWaitingForCallback;
|
||||||
|
|
||||||
public HotspotControllerImpl(Context context) {
|
public HotspotControllerImpl(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -101,22 +103,20 @@ public class HotspotControllerImpl implements HotspotController {
|
|||||||
return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED;
|
return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class OnStartTetheringCallback extends
|
@Override
|
||||||
ConnectivityManager.OnStartTetheringCallback {
|
public boolean isHotspotTransient() {
|
||||||
@Override
|
return mWaitingForCallback || (mHotspotState == WifiManager.WIFI_AP_STATE_ENABLING);
|
||||||
public void onTetheringStarted() {}
|
|
||||||
@Override
|
|
||||||
public void onTetheringFailed() {
|
|
||||||
// TODO: Show error.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHotspotEnabled(boolean enabled) {
|
public void setHotspotEnabled(boolean enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
OnStartTetheringCallback callback = new OnStartTetheringCallback();
|
OnStartTetheringCallback callback = new OnStartTetheringCallback();
|
||||||
|
mWaitingForCallback = true;
|
||||||
|
if (DEBUG) Log.d(TAG, "Starting tethering");
|
||||||
mConnectivityManager.startTethering(
|
mConnectivityManager.startTethering(
|
||||||
ConnectivityManager.TETHERING_WIFI, false, callback);
|
ConnectivityManager.TETHERING_WIFI, false, callback);
|
||||||
|
fireCallback(isHotspotEnabled());
|
||||||
} else {
|
} else {
|
||||||
mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
|
mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
|
||||||
}
|
}
|
||||||
@@ -130,6 +130,24 @@ public class HotspotControllerImpl implements HotspotController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class OnStartTetheringCallback extends
|
||||||
|
ConnectivityManager.OnStartTetheringCallback {
|
||||||
|
@Override
|
||||||
|
public void onTetheringStarted() {
|
||||||
|
if (DEBUG) Log.d(TAG, "onTetheringStarted");
|
||||||
|
mWaitingForCallback = false;
|
||||||
|
// Don't fire a callback here, instead wait for the next update from wifi.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTetheringFailed() {
|
||||||
|
if (DEBUG) Log.d(TAG, "onTetheringFailed");
|
||||||
|
mWaitingForCallback = false;
|
||||||
|
fireCallback(isHotspotEnabled());
|
||||||
|
// TODO: Show error.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final class Receiver extends BroadcastReceiver {
|
private final class Receiver extends BroadcastReceiver {
|
||||||
private boolean mRegistered;
|
private boolean mRegistered;
|
||||||
|
|
||||||
@@ -149,9 +167,9 @@ public class HotspotControllerImpl implements HotspotController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (DEBUG) Log.d(TAG, "onReceive " + intent.getAction());
|
|
||||||
int state = intent.getIntExtra(
|
int state = intent.getIntExtra(
|
||||||
WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
|
WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
|
||||||
|
if (DEBUG) Log.d(TAG, "onReceive " + state);
|
||||||
mHotspotState = state;
|
mHotspotState = state;
|
||||||
fireCallback(mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED);
|
fireCallback(mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ public class FakeHotspotController extends BaseLeakChecker<Callback> implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isHotspotTransient() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHotspotEnabled(boolean enabled) {
|
public void setHotspotEnabled(boolean enabled) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user