diff options
3 files changed, 123 insertions, 19 deletions
diff --git a/core/java/com/android/internal/widget/LockScreenWidgetCallback.java b/core/java/com/android/internal/widget/LockScreenWidgetCallback.java index d6403e9..d7ad6c0 100644 --- a/core/java/com/android/internal/widget/LockScreenWidgetCallback.java +++ b/core/java/com/android/internal/widget/LockScreenWidgetCallback.java @@ -29,6 +29,9 @@ public interface LockScreenWidgetCallback { // Sends a message to lock screen requesting the view to be hidden. public void requestHide(View self); + // Whether or not this view is currently visible on LockScreen + public boolean isVisible(View self); + // Sends a message to lock screen that user has interacted with widget. This should be used // exclusively in response to user activity, i.e. user hits a button in the view. public void userActivity(View self); diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java index 73d9f10..be88f14 100644 --- a/core/java/com/android/internal/widget/TransportControlView.java +++ b/core/java/com/android/internal/widget/TransportControlView.java @@ -34,6 +34,8 @@ import android.media.IRemoteControlDisplay; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.os.Parcel; +import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; import android.text.Spannable; @@ -61,7 +63,7 @@ public class TransportControlView extends FrameLayout implements OnClickListener private static final int MSG_SET_GENERATION_ID = 104; private static final int MAXDIM = 512; private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s - protected static final boolean DEBUG = true; + protected static final boolean DEBUG = false; protected static final String TAG = "TransportControlView"; private ImageView mAlbumArt; @@ -74,7 +76,7 @@ public class TransportControlView extends FrameLayout implements OnClickListener private boolean mAttached; private PendingIntent mClientIntent; private int mTransportControlFlags; - private int mPlayState; + private int mCurrentPlayState; private AudioManager mAudioManager; private LockScreenWidgetCallback mWidgetCallbacks; private IRemoteControlDisplayWeak mIRCD; @@ -84,6 +86,11 @@ public class TransportControlView extends FrameLayout implements OnClickListener */ private Bundle mPopulateMetadataWhenAttached = null; + /** + * Whether to clear the interface next time it is shown (i.e. the generation id changed) + */ + private boolean mClearOnNextShow; + // This handler is required to ensure messages from IRCD are handled in sequence and on // the UI thread. private Handler mHandler = new Handler() { @@ -113,15 +120,10 @@ public class TransportControlView extends FrameLayout implements OnClickListener break; case MSG_SET_GENERATION_ID: - if (mWidgetCallbacks != null) { - boolean clearing = msg.arg2 != 0; - if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + clearing); - if (!clearing) { - mWidgetCallbacks.requestShow(TransportControlView.this); - } else { - mWidgetCallbacks.requestHide(TransportControlView.this); - } + if (msg.arg2 != 0) { + mClearOnNextShow = true; // TODO: handle this } + if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2); mClientGeneration = msg.arg1; mClientIntent = (PendingIntent) msg.obj; break; @@ -195,6 +197,7 @@ public class TransportControlView extends FrameLayout implements OnClickListener super(context, attrs); Log.v(TAG, "Create TCV " + this); mAudioManager = new AudioManager(mContext); + mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback mIRCD = new IRemoteControlDisplayWeak(mHandler); } @@ -319,7 +322,7 @@ public class TransportControlView extends FrameLayout implements OnClickListener | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE | RemoteControlClient.FLAG_KEY_MEDIA_STOP); - updatePlayPauseState(mPlayState); + updatePlayPauseState(mCurrentPlayState); } private static void setVisibilityBasedOnFlag(View view, int flags, int flag) { @@ -332,32 +335,92 @@ public class TransportControlView extends FrameLayout implements OnClickListener private void updatePlayPauseState(int state) { if (DEBUG) Log.v(TAG, - "updatePlayPauseState(), old=" + mPlayState + ", state=" + state); - if (state == mPlayState) { + "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state); + if (state == mCurrentPlayState) { return; } final int imageResId; final int imageDescId; + final boolean showIfHidden; switch (state) { case RemoteControlClient.PLAYSTATE_PLAYING: imageResId = com.android.internal.R.drawable.ic_media_pause; imageDescId = com.android.internal.R.string.lockscreen_transport_pause_description; + showIfHidden = true; break; case RemoteControlClient.PLAYSTATE_BUFFERING: imageResId = com.android.internal.R.drawable.ic_media_stop; imageDescId = com.android.internal.R.string.lockscreen_transport_stop_description; + showIfHidden = true; break; case RemoteControlClient.PLAYSTATE_PAUSED: default: imageResId = com.android.internal.R.drawable.ic_media_play; imageDescId = com.android.internal.R.string.lockscreen_transport_play_description; + showIfHidden = false; break; } mBtnPlay.setImageResource(imageResId); mBtnPlay.setContentDescription(getResources().getString(imageDescId)); - mPlayState = state; + if (showIfHidden && mWidgetCallbacks != null && !mWidgetCallbacks.isVisible(this)) { + mWidgetCallbacks.requestShow(this); + } + mCurrentPlayState = state; + } + + static class SavedState extends BaseSavedState { + boolean wasShowing; + + SavedState(Parcelable superState) { + super(superState); + } + + private SavedState(Parcel in) { + super(in); + this.wasShowing = in.readInt() != 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeInt(this.wasShowing ? 1 : 0); + } + + public static final Parcelable.Creator<SavedState> CREATOR + = new Parcelable.Creator<SavedState>() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + @Override + public Parcelable onSaveInstanceState() { + if (DEBUG) Log.v(TAG, "onSaveInstanceState()"); + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + ss.wasShowing = mWidgetCallbacks.isVisible(this); + return ss; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + if (DEBUG) Log.v(TAG, "onRestoreInstanceState()"); + if (!(state instanceof SavedState)) { + super.onRestoreInstanceState(state); + return; + } + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + if (ss.wasShowing) { + mWidgetCallbacks.requestShow(this); + } } public void onClick(View v) { diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 80275b1..155f6fd 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -49,6 +49,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.IBinder; +import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; @@ -221,6 +222,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler private Runnable mRecreateRunnable = new Runnable() { public void run() { updateScreen(mMode, true); + restoreWidgetState(); } }; @@ -244,8 +246,20 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // TODO: examine all widgets to derive clock status mUpdateMonitor.reportClockVisible(true); } + + public boolean isVisible(View self) { + // TODO: this should be up to the lockscreen to determine if the view + // is currently showing. The idea is it can be used for the widget to + // avoid doing work if it's not visible. For now just returns the view's + // actual visibility. + return self.getVisibility() == View.VISIBLE; + } }; + private TransportControlView mTransportControlView; + + private Parcelable mSavedState; + /** * @return Whether we are stuck on the lock screen because the sim is * missing. @@ -365,6 +379,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler public void keyguardDone(boolean authenticated) { getCallback().keyguardDone(authenticated); + mSavedState = null; // clear state so we re-establish when locked again } public void keyguardDoneDrawing() { @@ -528,6 +543,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler ((KeyguardScreen) mUnlockScreen).onPause(); } + saveWidgetState(); + // When screen is turned off, need to unbind from FaceLock service if using FaceLock stopAndUnbindFromFaceLock(); } @@ -558,8 +575,28 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler mScreenOn = true; runFaceLock = mWindowFocused; } + show(); - if(runFaceLock) activateFaceLockIfAble(); + + restoreWidgetState(); + + if (runFaceLock) activateFaceLockIfAble(); + } + + private void saveWidgetState() { + if (mTransportControlView != null) { + if (DEBUG) Log.v(TAG, "Saving widget state"); + mSavedState = mTransportControlView.onSaveInstanceState(); + } + } + + private void restoreWidgetState() { + if (mTransportControlView != null) { + if (DEBUG) Log.v(TAG, "Restoring widget state"); + if (mSavedState != null) { + mTransportControlView.onRestoreInstanceState(mSavedState); + } + } } /** Unbind from facelock if something covers this window (such as an alarm) @@ -643,6 +680,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler mShowLockBeforeUnlock = resources.getBoolean(R.bool.config_enableLockBeforeUnlockScreen); mConfiguration = newConfig; if (DEBUG_CONFIGURATION) Log.v(TAG, "**** re-creating lock screen since config changed"); + saveWidgetState(); removeCallbacks(mRecreateRunnable); post(mRecreateRunnable); } @@ -895,13 +933,13 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler } private void initializeTransportControlView(View view) { - TransportControlView tcv = (TransportControlView) view.findViewById(R.id.transport); - if (tcv == null) { + mTransportControlView = (TransportControlView) view.findViewById(R.id.transport); + if (mTransportControlView == null) { if (DEBUG) Log.w(TAG, "Couldn't find transport control widget"); } else { mUpdateMonitor.reportClockVisible(true); - tcv.setVisibility(View.GONE); // hide until it requests being shown. - tcv.setCallback(mWidgetCallback); + mTransportControlView.setVisibility(View.GONE); // hide until it requests being shown. + mTransportControlView.setCallback(mWidgetCallback); } } |