Loading core/java/com/android/internal/widget/LockScreenWidgetCallback.java +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/com/android/internal/widget/TransportControlView.java +77 −14 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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) { Loading @@ -332,12 +335,13 @@ 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_ERROR: imageResId = com.android.internal.R.drawable.stat_sys_warning; Loading @@ -349,22 +353,81 @@ public class TransportControlView extends FrameLayout implements OnClickListener 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) { Loading policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +43 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -221,6 +222,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler private Runnable mRecreateRunnable = new Runnable() { public void run() { updateScreen(mMode, true); restoreWidgetState(); } }; Loading @@ -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. Loading Loading @@ -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() { Loading Loading @@ -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(); } Loading Loading @@ -558,10 +575,30 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler mScreenOn = true; runFaceLock = mWindowFocused; } show(); 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) * bind to facelock if the lockscreen window just came into focus, and the screen is on */ Loading Loading @@ -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); } Loading Loading @@ -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); } } Loading Loading
core/java/com/android/internal/widget/LockScreenWidgetCallback.java +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/com/android/internal/widget/TransportControlView.java +77 −14 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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) { Loading @@ -332,12 +335,13 @@ 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_ERROR: imageResId = com.android.internal.R.drawable.stat_sys_warning; Loading @@ -349,22 +353,81 @@ public class TransportControlView extends FrameLayout implements OnClickListener 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) { Loading
policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +43 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -221,6 +222,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler private Runnable mRecreateRunnable = new Runnable() { public void run() { updateScreen(mMode, true); restoreWidgetState(); } }; Loading @@ -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. Loading Loading @@ -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() { Loading Loading @@ -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(); } Loading Loading @@ -558,10 +575,30 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler mScreenOn = true; runFaceLock = mWindowFocused; } show(); 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) * bind to facelock if the lockscreen window just came into focus, and the screen is on */ Loading Loading @@ -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); } Loading Loading @@ -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); } } Loading