3333import android .graphics .Canvas ;
3434import android .graphics .Rect ;
3535import android .os .Looper ;
36+ import android .os .Parcel ;
37+ import android .os .Parcelable ;
3638import android .os .UserManager ;
3739import android .util .AttributeSet ;
3840import android .util .Log ;
4345import android .view .View ;
4446import android .view .ViewGroup ;
4547import android .view .WindowManager ;
48+ import android .view .View .BaseSavedState ;
4649import android .view .animation .AnimationUtils ;
4750import android .widget .RemoteViews .OnClickHandler ;
4851import android .widget .ViewFlipper ;
4952
5053import com .android .internal .R ;
5154import com .android .internal .policy .impl .keyguard .KeyguardSecurityModel .SecurityMode ;
55+ import com .android .internal .policy .impl .keyguard .KeyguardTransportControlView .SavedState ;
5256import com .android .internal .widget .LockPatternUtils ;
5357
5458import java .io .File ;
@@ -64,6 +68,10 @@ public class KeyguardHostView extends KeyguardViewBase {
6468 static final int APPWIDGET_HOST_ID = 0x4B455947 ;
6569 private static final String KEYGUARD_WIDGET_PREFS = "keyguard_widget_prefs" ;
6670
71+ private static final int TRANSPORT_GONE = 0 ;
72+ private static final int TRANSPORT_INVISIBLE = 1 ;
73+ private static final int TRANSPORT_VISIBLE = 2 ;
74+
6775 private AppWidgetHost mAppWidgetHost ;
6876 private KeyguardWidgetRegion mAppWidgetRegion ;
6977 private KeyguardWidgetPager mAppWidgetContainer ;
@@ -83,10 +91,12 @@ public class KeyguardHostView extends KeyguardViewBase {
8391 private KeyguardSecurityModel mSecurityModel ;
8492
8593 private Rect mTempRect = new Rect ();
94+ private int mTransportState = TRANSPORT_GONE ;
8695
8796 /*package*/ interface TransportCallback {
88- void hide ();
89- void show ();
97+ void onListenerDetached ();
98+ void onListenerAttached ();
99+ void onPlayStateChanged ();
90100 }
91101
92102 /*package*/ interface UserSwitcherCallback {
@@ -185,7 +195,7 @@ protected void onAttachedToWindow() {
185195 mAppWidgetHost .startListening ();
186196 maybePopulateWidgets ();
187197 disableStatusViewInteraction ();
188- showAppropriateWidgetPage ( );
198+ post ( mSwitchPageRunnable );
189199 }
190200
191201 private void disableStatusViewInteraction () {
@@ -712,7 +722,7 @@ private void addWidget(int appId) {
712722 private void addDefaultWidgets () {
713723 LayoutInflater inflater = LayoutInflater .from (mContext );
714724 inflater .inflate (R .layout .keyguard_status_view , mAppWidgetContainer , true );
715- inflater .inflate (R .layout .keyguard_transport_control_view , mAppWidgetContainer , true );
725+ inflater .inflate (R .layout .keyguard_transport_control_view , this , true );
716726
717727 inflateAndAddUserSelectorWidgetIfNecessary ();
718728 initializeTransportControl ();
@@ -721,16 +731,16 @@ private void addDefaultWidgets() {
721731 private void initializeTransportControl () {
722732 mTransportControl =
723733 (KeyguardTransportControlView ) findViewById (R .id .keyguard_transport_control );
734+ mTransportControl .setVisibility (View .GONE );
724735
725736 // This code manages showing/hiding the transport control. We keep it around and only
726737 // add it to the hierarchy if it needs to be present.
727738 if (mTransportControl != null ) {
728739 mTransportControl .setKeyguardCallback (new TransportCallback () {
729- boolean mSticky = false ;
730740 @ Override
731- public void hide () {
741+ public void onListenerDetached () {
732742 int page = getWidgetPosition (R .id .keyguard_transport_control );
733- if (page != -1 && ! mSticky ) {
743+ if (page != -1 ) {
734744 if (page == mAppWidgetContainer .getCurrentPage ()) {
735745 // Switch back to clock view if music was showing.
736746 mAppWidgetContainer
@@ -741,20 +751,23 @@ public void hide() {
741751 // from AudioManager
742752 KeyguardHostView .this .addView (mTransportControl );
743753 mTransportControl .setVisibility (View .GONE );
754+ mTransportState = TRANSPORT_GONE ;
744755 }
745756 }
746757
747758 @ Override
748- public void show () {
759+ public void onListenerAttached () {
749760 if (getWidgetPosition (R .id .keyguard_transport_control ) == -1 ) {
750761 KeyguardHostView .this .removeView (mTransportControl );
751- mAppWidgetContainer .addView (mTransportControl ,
752- getWidgetPosition (R .id .keyguard_status_view ) + 1 );
762+ mAppWidgetContainer .addView (mTransportControl , 0 );
753763 mTransportControl .setVisibility (View .VISIBLE );
754- // Once shown, leave it showing
755- mSticky = true ;
756764 }
757765 }
766+
767+ @ Override
768+ public void onPlayStateChanged () {
769+ mTransportControl .post (mSwitchPageRunnable );
770+ }
758771 });
759772 }
760773 }
@@ -796,12 +809,87 @@ private void maybePopulateWidgets() {
796809 }
797810 }
798811
812+ Runnable mSwitchPageRunnable = new Runnable () {
813+ @ Override
814+ public void run () {
815+ showAppropriateWidgetPage ();
816+ }
817+ };
818+
819+ static class SavedState extends BaseSavedState {
820+ int transportState ;
821+
822+ SavedState (Parcelable superState ) {
823+ super (superState );
824+ }
825+
826+ private SavedState (Parcel in ) {
827+ super (in );
828+ this .transportState = in .readInt ();
829+ }
830+
831+ @ Override
832+ public void writeToParcel (Parcel out , int flags ) {
833+ super .writeToParcel (out , flags );
834+ out .writeInt (this .transportState );
835+ }
836+
837+ public static final Parcelable .Creator <SavedState > CREATOR
838+ = new Parcelable .Creator <SavedState >() {
839+ public SavedState createFromParcel (Parcel in ) {
840+ return new SavedState (in );
841+ }
842+
843+ public SavedState [] newArray (int size ) {
844+ return new SavedState [size ];
845+ }
846+ };
847+ }
848+
849+ @ Override
850+ public Parcelable onSaveInstanceState () {
851+ Parcelable superState = super .onSaveInstanceState ();
852+ SavedState ss = new SavedState (superState );
853+ ss .transportState = mTransportState ;
854+ return ss ;
855+ }
856+
857+ @ Override
858+ public void onRestoreInstanceState (Parcelable state ) {
859+ if (!(state instanceof SavedState )) {
860+ super .onRestoreInstanceState (state );
861+ return ;
862+ }
863+ SavedState ss = (SavedState ) state ;
864+ super .onRestoreInstanceState (ss .getSuperState ());
865+ mTransportState = ss .transportState ;
866+ post (mSwitchPageRunnable );
867+ }
868+
799869 private void showAppropriateWidgetPage () {
800- int page = mAppWidgetContainer .indexOfChild (findViewById (R .id .keyguard_status_view ));
801- if (mAppWidgetContainer .indexOfChild (mTransportControl ) != -1 ) {
802- page = mAppWidgetContainer .indexOfChild (mTransportControl );
870+
871+ // The following sets the priority for showing widgets. Transport should be shown if
872+ // music is playing, followed by the multi-user widget if enabled, followed by the
873+ // status widget.
874+ final int pageToShow ;
875+ if (mTransportControl .isMusicPlaying () || mTransportState == TRANSPORT_VISIBLE ) {
876+ mTransportState = TRANSPORT_VISIBLE ;
877+ pageToShow = mAppWidgetContainer .indexOfChild (mTransportControl );
878+ } else {
879+ UserManager mUm = (UserManager ) mContext .getSystemService (Context .USER_SERVICE );
880+ final View multiUserView = findViewById (R .id .keyguard_multi_user_selector );
881+ final int multiUserPosition = mAppWidgetContainer .indexOfChild (multiUserView );
882+ if (multiUserPosition != -1 && mUm .getUsers (true ).size () > 1 ) {
883+ pageToShow = multiUserPosition ;
884+ } else {
885+ final View statusView = findViewById (R .id .keyguard_status_view );
886+ pageToShow = mAppWidgetContainer .indexOfChild (statusView );
887+ }
888+ if (mTransportState == TRANSPORT_VISIBLE ) {
889+ mTransportState = TRANSPORT_INVISIBLE ;
890+ }
803891 }
804- mAppWidgetContainer .setCurrentPage (page );
892+ mAppWidgetContainer .setCurrentPage (pageToShow );
805893 }
806894
807895 private void inflateAndAddUserSelectorWidgetIfNecessary () {
0 commit comments