diff options
9 files changed, 178 insertions, 55 deletions
diff --git a/docs/html/distribute/googleplay/publish/preparing.jd b/docs/html/distribute/googleplay/publish/preparing.jd index 463343d2d7e5..a3538a95c0ee 100644 --- a/docs/html/distribute/googleplay/publish/preparing.jd +++ b/docs/html/distribute/googleplay/publish/preparing.jd @@ -15,7 +15,7 @@ page.title=Publishing Checklist for Google Play <li><a href="#inapp-billing">9. Consider In-app Billing</a></li> <li><a href="#pricing">10. Set prices for your apps</a></li> <li><a href="#localize">11. Start localization early</a></li> -<li><a href="#localize">12. Prepare promotional graphics</a></li> +<li><a href="#graphics">12. Prepare promotional graphics</a></li> <li><a href="#apk">13. Build the release-ready APK</a></li> <li><a href="#product-page">14. Complete the product details</a></li> <li><a href="#badges">15. Use Google Play badges</a></li> diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index fefd4fb9831b..17256cfa2893 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -412,7 +412,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mForceStatusBar; boolean mForceStatusBarFromKeyguard; boolean mHideLockScreen; - boolean mDismissKeyguard; + + // States of keyguard dismiss. + private static final int DISMISS_KEYGUARD_NONE = 0; // Keyguard not being dismissed. + private static final int DISMISS_KEYGUARD_START = 1; // Keyguard needs to be dismissed. + private static final int DISMISS_KEYGUARD_CONTINUE = 2; // Keyguard has been dismissed. + int mDismissKeyguard = DISMISS_KEYGUARD_NONE; + + /** The window that is currently dismissing the keyguard. Dismissing the keyguard must only + * be done once per window. */ + private WindowState mWinDismissingKeyguard; + boolean mShowingLockscreen; boolean mShowingDream; boolean mDreamingLockscreen; @@ -2921,6 +2931,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** {@inheritDoc} */ + @Override public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) { mTopFullscreenOpaqueWindowState = null; mForceStatusBar = false; @@ -2928,12 +2939,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { mHideLockScreen = false; mAllowLockscreenWhenOn = false; - mDismissKeyguard = false; + mDismissKeyguard = DISMISS_KEYGUARD_NONE; mShowingLockscreen = false; mShowingDream = false; } /** {@inheritDoc} */ + @Override public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs) { if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw=" @@ -2971,9 +2983,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { mHideLockScreen = true; mForceStatusBarFromKeyguard = false; } - if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0) { + if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0 + && mDismissKeyguard == DISMISS_KEYGUARD_NONE) { if (DEBUG_LAYOUT) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win); - mDismissKeyguard = true; + mDismissKeyguard = mWinDismissingKeyguard == win ? + DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START; + mWinDismissingKeyguard = win; mForceStatusBarFromKeyguard = false; } if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) { @@ -2984,6 +2999,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** {@inheritDoc} */ + @Override public int finishPostLayoutPolicyLw() { int changes = 0; boolean topIsFullscreen = false; @@ -3023,7 +3039,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mStatusBar.hideLw(true)) { changes |= FINISH_LAYOUT_REDO_LAYOUT; - mHandler.post(new Runnable() { public void run() { + mHandler.post(new Runnable() { + @Override + public void run() { try { IStatusBarService statusbar = getStatusBarService(); if (statusbar != null) { @@ -3051,7 +3069,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mKeyguard != null) { if (localLOGV) Log.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard=" + mHideLockScreen); - if (mDismissKeyguard && !mKeyguardMediator.isSecure()) { + if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardMediator.isSecure()) { if (mKeyguard.hideLw(true)) { changes |= FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG @@ -3059,6 +3077,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if (mKeyguardMediator.isShowing()) { mHandler.post(new Runnable() { + @Override public void run() { mKeyguardMediator.keyguardDone(false, false); } @@ -3071,7 +3090,25 @@ public class PhoneWindowManager implements WindowManagerPolicy { | FINISH_LAYOUT_REDO_WALLPAPER; } mKeyguardMediator.setHidden(true); + } else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) { + // This is the case of keyguard isSecure() and not mHideLockScreen. + if (mDismissKeyguard == DISMISS_KEYGUARD_START) { + // Only launch the next keyguard unlock window once per window. + if (mKeyguard.showLw(true)) { + changes |= FINISH_LAYOUT_REDO_LAYOUT + | FINISH_LAYOUT_REDO_CONFIG + | FINISH_LAYOUT_REDO_WALLPAPER; + } + mKeyguardMediator.setHidden(false); + mHandler.post(new Runnable() { + @Override + public void run() { + mKeyguardMediator.dismiss(); + } + }); + } } else { + mWinDismissingKeyguard = null; if (mKeyguard.showLw(true)) { changes |= FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG @@ -4549,6 +4586,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { pw.print(" mForceStatusBarFromKeyguard="); pw.println(mForceStatusBarFromKeyguard); pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard); + pw.print(" mWinDismissingKeyguard="); pw.print(mWinDismissingKeyguard); pw.print(" mHomePressed="); pw.println(mHomePressed); pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn); pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index a182ec39205e..748e0dfdcd22 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -48,7 +48,6 @@ import android.view.View; import android.view.WindowManager; import android.view.animation.AnimationUtils; import android.widget.RemoteViews.OnClickHandler; -import android.widget.TextView; import com.android.internal.R; import com.android.internal.policy.impl.keyguard.KeyguardSecurityModel.SecurityMode; @@ -66,11 +65,6 @@ public class KeyguardHostView extends KeyguardViewBase { // also referenced in SecuritySettings.java static final int APPWIDGET_HOST_ID = 0x4B455947; - // transport control states - private static final int TRANSPORT_GONE = 0; - private static final int TRANSPORT_INVISIBLE = 1; - private static final int TRANSPORT_VISIBLE = 2; - private AppWidgetHost mAppWidgetHost; private KeyguardWidgetPager mAppWidgetContainer; private KeyguardSecurityViewFlipper mSecurityViewContainer; @@ -90,7 +84,6 @@ public class KeyguardHostView extends KeyguardViewBase { private KeyguardViewStateManager mViewStateManager; private Rect mTempRect = new Rect(); - private int mTransportState = TRANSPORT_GONE; /*package*/ interface TransportCallback { void onListenerDetached(); @@ -144,7 +137,7 @@ public class KeyguardHostView extends KeyguardViewBase { private int getWidgetPosition(int id) { final int children = mAppWidgetContainer.getChildCount(); for (int i = 0; i < children; i++) { - if (mAppWidgetContainer.getChildAt(i).getId() == id) { + if (mAppWidgetContainer.getWidgetPageAt(i).getContent().getId() == id) { return i; } } @@ -864,7 +857,8 @@ public class KeyguardHostView extends KeyguardViewBase { @Override LockPatternUtils getLockPatternUtils() { return mLockPatternUtils; - }}; + } + }; private void addDefaultWidgets() { LayoutInflater inflater = LayoutInflater.from(mContext); @@ -906,6 +900,33 @@ public class KeyguardHostView extends KeyguardViewBase { initializeTransportControl(); } + private void removeTransportFromWidgetPager() { + int page = getWidgetPosition(R.id.keyguard_transport_control); + if (page != -1) { + mAppWidgetContainer.removeWidget(mTransportControl); + + // XXX keep view attached so we still get show/hide events from AudioManager + KeyguardHostView.this.addView(mTransportControl); + mTransportControl.setVisibility(View.GONE); + mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_GONE); + mTransportControl.post(mSwitchPageRunnable); + } + } + + private void addTransportToWidgetPager() { + if (getWidgetPosition(R.id.keyguard_transport_control) == -1) { + KeyguardHostView.this.removeView(mTransportControl); + // insert to left of camera if it exists, otherwise after right-most widget + int lastWidget = mAppWidgetContainer.getChildCount() - 1; + int position = 0; // handle no widget case + if (lastWidget >= 0) { + position = isCameraPage(lastWidget) ? lastWidget : lastWidget + 1; + } + mAppWidgetContainer.addWidget(mTransportControl, position); + mTransportControl.setVisibility(View.VISIBLE); + } + } + private void initializeTransportControl() { mTransportControl = (KeyguardTransportControlView) findViewById(R.id.keyguard_transport_control); @@ -917,24 +938,14 @@ public class KeyguardHostView extends KeyguardViewBase { mTransportControl.setKeyguardCallback(new TransportCallback() { @Override public void onListenerDetached() { - int page = getWidgetPosition(R.id.keyguard_transport_control); - if (page != -1) { - mAppWidgetContainer.removeView(mTransportControl); - // XXX keep view attached so we still get show/hide events from AudioManager - KeyguardHostView.this.addView(mTransportControl); - mTransportControl.setVisibility(View.GONE); - mTransportState = TRANSPORT_GONE; - mTransportControl.post(mSwitchPageRunnable); - } + removeTransportFromWidgetPager(); + mTransportControl.post(mSwitchPageRunnable); } @Override public void onListenerAttached() { - if (getWidgetPosition(R.id.keyguard_transport_control) == -1) { - KeyguardHostView.this.removeView(mTransportControl); - mAppWidgetContainer.addView(mTransportControl, 0); - mTransportControl.setVisibility(View.VISIBLE); - } + // Transport will be added when playstate changes... + mTransportControl.post(mSwitchPageRunnable); } @Override @@ -1027,7 +1038,7 @@ public class KeyguardHostView extends KeyguardViewBase { saveStickyWidgetIndex(); Parcelable superState = super.onSaveInstanceState(); SavedState ss = new SavedState(superState); - ss.transportState = mTransportState; + ss.transportState = mViewStateManager.getTransportState(); return ss; } @@ -1040,7 +1051,7 @@ public class KeyguardHostView extends KeyguardViewBase { } SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); - mTransportState = ss.transportState; + mViewStateManager.setTransportState(ss.transportState); post(mSwitchPageRunnable); } @@ -1054,12 +1065,14 @@ public class KeyguardHostView extends KeyguardViewBase { } private void showAppropriateWidgetPage() { - boolean isMusicPlaying = - mTransportControl.isMusicPlaying() || mTransportState == TRANSPORT_VISIBLE; + int state = mViewStateManager.getTransportState(); + boolean isMusicPlaying = mTransportControl.isMusicPlaying() + || state == KeyguardViewStateManager.TRANSPORT_VISIBLE; if (isMusicPlaying) { - mTransportState = TRANSPORT_VISIBLE; - } else if (mTransportState == TRANSPORT_VISIBLE) { - mTransportState = TRANSPORT_INVISIBLE; + mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_VISIBLE); + addTransportToWidgetPager(); + } else if (state == KeyguardViewStateManager.TRANSPORT_VISIBLE) { + mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_INVISIBLE); } int pageToShow = getAppropriateWidgetPage(isMusicPlaying); mAppWidgetContainer.setCurrentPage(pageToShow); @@ -1081,7 +1094,7 @@ public class KeyguardHostView extends KeyguardViewBase { // if music playing, show transport if (isMusicPlaying) { if (DEBUG) Log.d(TAG, "Music playing, show transport"); - return mAppWidgetContainer.indexOfChild(mTransportControl); + return mAppWidgetContainer.getWidgetPageIndex(mTransportControl); } // if we have a valid sticky widget, show it @@ -1205,4 +1218,10 @@ public class KeyguardHostView extends KeyguardViewBase { return false; } + /** + * Dismisses the keyguard by going to the next screen or making it gone. + */ + public void dismiss() { + showNextSecurityScreenOrFinish(false); + } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardTransportControlView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardTransportControlView.java index 89f220a0cf2d..d2846026324a 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardTransportControlView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardTransportControlView.java @@ -40,6 +40,7 @@ import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -49,14 +50,13 @@ import java.lang.ref.WeakReference; /** * This is the widget responsible for showing music controls in keyguard. */ -public class KeyguardTransportControlView extends KeyguardWidgetFrame implements OnClickListener { +public class KeyguardTransportControlView extends FrameLayout implements OnClickListener { private static final int MSG_UPDATE_STATE = 100; private static final int MSG_SET_METADATA = 101; private static final int MSG_SET_TRANSPORT_CONTROLS = 102; private static final int MSG_SET_ARTWORK = 103; 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 = false; protected static final String TAG = "TransportControlView"; @@ -260,14 +260,6 @@ public class KeyguardTransportControlView extends KeyguardWidgetFrame implements mAttached = false; } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); -// int dim = Math.min(MAXDIM, Math.max(getWidth(), getHeight())); -// Log.v(TAG, "setting max bitmap size: " + dim + "x" + dim); -// mAudioManager.remoteControlDisplayUsesBitmapSize(mIRCD, dim, dim); - } - class Metadata { private String artist; private String trackTitle; diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java index 9fa14f5f3692..b224c0898f4d 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java @@ -65,6 +65,7 @@ public class KeyguardViewManager { private FrameLayout mKeyguardHost; private KeyguardHostView mKeyguardView; + private boolean mScreenOn = false; private LockPatternUtils mLockPatternUtils; public interface ShowListener { @@ -302,6 +303,7 @@ public class KeyguardViewManager { public synchronized void onScreenTurnedOff() { if (DEBUG) Log.d(TAG, "onScreenTurnedOff()"); + mScreenOn = false; if (mKeyguardView != null) { mKeyguardView.onScreenTurnedOff(); } @@ -310,6 +312,7 @@ public class KeyguardViewManager { public synchronized void onScreenTurnedOn( final KeyguardViewManager.ShowListener showListener) { if (DEBUG) Log.d(TAG, "onScreenTurnedOn()"); + mScreenOn = true; if (mKeyguardView != null) { mKeyguardView.onScreenTurnedOn(); @@ -398,6 +401,15 @@ public class KeyguardViewManager { } /** + * Dismisses the keyguard by going to the next screen or making it gone. + */ + public synchronized void dismiss() { + if (mScreenOn) { + mKeyguardView.dismiss(); + } + } + + /** * @return Whether the keyguard is showing */ public synchronized boolean isShowing() { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java index bc12e96e475f..53cbb39fd832 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java @@ -813,9 +813,7 @@ public class KeyguardViewMediator { } /** - * Enable the keyguard if the settings are appropriate. Return true if all - * work that will happen is done; returns false if the caller can wait for - * the keyguard to be shown. + * Enable the keyguard if the settings are appropriate. */ private void doKeyguardLocked(Bundle options) { // if another app is disabling us, don't show @@ -867,6 +865,13 @@ public class KeyguardViewMediator { } /** + * Dismiss the keyguard through the security layers. + */ + public void dismiss() { + mKeyguardViewManager.dismiss(); + } + + /** * Send message to keyguard telling it to reset its state. * @param options options about how to show the keyguard * @see #handleReset() diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index eed810486473..c89e8800f6cd 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -32,6 +32,13 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle private static final int SCREEN_ON_RING_HINT_DELAY = 300; Handler mMainQueue = new Handler(Looper.myLooper()); + // transport control states + static final int TRANSPORT_GONE = 0; + static final int TRANSPORT_INVISIBLE = 1; + static final int TRANSPORT_VISIBLE = 2; + + private int mTransportState = TRANSPORT_GONE; + int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE; // Paged view state @@ -222,4 +229,12 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION); } + + public void setTransportState(int state) { + mTransportState = state; + } + + public int getTransportState() { + return mTransportState; + } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index bddd6edc7586..667b2d63b262 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -27,6 +27,7 @@ import android.content.res.Resources; import android.os.Handler; import android.os.HandlerThread; import android.util.AttributeSet; +import android.util.Slog; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; @@ -62,6 +63,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit boolean showHintsAfterLayout = false; private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000; + private static final String TAG = "KeyguardWidgetPager"; private int mPage = 0; private Callbacks mCallbacks; @@ -245,25 +247,40 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } } - // We enforce that all children are KeyguardWidgetFrames + /** + * Use addWidget() instead. + * @deprecated + */ @Override public void addView(View child, int index) { enforceKeyguardWidgetFrame(child); super.addView(child, index); } + /** + * Use addWidget() instead. + * @deprecated + */ @Override public void addView(View child, int width, int height) { enforceKeyguardWidgetFrame(child); super.addView(child, width, height); } + /** + * Use addWidget() instead. + * @deprecated + */ @Override public void addView(View child, LayoutParams params) { enforceKeyguardWidgetFrame(child); super.addView(child, params); } + /** + * Use addWidget() instead. + * @deprecated + */ @Override public void addView(View child, int index, LayoutParams params) { enforceKeyguardWidgetFrame(child); @@ -440,8 +457,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit return true; } boolean isMusicWidgetVisible() { - // TODO: Make proper test once we have music in the list - return false; + return mViewStateManager.getTransportState() != KeyguardViewStateManager.TRANSPORT_GONE; } boolean isCameraWidgetVisible() { return mCameraWidgetEnabled; @@ -638,4 +654,30 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } return false; } + + public void removeWidget(View view) { + if (view instanceof KeyguardWidgetFrame) { + removeView(view); + } else { + // Assume view was wrapped by a KeyguardWidgetFrame in KeyguardWidgetPager#addWidget(). + // This supports legacy hard-coded "widgets" like KeyguardTransportControlView. + int pos = getWidgetPageIndex(view); + if (pos != -1) { + KeyguardWidgetFrame frame = (KeyguardWidgetFrame) getChildAt(pos); + frame.removeView(view); + removeView(frame); + } else { + Slog.w(TAG, "removeWidget() can't find:" + view); + } + } + } + + public int getWidgetPageIndex(View view) { + if (view instanceof KeyguardWidgetFrame) { + return indexOfChild(view); + } else { + // View was wrapped by a KeyguardWidgetFrame by KeyguardWidgetPager#addWidget() + return indexOfChild((KeyguardWidgetFrame)view.getParent()); + } + } } diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index c195f4578d8b..0a9c3e5bfdcd 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -282,7 +282,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0; if (WindowManagerService.localLOGV) Slog.v( TAG, "Window " + this + " client=" + c.asBinder() - + " token=" + token + " (" + mAttrs.token + ")"); + + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a); try { c.asBinder().linkToDeath(deathRecipient, 0); } catch (RemoteException e) { |