diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2014-08-22 16:09:37 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2014-08-25 11:38:02 -0700 |
commit | 424418bb50ccf5d9270650b70cc51f423da51a65 (patch) | |
tree | 23c7b40d02e7b4dfda6395b7b30ea6305a27dd1a /src/com/android/launcher3 | |
parent | dec12adb6dba114ad2feedce3a9f3ce0c178fc04 (diff) | |
download | android_packages_apps_Trebuchet-424418bb50ccf5d9270650b70cc51f423da51a65.tar.gz android_packages_apps_Trebuchet-424418bb50ccf5d9270650b70cc51f423da51a65.tar.bz2 android_packages_apps_Trebuchet-424418bb50ccf5d9270650b70cc51f423da51a65.zip |
Updating clings, removing ununsed clings
issue: 16127412
Change-Id: I1d18515765100ff10d33439b3ac39ebfc5da35c7
Diffstat (limited to 'src/com/android/launcher3')
-rw-r--r-- | src/com/android/launcher3/AppsCustomizePagedView.java | 7 | ||||
-rw-r--r-- | src/com/android/launcher3/ClearCircleLayout.java | 118 | ||||
-rw-r--r-- | src/com/android/launcher3/Cling.java | 571 | ||||
-rw-r--r-- | src/com/android/launcher3/DragLayer.java | 7 | ||||
-rw-r--r-- | src/com/android/launcher3/Folder.java | 11 | ||||
-rw-r--r-- | src/com/android/launcher3/HideFromAccessibilityHelper.java | 114 | ||||
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 43 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherClings.java | 522 | ||||
-rw-r--r-- | src/com/android/launcher3/Workspace.java | 14 |
9 files changed, 293 insertions, 1114 deletions
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java index 9f9c34bf4..03e1e5642 100644 --- a/src/com/android/launcher3/AppsCustomizePagedView.java +++ b/src/com/android/launcher3/AppsCustomizePagedView.java @@ -170,11 +170,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen private ArrayList<AppInfo> mApps; private ArrayList<Object> mWidgets; - // Cling - private boolean mHasShownAllAppsCling; - private int mClingFocusedX; - private int mClingFocusedY; - // Caching private IconCache mIconCache; @@ -229,8 +224,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0); mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2); mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2); - mClingFocusedX = a.getInt(R.styleable.AppsCustomizePagedView_clingFocusedX, 0); - mClingFocusedY = a.getInt(R.styleable.AppsCustomizePagedView_clingFocusedY, 0); a.recycle(); mWidgetSpacingLayout = new PagedViewCellLayout(getContext()); diff --git a/src/com/android/launcher3/ClearCircleLayout.java b/src/com/android/launcher3/ClearCircleLayout.java new file mode 100644 index 000000000..e48c84eef --- /dev/null +++ b/src/com/android/launcher3/ClearCircleLayout.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.View; + +public class ClearCircleLayout extends View { + + private static final String HOLE_LOCATION_PAGE_INDICATOR = "page_indicator"; + private static final String HOLE_LOCATION_CENTER_SCREEN = "center_screen"; + + private static final int BACKGROUND_COLOR = 0x80000000; + private static float MIGRATION_WORKSPACE_INNER_CIRCLE_RADIUS_DPS = 42; + private static float MIGRATION_WORKSPACE_OUTER_CIRCLE_RADIUS_DPS = 46; + + private final String mHoleLocation; + private final Paint mErasePaint; + private final Paint mBorderPaint; + + private Launcher mLauncher; + private Point mHoleCenter; + private DisplayMetrics mMetrics; + + public ClearCircleLayout(Context context, AttributeSet attrs) { + super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ClearCircleLayout); + mHoleLocation = a.getString(R.styleable.ClearCircleLayout_holeLocation); + a.recycle(); + + mErasePaint = new Paint(); + mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); + mErasePaint.setColor(0xFFFFFF); + mErasePaint.setAlpha(0); + mErasePaint.setAntiAlias(true); + + mBorderPaint = new Paint(); + mBorderPaint.setColor(0xFFFFFFFF); + mBorderPaint.setAntiAlias(true); + } + + void initHole(Launcher launcher) { + mLauncher = launcher; + mMetrics = new DisplayMetrics(); + launcher.getWindowManager().getDefaultDisplay().getMetrics(mMetrics); + + if (mHoleLocation.endsWith(HOLE_LOCATION_PAGE_INDICATOR)) { + LauncherAppState app = LauncherAppState.getInstance(); + DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); + + Rect indicator = grid.getWorkspacePageIndicatorBounds(new Rect()); + mHoleCenter = new Point(indicator.centerX(), indicator.centerY()); + } else if (mHoleLocation.endsWith(HOLE_LOCATION_CENTER_SCREEN)) { + mHoleCenter = new Point(mMetrics.widthPixels / 2, mMetrics.heightPixels / 2); + } + } + + @Override + protected void dispatchDraw(Canvas canvas) { + if (mHoleCenter == null) { + canvas.drawColor(BACKGROUND_COLOR); + } else { + drawHole(canvas); + } + + super.dispatchDraw(canvas); + } + + private void drawHole(Canvas canvas) { + // Initialize the draw buffer (to allow punching through) + Bitmap eraseBg = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), + Bitmap.Config.ARGB_8888); + Canvas eraseCanvas = new Canvas(eraseBg); + eraseCanvas.drawColor(BACKGROUND_COLOR); + + Rect insets = mLauncher.getDragLayer().getInsets(); + float x = mHoleCenter.x - insets.left; + float y = mHoleCenter.y - insets.top; + // Draw the outer circle + eraseCanvas.drawCircle(x, y, + DynamicGrid.pxFromDp(MIGRATION_WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, mMetrics), + mBorderPaint); + + // Draw the inner circle + eraseCanvas.drawCircle(x, y, + DynamicGrid.pxFromDp(MIGRATION_WORKSPACE_INNER_CIRCLE_RADIUS_DPS, mMetrics), + mErasePaint); + + canvas.drawBitmap(eraseBg, 0, 0, null); + eraseCanvas.setBitmap(null); + eraseBg.recycle(); + } +} diff --git a/src/com/android/launcher3/Cling.java b/src/com/android/launcher3/Cling.java deleted file mode 100644 index a6139ccbc..000000000 --- a/src/com/android/launcher3/Cling.java +++ /dev/null @@ -1,571 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.*; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.view.FocusFinder; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.AccelerateInterpolator; -import android.widget.FrameLayout; -import android.widget.TextView; - -public class Cling extends FrameLayout implements Insettable, View.OnClickListener, - View.OnLongClickListener, View.OnTouchListener { - - private static String FIRST_RUN_PORTRAIT = "first_run_portrait"; - private static String FIRST_RUN_LANDSCAPE = "first_run_landscape"; - - private static String WORKSPACE_PORTRAIT = "workspace_portrait"; - private static String WORKSPACE_LANDSCAPE = "workspace_landscape"; - private static String WORKSPACE_LARGE = "workspace_large"; - private static String WORKSPACE_CUSTOM = "workspace_custom"; - - private static String MIGRATION_PORTRAIT = "migration_portrait"; - private static String MIGRATION_LANDSCAPE = "migration_landscape"; - - private static String MIGRATION_WORKSPACE_PORTRAIT = "migration_workspace_portrait"; - private static String MIGRATION_WORKSPACE_LARGE_PORTRAIT = "migration_workspace_large_portrait"; - private static String MIGRATION_WORKSPACE_LANDSCAPE = "migration_workspace_landscape"; - - private static String FOLDER_PORTRAIT = "folder_portrait"; - private static String FOLDER_LANDSCAPE = "folder_landscape"; - private static String FOLDER_LARGE = "folder_large"; - - private static float FIRST_RUN_CIRCLE_BUFFER_DPS = 60; - private static float FIRST_RUN_MAX_CIRCLE_RADIUS_DPS = 180; - private static float WORKSPACE_INNER_CIRCLE_RADIUS_DPS = 50; - private static float WORKSPACE_OUTER_CIRCLE_RADIUS_DPS = 60; - private static float WORKSPACE_CIRCLE_Y_OFFSET_DPS = 30; - private static float MIGRATION_WORKSPACE_INNER_CIRCLE_RADIUS_DPS = 42; - private static float MIGRATION_WORKSPACE_OUTER_CIRCLE_RADIUS_DPS = 46; - - private Launcher mLauncher; - private boolean mIsInitialized; - private String mDrawIdentifier; - private Drawable mBackground; - - private int[] mTouchDownPt = new int[2]; - - private Drawable mFocusedHotseatApp; - private ComponentName mFocusedHotseatAppComponent; - private Rect mFocusedHotseatAppBounds; - - private Paint mErasePaint; - private Paint mBorderPaint; - private Paint mBubblePaint; - private Paint mDotPaint; - - private View mScrimView; - private int mBackgroundColor; - - private final Rect mInsets = new Rect(); - - public Cling(Context context) { - this(context, null, 0); - } - - public Cling(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public Cling(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Cling, defStyle, 0); - mDrawIdentifier = a.getString(R.styleable.Cling_drawIdentifier); - a.recycle(); - - setClickable(true); - - } - - void init(Launcher l, View scrim) { - if (!mIsInitialized) { - mLauncher = l; - mScrimView = scrim; - mBackgroundColor = 0xcc000000; - setOnLongClickListener(this); - setOnClickListener(this); - setOnTouchListener(this); - - mErasePaint = new Paint(); - mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); - mErasePaint.setColor(0xFFFFFF); - mErasePaint.setAlpha(0); - mErasePaint.setAntiAlias(true); - - mBorderPaint = new Paint(); - mBorderPaint.setColor(0xFFFFFFFF); - mBorderPaint.setAntiAlias(true); - - int circleColor = getResources().getColor( - R.color.first_run_cling_circle_background_color); - mBubblePaint = new Paint(); - mBubblePaint.setColor(circleColor); - mBubblePaint.setAntiAlias(true); - - mDotPaint = new Paint(); - mDotPaint.setColor(0x72BBED); - mDotPaint.setAntiAlias(true); - - mIsInitialized = true; - } - } - - void setFocusedHotseatApp(int drawableId, int appRank, ComponentName cn, String title, - String description) { - // Get the app to draw - Resources r = getResources(); - int appIconId = drawableId; - Hotseat hotseat = mLauncher.getHotseat(); - // Skip the focused app in the large layouts - if (!mDrawIdentifier.equals(WORKSPACE_LARGE) && - hotseat != null && appIconId > -1 && appRank > -1 && !title.isEmpty() && - !description.isEmpty()) { - // Set the app bounds - int x = hotseat.getCellXFromOrder(appRank); - int y = hotseat.getCellYFromOrder(appRank); - Rect pos = hotseat.getCellCoordinates(x, y); - LauncherAppState app = LauncherAppState.getInstance(); - DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); - mFocusedHotseatApp = getResources().getDrawable(appIconId); - mFocusedHotseatAppComponent = cn; - mFocusedHotseatAppBounds = new Rect(pos.left, pos.top, - pos.left + Utilities.sIconTextureWidth, - pos.top + Utilities.sIconTextureHeight); - Utilities.scaleRectAboutCenter(mFocusedHotseatAppBounds, - ((float) grid.hotseatIconSizePx / grid.iconSizePx)); - - // Set the title - TextView v = (TextView) findViewById(R.id.focused_hotseat_app_title); - if (v != null) { - v.setText(title); - } - - // Set the description - v = (TextView) findViewById(R.id.focused_hotseat_app_description); - if (v != null) { - v.setText(description); - } - - // Show the bubble - View bubble = findViewById(R.id.focused_hotseat_app_bubble); - bubble.setVisibility(View.VISIBLE); - } - } - - void setOpenFolderRect(Rect r) { - if (mDrawIdentifier.equals(FOLDER_LANDSCAPE) || - mDrawIdentifier.equals(FOLDER_LARGE)) { - ViewGroup vg = (ViewGroup) findViewById(R.id.folder_bubble); - ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) vg.getLayoutParams(); - lp.topMargin = r.top - mInsets.bottom; - lp.leftMargin = r.right; - vg.setLayoutDirection(View.LAYOUT_DIRECTION_LTR); - vg.requestLayout(); - } - } - - void updateMigrationWorkspaceBubblePosition() { - DisplayMetrics metrics = new DisplayMetrics(); - mLauncher.getWindowManager().getDefaultDisplay().getMetrics(metrics); - - // Get the page indicator bounds - LauncherAppState app = LauncherAppState.getInstance(); - DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); - Rect pageIndicatorBounds = grid.getWorkspacePageIndicatorBounds(mInsets); - - if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT)) { - View bubble = findViewById(R.id.migration_workspace_cling_bubble); - ViewGroup.MarginLayoutParams lp = - (ViewGroup.MarginLayoutParams) bubble.getLayoutParams(); - lp.bottomMargin = grid.heightPx - pageIndicatorBounds.top; - bubble.requestLayout(); - } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT)) { - View bubble = findViewById(R.id.content); - ViewGroup.MarginLayoutParams lp = - (ViewGroup.MarginLayoutParams) bubble.getLayoutParams(); - lp.bottomMargin = grid.heightPx - pageIndicatorBounds.top; - bubble.requestLayout(); - } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) { - View bubble = findViewById(R.id.content); - ViewGroup.MarginLayoutParams lp = - (ViewGroup.MarginLayoutParams) bubble.getLayoutParams(); - if (grid.isLayoutRtl) { - lp.leftMargin = pageIndicatorBounds.right; - } else { - lp.rightMargin = (grid.widthPx - pageIndicatorBounds.left); - } - bubble.requestLayout(); - } - } - - void updateWorkspaceBubblePosition() { - DisplayMetrics metrics = new DisplayMetrics(); - mLauncher.getWindowManager().getDefaultDisplay().getMetrics(metrics); - - // Get the cut-out bounds - LauncherAppState app = LauncherAppState.getInstance(); - DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); - Rect cutOutBounds = getWorkspaceCutOutBounds(metrics); - - if (mDrawIdentifier.equals(WORKSPACE_LARGE)) { - View bubble = findViewById(R.id.workspace_cling_bubble); - ViewGroup.MarginLayoutParams lp = - (ViewGroup.MarginLayoutParams) bubble.getLayoutParams(); - lp.bottomMargin = grid.heightPx - cutOutBounds.top - mInsets.bottom; - bubble.requestLayout(); - } - } - - private Rect getWorkspaceCutOutBounds(DisplayMetrics metrics) { - int halfWidth = metrics.widthPixels / 2; - int halfHeight = metrics.heightPixels / 2; - int yOffset = DynamicGrid.pxFromDp(WORKSPACE_CIRCLE_Y_OFFSET_DPS, metrics); - if (mDrawIdentifier.equals(WORKSPACE_LARGE)) { - yOffset = 0; - } - int radius = DynamicGrid.pxFromDp(WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, metrics); - return new Rect(halfWidth - radius, halfHeight - yOffset - radius, halfWidth + radius, - halfHeight - yOffset + radius); - } - - void show(boolean animate, int duration) { - setVisibility(View.VISIBLE); - setLayerType(View.LAYER_TYPE_HARDWARE, null); - if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) || - mDrawIdentifier.equals(WORKSPACE_LARGE) || - mDrawIdentifier.equals(WORKSPACE_CUSTOM) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) { - View content = getContent(); - content.setAlpha(0f); - content.animate() - .alpha(1f) - .setDuration(duration) - .setListener(null) - .start(); - setAlpha(1f); - } else { - if (animate) { - buildLayer(); - setAlpha(0f); - animate() - .alpha(1f) - .setInterpolator(new AccelerateInterpolator()) - .setDuration(duration) - .setListener(null) - .start(); - } else { - setAlpha(1f); - } - } - - // Show the scrim if necessary - if (mScrimView != null) { - mScrimView.setVisibility(View.VISIBLE); - mScrimView.setAlpha(0f); - mScrimView.animate() - .alpha(1f) - .setDuration(duration) - .setListener(null) - .start(); - } - - setFocusableInTouchMode(true); - post(new Runnable() { - public void run() { - setFocusable(true); - requestFocus(); - } - }); - } - - void hide(final int duration, final Runnable postCb) { - if (mDrawIdentifier.equals(FIRST_RUN_PORTRAIT) || - mDrawIdentifier.equals(FIRST_RUN_LANDSCAPE) || - mDrawIdentifier.equals(MIGRATION_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_LANDSCAPE)) { - View content = getContent(); - content.animate() - .alpha(0f) - .setDuration(duration) - .setListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animation) { - // We are about to trigger the workspace cling, so don't do anything else - setVisibility(View.GONE); - postCb.run(); - }; - }) - .start(); - } else { - animate() - .alpha(0f) - .setDuration(duration) - .setListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animation) { - // We are about to trigger the workspace cling, so don't do anything else - setVisibility(View.GONE); - postCb.run(); - }; - }) - .start(); - } - - // Show the scrim if necessary - if (mScrimView != null) { - mScrimView.animate() - .alpha(0f) - .setDuration(duration) - .setListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animation) { - mScrimView.setVisibility(View.GONE); - }; - }) - .start(); - } - } - - void cleanup() { - mBackground = null; - mIsInitialized = false; - } - - void bringScrimToFront() { - if (mScrimView != null) { - mScrimView.bringToFront(); - } - } - - @Override - public void setInsets(Rect insets) { - mInsets.set(insets); - setPadding(insets.left, insets.top, insets.right, insets.bottom); - } - - View getContent() { - return findViewById(R.id.content); - } - - String getDrawIdentifier() { - return mDrawIdentifier; - } - - @Override - public View focusSearch(int direction) { - return this.focusSearch(this, direction); - } - - @Override - public View focusSearch(View focused, int direction) { - return FocusFinder.getInstance().findNextFocus(this, focused, direction); - } - - @Override - public boolean onHoverEvent(MotionEvent event) { - return (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) - || mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) - || mDrawIdentifier.equals(WORKSPACE_LARGE) - || mDrawIdentifier.equals(WORKSPACE_CUSTOM)); - } - - @Override - public boolean onTouchEvent(android.view.MotionEvent event) { - if (mDrawIdentifier.equals(FOLDER_PORTRAIT) || - mDrawIdentifier.equals(FOLDER_LANDSCAPE) || - mDrawIdentifier.equals(FOLDER_LARGE)) { - Folder f = mLauncher.getWorkspace().getOpenFolder(); - if (f != null) { - Rect r = new Rect(); - f.getHitRect(r); - if (r.contains((int) event.getX(), (int) event.getY())) { - return false; - } - } - } - return super.onTouchEvent(event); - }; - - @Override - public boolean onTouch(View v, MotionEvent ev) { - if (ev.getAction() == MotionEvent.ACTION_DOWN) { - mTouchDownPt[0] = (int) ev.getX(); - mTouchDownPt[1] = (int) ev.getY(); - } - return false; - } - - @Override - public void onClick(View v) { - if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) || - mDrawIdentifier.equals(WORKSPACE_LARGE)) { - if (mFocusedHotseatAppBounds != null && - mFocusedHotseatAppBounds.contains(mTouchDownPt[0], mTouchDownPt[1])) { - // Launch the activity that is being highlighted - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setComponent(mFocusedHotseatAppComponent); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - mLauncher.startActivity(intent, null); - mLauncher.getLauncherClings().dismissWorkspaceCling(this); - } - } - } - - @Override - public boolean onLongClick(View v) { - if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) || - mDrawIdentifier.equals(WORKSPACE_LARGE)) { - mLauncher.getLauncherClings().dismissWorkspaceCling(null); - return true; - } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) { - mLauncher.getLauncherClings().dismissMigrationWorkspaceCling(null); - return true; - } - return false; - } - - @Override - protected void dispatchDraw(Canvas canvas) { - if (mIsInitialized) { - canvas.save(); - - // Get the page indicator bounds - LauncherAppState app = LauncherAppState.getInstance(); - DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); - Rect pageIndicatorBounds = grid.getWorkspacePageIndicatorBounds(mInsets); - - // Get the background override if there is one - if (mBackground == null) { - if (mDrawIdentifier.equals(WORKSPACE_CUSTOM)) { - mBackground = getResources().getDrawable(R.drawable.bg_cling5); - } - } - // Draw the background - Bitmap eraseBg = null; - Canvas eraseCanvas = null; - if (mScrimView != null) { - // Skip drawing the background - mScrimView.setBackgroundColor(mBackgroundColor); - } else if (mBackground != null) { - mBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); - mBackground.draw(canvas); - } else if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) || - mDrawIdentifier.equals(WORKSPACE_LARGE) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) { - // Initialize the draw buffer (to allow punching through) - eraseBg = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), - Bitmap.Config.ARGB_8888); - eraseCanvas = new Canvas(eraseBg); - eraseCanvas.drawColor(mBackgroundColor); - } else { - canvas.drawColor(mBackgroundColor); - } - - // Draw everything else - DisplayMetrics metrics = new DisplayMetrics(); - mLauncher.getWindowManager().getDefaultDisplay().getMetrics(metrics); - float alpha = getAlpha(); - View content = getContent(); - if (content != null) { - alpha *= content.getAlpha(); - } - if (mDrawIdentifier.equals(FIRST_RUN_PORTRAIT) || - mDrawIdentifier.equals(FIRST_RUN_LANDSCAPE)) { - // Draw the circle - View bubbleContent = findViewById(R.id.bubble_content); - Rect bubbleRect = new Rect(); - bubbleContent.getGlobalVisibleRect(bubbleRect); - mBubblePaint.setAlpha((int) (255 * alpha)); - float buffer = DynamicGrid.pxFromDp(FIRST_RUN_CIRCLE_BUFFER_DPS, metrics); - float maxRadius = DynamicGrid.pxFromDp(FIRST_RUN_MAX_CIRCLE_RADIUS_DPS, metrics); - float radius = Math.min(maxRadius, (bubbleContent.getMeasuredWidth() + buffer) / 2); - canvas.drawCircle(metrics.widthPixels / 2, - bubbleRect.centerY(), radius, - mBubblePaint); - } else if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) || - mDrawIdentifier.equals(WORKSPACE_LARGE)) { - Rect cutOutBounds = getWorkspaceCutOutBounds(metrics); - // Draw the outer circle - mErasePaint.setAlpha(128); - eraseCanvas.drawCircle(cutOutBounds.centerX(), cutOutBounds.centerY(), - DynamicGrid.pxFromDp(WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, metrics), - mErasePaint); - // Draw the inner circle - mErasePaint.setAlpha(0); - eraseCanvas.drawCircle(cutOutBounds.centerX(), cutOutBounds.centerY(), - DynamicGrid.pxFromDp(WORKSPACE_INNER_CIRCLE_RADIUS_DPS, metrics), - mErasePaint); - canvas.drawBitmap(eraseBg, 0, 0, null); - eraseCanvas.setBitmap(null); - eraseBg = null; - - // Draw the focused hotseat app icon - if (mFocusedHotseatAppBounds != null && mFocusedHotseatApp != null) { - mFocusedHotseatApp.setBounds(mFocusedHotseatAppBounds.left, - mFocusedHotseatAppBounds.top, mFocusedHotseatAppBounds.right, - mFocusedHotseatAppBounds.bottom); - mFocusedHotseatApp.setAlpha((int) (255 * alpha)); - mFocusedHotseatApp.draw(canvas); - } - } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT) || - mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) { - int offset = DynamicGrid.pxFromDp(WORKSPACE_CIRCLE_Y_OFFSET_DPS, metrics); - // Draw the outer circle - eraseCanvas.drawCircle(pageIndicatorBounds.centerX(), - pageIndicatorBounds.centerY(), - DynamicGrid.pxFromDp(MIGRATION_WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, metrics), - mBorderPaint); - // Draw the inner circle - mErasePaint.setAlpha(0); - eraseCanvas.drawCircle(pageIndicatorBounds.centerX(), - pageIndicatorBounds.centerY(), - DynamicGrid.pxFromDp(MIGRATION_WORKSPACE_INNER_CIRCLE_RADIUS_DPS, metrics), - mErasePaint); - canvas.drawBitmap(eraseBg, 0, 0, null); - eraseCanvas.setBitmap(null); - eraseBg = null; - } - canvas.restore(); - } - - // Draw the rest of the cling - super.dispatchDraw(canvas); - }; -} diff --git a/src/com/android/launcher3/DragLayer.java b/src/com/android/launcher3/DragLayer.java index 79cb1f9c4..a8a61ea89 100644 --- a/src/com/android/launcher3/DragLayer.java +++ b/src/com/android/launcher3/DragLayer.java @@ -132,6 +132,10 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang return true; // I'll take it from here } + Rect getInsets() { + return mInsets; + } + @Override public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) { super.addView(child, index, params); @@ -200,8 +204,7 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang } Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); - if (currentFolder != null && !mLauncher.getLauncherClings().isFolderClingVisible() && - intercept) { + if (currentFolder != null && intercept) { if (currentFolder.isEditingName()) { if (!isEventOverFolderTextRegion(currentFolder, ev)) { currentFolder.dismissEditingName(); diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index f26f87c39..6bd4e0e2f 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -248,8 +248,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList return false; } - mLauncher.getLauncherClings().dismissFolderCling(null); - mLauncher.getWorkspace().beginDragShared(v, this); mCurrentDragInfo = item; @@ -553,15 +551,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList onCompleteRunnable.run(); } - // Only show cling if we are not in the middle of a drag - this would be quite jarring. - if (!mDragController.isDragging()) { - Cling cling = mLauncher.getLauncherClings().showFoldersCling(); - if (cling != null) { - cling.bringScrimToFront(); - bringToFront(); - cling.bringToFront(); - } - } setFocusOnFirstChild(); } }); diff --git a/src/com/android/launcher3/HideFromAccessibilityHelper.java b/src/com/android/launcher3/HideFromAccessibilityHelper.java deleted file mode 100644 index 75cbb1b1e..000000000 --- a/src/com/android/launcher3/HideFromAccessibilityHelper.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3; - -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.OnHierarchyChangeListener; - -import java.util.HashMap; - -public class HideFromAccessibilityHelper implements OnHierarchyChangeListener { - private HashMap<View, Integer> mPreviousValues; - boolean mHide; - boolean mOnlyAllApps; - - public HideFromAccessibilityHelper() { - mPreviousValues = new HashMap<View, Integer>(); - mHide = false; - } - - public void setImportantForAccessibilityToNo(View v, boolean onlyAllApps) { - mOnlyAllApps = onlyAllApps; - setImportantForAccessibilityToNoHelper(v); - mHide = true; - } - - private void setImportantForAccessibilityToNoHelper(View v) { - mPreviousValues.put(v, v.getImportantForAccessibility()); - v.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); - - // Call method on children recursively - if (v instanceof ViewGroup) { - ViewGroup vg = (ViewGroup) v; - vg.setOnHierarchyChangeListener(this); - for (int i = 0; i < vg.getChildCount(); i++) { - View child = vg.getChildAt(i); - - if (includeView(child)) { - setImportantForAccessibilityToNoHelper(child); - } - } - } - } - - public void restoreImportantForAccessibility(View v) { - if (mHide) { - restoreImportantForAccessibilityHelper(v); - } - mHide = false; - } - - private void restoreImportantForAccessibilityHelper(View v) { - Integer important = mPreviousValues.get(v); - v.setImportantForAccessibility(important); - mPreviousValues.remove(v); - - // Call method on children recursively - if (v instanceof ViewGroup) { - ViewGroup vg = (ViewGroup) v; - - // We assume if a class implements OnHierarchyChangeListener, it listens - // to changes to any of its children (happens to be the case in Launcher) - if (vg instanceof OnHierarchyChangeListener) { - vg.setOnHierarchyChangeListener((OnHierarchyChangeListener) vg); - } else { - vg.setOnHierarchyChangeListener(null); - } - for (int i = 0; i < vg.getChildCount(); i++) { - View child = vg.getChildAt(i); - if (includeView(child)) { - restoreImportantForAccessibilityHelper(child); - } - } - } - } - - public void onChildViewAdded(View parent, View child) { - if (mHide && includeView(child)) { - setImportantForAccessibilityToNoHelper(child); - } - } - - public void onChildViewRemoved(View parent, View child) { - if (mHide && includeView(child)) { - restoreImportantForAccessibilityHelper(child); - } - } - - private boolean includeView(View v) { - return !hasAncestorOfType(v, Cling.class) && - (!mOnlyAllApps || hasAncestorOfType(v, AppsCustomizeTabHost.class)); - } - - private boolean hasAncestorOfType(View v, Class c) { - return v != null && - (v.getClass().equals(c) || - (v.getParent() instanceof ViewGroup && - hasAncestorOfType((ViewGroup) v.getParent(), c))); - } -}
\ No newline at end of file diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 8a3ce2568..e134d1b4d 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -126,7 +126,6 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; - /** * Default launcher application. */ @@ -256,7 +255,6 @@ public class Launcher extends Activity private DragLayer mDragLayer; private DragController mDragController; private View mWeightWatcher; - private LauncherClings mLauncherClings; private AppWidgetManagerCompat mAppWidgetManager; private LauncherAppWidgetHost mAppWidgetHost; @@ -434,7 +432,6 @@ public class Launcher extends Activity mIconCache = app.getIconCache(); mIconCache.flushInvalidIcons(grid); mDragController = new DragController(this); - mLauncherClings = new LauncherClings(this); mInflater = getLayoutInflater(); mStats = new Stats(this); @@ -504,14 +501,13 @@ public class Launcher extends Activity // The two first run cling paths are mutually exclusive, if the launcher is preinstalled // on the device, then we always show the first run cling experience (or if there is no // launcher2). Otherwise, we prompt the user upon started for migration - if (mLauncherClings.shouldShowFirstRunOrMigrationClings()) { + LauncherClings launcherClings = new LauncherClings(this); + if (launcherClings.shouldShowFirstRunOrMigrationClings()) { if (mModel.canMigrateFromOldLauncherDb(this)) { - mLauncherClings.showMigrationCling(); + launcherClings.showMigrationCling(); } else { - mLauncherClings.showFirstRunCling(); + launcherClings.showLongPressCling(true); } - } else { - mLauncherClings.removeFirstRunAndMigrationClings(); } } @@ -1849,10 +1845,6 @@ public class Launcher extends Activity return mModel; } - public LauncherClings getLauncherClings() { - return mLauncherClings; - } - protected SharedPreferences getSharedPrefs() { return mSharedPrefs; } @@ -2977,9 +2969,6 @@ public class Launcher extends Activity folder.dismissEditingName(); } closeFolder(folder); - - // Dismiss the folder cling - mLauncherClings.dismissFolderCling(null); } } @@ -4757,7 +4746,7 @@ public class Launcher extends Activity * @param hint the hint to be displayed in the search bar. */ protected void onSearchBarHintChanged(String hint) { - mLauncherClings.updateSearchBarHint(hint); + } protected boolean isLauncherPreinstalled() { @@ -4808,28 +4797,6 @@ public class Launcher extends Activity return ""; } - public void dismissFirstRunCling(View v) { - mLauncherClings.dismissFirstRunCling(v); - } - public void dismissMigrationClingCopyApps(View v) { - mLauncherClings.dismissMigrationClingCopyApps(v); - } - public void dismissMigrationClingUseDefault(View v) { - mLauncherClings.dismissMigrationClingUseDefault(v); - } - public void dismissMigrationWorkspaceCling(View v) { - mLauncherClings.dismissMigrationWorkspaceCling(v); - } - public void dismissWorkspaceCling(View v) { - mLauncherClings.dismissWorkspaceCling(v); - } - public void dismissFolderCling(View v) { - mLauncherClings.dismissFolderCling(v); - } - public void markFolderClingDismissedIfNecessary() { - mLauncherClings.markFolderClingDismissedIfNecessary(); - } - /** * To be overridden by subclasses to indicate that there is an activity to launch * before showing the standard launcher experience. diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java index 00586bd4e..840fb52c3 100644 --- a/src/com/android/launcher3/LauncherClings.java +++ b/src/com/android/launcher3/LauncherClings.java @@ -18,31 +18,31 @@ package com.android.launcher3; import android.accounts.Account; import android.accounts.AccountManager; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.animation.ValueAnimator; import android.app.ActivityManager; -import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.graphics.Rect; import android.os.Bundle; import android.os.UserManager; import android.provider.Settings; +import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnLongClickListener; import android.view.ViewGroup; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.accessibility.AccessibilityManager; -import android.widget.TextView; -class LauncherClings { - private static final String FIRST_RUN_CLING_DISMISSED_KEY = "cling_gel.first_run.dismissed"; +class LauncherClings implements OnClickListener { private static final String MIGRATION_CLING_DISMISSED_KEY = "cling_gel.migration.dismissed"; - private static final String MIGRATION_WORKSPACE_CLING_DISMISSED_KEY = - "cling_gel.migration_workspace.dismissed"; private static final String WORKSPACE_CLING_DISMISSED_KEY = "cling_gel.workspace.dismissed"; - private static final String FOLDER_CLING_DISMISSED_KEY = "cling_gel.folder.dismissed"; + + private static final String ANIM_SLIDE_FROM_BOTTOM = "slide_from_bottom"; + private static final String ANIM_SLIDE_FROM_TOP = "slide_from_top"; private static final boolean DISABLE_CLINGS = false; @@ -54,294 +54,158 @@ class LauncherClings { private Launcher mLauncher; private LayoutInflater mInflater; - private HideFromAccessibilityHelper mHideFromAccessibilityHelper - = new HideFromAccessibilityHelper(); /** Ctor */ public LauncherClings(Launcher launcher) { mLauncher = launcher; - mInflater = mLauncher.getLayoutInflater(); + mInflater = LayoutInflater.from(new + ContextThemeWrapper(mLauncher, android.R.style.Theme_DeviceDefault)); } - /** Initializes a cling */ - private Cling initCling(int clingId, int scrimId, boolean animate, - boolean dimNavBarVisibilty) { - Cling cling = (Cling) mLauncher.findViewById(clingId); - View scrim = null; - if (scrimId > 0) { - scrim = mLauncher.findViewById(scrimId); - } - if (cling != null) { - cling.init(mLauncher, scrim); - cling.show(animate, SHOW_CLING_DURATION); - - if (dimNavBarVisibilty) { - cling.setSystemUiVisibility(cling.getSystemUiVisibility() | - View.SYSTEM_UI_FLAG_LOW_PROFILE); - } + @Override + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.cling_dismiss_migration_use_default) { + // Disable the migration cling + dismissMigrationCling(); + } else if (id == R.id.cling_dismiss_migration_copy_apps) { + // Copy the shortcuts from the old database + LauncherModel model = mLauncher.getModel(); + model.resetLoadedState(false, true); + model.startLoader(false, PagedView.INVALID_RESTORE_PAGE, + LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE + | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS); + // Set the flag to skip the folder cling + String spKey = LauncherAppState.getSharedPreferencesKey(); + SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putBoolean(Launcher.USER_HAS_MIGRATED, true); + editor.apply(); + // Disable the migration cling + dismissMigrationCling(); + } else if (id == R.id.cling_dismiss_longpress_info) { + dismissLongPressCling(); } - return cling; } - /** Returns whether the clings are enabled or should be shown */ - private boolean areClingsEnabled() { - if (DISABLE_CLINGS) { - return false; - } - - // disable clings when running in a test harness - if(ActivityManager.isRunningInTestHarness()) return false; + /** + * Shows the migration cling. + * + * This flow is mutually exclusive with showFirstRunCling, and only runs if this Launcher + * package was not preinstalled and there exists a db to migrate from. + */ + public void showMigrationCling() { + mLauncher.hideWorkspaceSearchAndHotseat(); - // Disable clings for accessibility when explore by touch is enabled - final AccessibilityManager a11yManager = (AccessibilityManager) mLauncher.getSystemService( - Launcher.ACCESSIBILITY_SERVICE); - if (a11yManager.isTouchExplorationEnabled()) { - return false; - } + ViewGroup root = (ViewGroup) mLauncher.findViewById(R.id.launcher); + View inflated = mInflater.inflate(R.layout.migration_cling, root); + inflated.findViewById(R.id.cling_dismiss_migration_copy_apps).setOnClickListener(this); + inflated.findViewById(R.id.cling_dismiss_migration_use_default).setOnClickListener(this); + } - // Restricted secondary users (child mode) will potentially have very few apps - // seeded when they start up for the first time. Clings won't work well with that - boolean supportsLimitedUsers = - android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; - Account[] accounts = AccountManager.get(mLauncher).getAccounts(); - if (supportsLimitedUsers && accounts.length == 0) { - UserManager um = (UserManager) mLauncher.getSystemService(Context.USER_SERVICE); - Bundle restrictions = um.getUserRestrictions(); - if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) { - return false; + private void dismissMigrationCling() { + mLauncher.showWorkspaceSearchAndHotseat(); + Runnable dismissCb = new Runnable() { + public void run() { + Runnable cb = new Runnable() { + public void run() { + // Show the longpress cling next + showLongPressCling(false); + } + }; + dismissCling(mLauncher.findViewById(R.id.migration_cling), cb, + MIGRATION_CLING_DISMISSED_KEY, DISMISS_CLING_DURATION); } - } - if (Settings.Secure.getInt(mLauncher.getContentResolver(), SKIP_FIRST_USE_HINTS, 0) - == 1) { - return false; - } - return true; + }; + mLauncher.getWorkspace().post(dismissCb); } - /** Returns whether the folder cling is visible. */ - public boolean isFolderClingVisible() { - Cling cling = (Cling) mLauncher.findViewById(R.id.folder_cling); - if (cling != null) { - return cling.getVisibility() == View.VISIBLE; - } - return false; - } + public void showLongPressCling(boolean showWelcome) { + ViewGroup root = (ViewGroup) mLauncher.findViewById(R.id.launcher); + View cling = mInflater.inflate(R.layout.longpress_cling, root, false); - private boolean skipCustomClingIfNoAccounts() { - Cling cling = (Cling) mLauncher.findViewById(R.id.workspace_cling); - boolean customCling = cling.getDrawIdentifier().equals("workspace_custom"); - if (customCling) { - AccountManager am = AccountManager.get(mLauncher); - if (am == null) return false; - Account[] accounts = am.getAccountsByType("com.google"); - return accounts.length == 0; - } - return false; - } + final ClearCircleLayout hole = (ClearCircleLayout) cling.findViewById(R.id.cling_longpress_hole); + hole.initHole(mLauncher); + hole.setClickable(true); + hole.setOnLongClickListener(new OnLongClickListener() { - /** Updates the first run cling custom content hint */ - private void setCustomContentHintVisibility(Cling cling, String ccHintStr, boolean visible, - boolean animate) { - final TextView ccHint = (TextView) cling.findViewById(R.id.custom_content_hint); - if (ccHint != null) { - if (visible && !ccHintStr.isEmpty()) { - ccHint.setText(ccHintStr); - ccHint.setVisibility(View.VISIBLE); - if (animate) { - ccHint.setAlpha(0f); - ccHint.animate().alpha(1f) - .setDuration(SHOW_CLING_DURATION) - .start(); - } else { - ccHint.setAlpha(1f); - } - } else { - if (animate) { - ccHint.animate().alpha(0f) - .setDuration(SHOW_CLING_DURATION) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - ccHint.setVisibility(View.GONE); - } - }) - .start(); - } else { - ccHint.setAlpha(0f); - ccHint.setVisibility(View.GONE); - } + @Override + public boolean onLongClick(View v) { + mLauncher.getWorkspace().enterOverviewMode(); + dismissLongPressCling(); + return true; } - } - } + }); - /** Updates the first run cling custom content hint */ - public void updateCustomContentHintVisibility() { - Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling); - String ccHintStr = mLauncher.getFirstRunCustomContentHint(); + final ViewGroup content = (ViewGroup) cling.findViewById(R.id.cling_content); + mInflater.inflate(showWelcome ? R.layout.longpress_cling_welcome_content + : R.layout.longpress_cling_content, content); + content.findViewById(R.id.cling_dismiss_longpress_info).setOnClickListener(this); - if (mLauncher.getWorkspace().hasCustomContent()) { - // Show the custom content hint if ccHintStr is not empty - if (cling != null) { - setCustomContentHintVisibility(cling, ccHintStr, true, true); - } - } else { - // Hide the custom content hint - if (cling != null) { - setCustomContentHintVisibility(cling, ccHintStr, false, true); - } - } - } + root.addView(cling); - /** Updates the first run cling search bar hint. */ - public void updateSearchBarHint(String hint) { - Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling); - if (cling != null && cling.getVisibility() == View.VISIBLE && !hint.isEmpty()) { - TextView sbHint = (TextView) cling.findViewById(R.id.search_bar_hint); - sbHint.setText(hint); - sbHint.setVisibility(View.VISIBLE); + if (showWelcome) { + // This is the first cling being shown. No need to animate. + return; } - } - public boolean shouldShowFirstRunOrMigrationClings() { - SharedPreferences sharedPrefs = mLauncher.getSharedPrefs(); - return areClingsEnabled() && - !sharedPrefs.getBoolean(FIRST_RUN_CLING_DISMISSED_KEY, false) && - !sharedPrefs.getBoolean(MIGRATION_CLING_DISMISSED_KEY, false); - } + // Animate + content.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { - public void removeFirstRunAndMigrationClings() { - removeCling(R.id.first_run_cling); - removeCling(R.id.migration_cling); - } + @Override + public void onGlobalLayout() { + content.getViewTreeObserver().removeOnGlobalLayoutListener(this); - /** - * Shows the first run cling. - * - * This flow is mutually exclusive with showMigrationCling, and only runs if this Launcher - * package was preinstalled or there is no db to migrate from. - */ - public void showFirstRunCling() { - if (!skipCustomClingIfNoAccounts()) { - Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling); - if (cling != null) { - String sbHintStr = mLauncher.getFirstRunClingSearchBarHint(); - String ccHintStr = mLauncher.getFirstRunCustomContentHint(); - if (!sbHintStr.isEmpty()) { - TextView sbHint = (TextView) cling.findViewById(R.id.search_bar_hint); - sbHint.setText(sbHintStr); - sbHint.setVisibility(View.VISIBLE); - } - setCustomContentHintVisibility(cling, ccHintStr, true, false); - } - initCling(R.id.first_run_cling, 0, false, true); - } else { - removeFirstRunAndMigrationClings(); - } - } + hole.setAlpha(0); + ValueAnimator anim1 = LauncherAnimUtils.ofFloat(hole, "alpha", 1); - /** - * Shows the migration cling. - * - * This flow is mutually exclusive with showFirstRunCling, and only runs if this Launcher - * package was not preinstalled and there exists a db to migrate from. - */ - public void showMigrationCling() { - mLauncher.hideWorkspaceSearchAndHotseat(); - - Cling c = initCling(R.id.migration_cling, 0, false, true); - c.bringScrimToFront(); - c.bringToFront(); - } + ObjectAnimator anim2; - public void showMigrationWorkspaceCling() { - // Enable the clings only if they have not been dismissed before - if (areClingsEnabled() && !mLauncher.getSharedPrefs().getBoolean( - MIGRATION_WORKSPACE_CLING_DISMISSED_KEY, false)) { - Cling c = initCling(R.id.migration_workspace_cling, 0, false, true); - c.updateMigrationWorkspaceBubblePosition(); - c.bringScrimToFront(); - c.bringToFront(); - } else { - removeCling(R.id.migration_workspace_cling); - } - } + if (ANIM_SLIDE_FROM_TOP.equals(content.getTag())) { + content.setTranslationY(-content.getMeasuredHeight()); + anim2 = LauncherAnimUtils.ofFloat(content, "translationY", 0); + } else if (ANIM_SLIDE_FROM_BOTTOM.equals(content.getTag())) { + content.setTranslationY(content.getMeasuredHeight()); + anim2 = LauncherAnimUtils.ofFloat(content, "translationY", 0); + } else { + content.setScaleX(0); + content.setScaleY(0); + PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1); + PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1); + anim2 = LauncherAnimUtils.ofPropertyValuesHolder(content, scaleX, scaleY); + } - public void showWorkspaceCling() { - // Enable the clings only if they have not been dismissed before - if (areClingsEnabled() && !mLauncher.getSharedPrefs().getBoolean( - WORKSPACE_CLING_DISMISSED_KEY, false)) { - Cling c = initCling(R.id.workspace_cling, 0, false, true); - c.updateWorkspaceBubblePosition(); - if (mLauncher.shouldClingFocusHotseatApp()) { - // Set the focused hotseat app - c.setFocusedHotseatApp(mLauncher.getFirstRunFocusedHotseatAppDrawableId(), - mLauncher.getFirstRunFocusedHotseatAppRank(), - mLauncher.getFirstRunFocusedHotseatAppComponentName(), - mLauncher.getFirstRunFocusedHotseatAppBubbleTitle(), - mLauncher.getFirstRunFocusedHotseatAppBubbleDescription()); + AnimatorSet anim = LauncherAnimUtils.createAnimatorSet(); + anim.setDuration(SHOW_CLING_DURATION); + anim.setInterpolator(new LogDecelerateInterpolator(100, 0)); + anim.playTogether(anim1, anim2); + anim.start(); } - } else { - removeCling(R.id.workspace_cling); - } + }); } - public Cling showFoldersCling() { - SharedPreferences sharedPrefs = mLauncher.getSharedPrefs(); - // Enable the clings only if they have not been dismissed before - if (areClingsEnabled() && - !sharedPrefs.getBoolean(FOLDER_CLING_DISMISSED_KEY, false) && - !sharedPrefs.getBoolean(Launcher.USER_HAS_MIGRATED, false)) { - Cling cling = initCling(R.id.folder_cling, R.id.cling_scrim, - true, true); - Folder openFolder = mLauncher.getWorkspace().getOpenFolder(); - if (openFolder != null) { - Rect openFolderRect = new Rect(); - openFolder.getHitRect(openFolderRect); - cling.setOpenFolderRect(openFolderRect); - openFolder.bringToFront(); + private void dismissLongPressCling() { + Runnable dismissCb = new Runnable() { + public void run() { + dismissCling(mLauncher.findViewById(R.id.longpress_cling), null, + WORKSPACE_CLING_DISMISSED_KEY, DISMISS_CLING_DURATION); } - return cling; - } else { - removeCling(R.id.folder_cling); - return null; - } - } - - public static void synchonouslyMarkFirstRunClingDismissed(Context ctx) { - SharedPreferences prefs = ctx.getSharedPreferences( - LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(LauncherClings.FIRST_RUN_CLING_DISMISSED_KEY, true); - editor.commit(); - } - - /** Removes the cling outright from the DragLayer */ - private void removeCling(int id) { - final View cling = mLauncher.findViewById(id); - if (cling != null) { - final ViewGroup parent = (ViewGroup) cling.getParent(); - parent.post(new Runnable() { - @Override - public void run() { - parent.removeView(cling); - } - }); - mHideFromAccessibilityHelper.restoreImportantForAccessibility(mLauncher.getDragLayer()); - } + }; + mLauncher.getWorkspace().post(dismissCb); } /** Hides the specified Cling */ - private void dismissCling(final Cling cling, final Runnable postAnimationCb, - final String flag, int duration, boolean restoreNavBarVisibilty) { + private void dismissCling(final View cling, final Runnable postAnimationCb, + final String flag, int duration) { // To catch cases where siblings of top-level views are made invisible, just check whether // the cling is directly set to GONE before dismissing it. if (cling != null && cling.getVisibility() != View.GONE) { final Runnable cleanUpClingCb = new Runnable() { public void run() { - cling.cleanup(); - SharedPreferences.Editor editor = mLauncher.getSharedPrefs().edit(); - editor.putBoolean(flag, true); - editor.apply(); + cling.setVisibility(View.GONE); + mLauncher.getSharedPrefs().edit() + .putBoolean(flag, true) + .apply(); if (postAnimationCb != null) { postAnimationCb.run(); } @@ -350,114 +214,58 @@ class LauncherClings { if (duration <= 0) { cleanUpClingCb.run(); } else { - cling.hide(duration, cleanUpClingCb); - } - mHideFromAccessibilityHelper.restoreImportantForAccessibility(mLauncher.getDragLayer()); - - if (restoreNavBarVisibilty) { - cling.setSystemUiVisibility(cling.getSystemUiVisibility() & - ~View.SYSTEM_UI_FLAG_LOW_PROFILE); + cling.animate().alpha(0).setDuration(duration).withEndAction(cleanUpClingCb); } } } - public void dismissFirstRunCling(View v) { - Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling); - Runnable cb = new Runnable() { - public void run() { - // Show the workspace cling next - showWorkspaceCling(); - } - }; - dismissCling(cling, cb, FIRST_RUN_CLING_DISMISSED_KEY, - DISMISS_CLING_DURATION, false); - - // Fade out the search bar for the workspace cling coming up - mLauncher.getSearchBar().hideSearchBar(true); - } - - private void dismissMigrationCling() { - mLauncher.showWorkspaceSearchAndHotseat(); - Runnable dismissCb = new Runnable() { - public void run() { - Cling cling = (Cling) mLauncher.findViewById(R.id.migration_cling); - Runnable cb = new Runnable() { - public void run() { - // Show the migration workspace cling next - showMigrationWorkspaceCling(); - } - }; - dismissCling(cling, cb, MIGRATION_CLING_DISMISSED_KEY, - DISMISS_CLING_DURATION, true); - } - }; - mLauncher.getWorkspace().post(dismissCb); - } - - private void dismissAnyWorkspaceCling(Cling cling, String key, View v) { - Runnable cb = null; - if (v == null) { - cb = new Runnable() { - public void run() { - mLauncher.getWorkspace().enterOverviewMode(); - } - }; + /** Returns whether the clings are enabled or should be shown */ + private boolean areClingsEnabled() { + if (DISABLE_CLINGS) { + return false; } - dismissCling(cling, cb, key, DISMISS_CLING_DURATION, true); - // Fade in the search bar - mLauncher.getSearchBar().showSearchBar(true); - } + // disable clings when running in a test harness + if(ActivityManager.isRunningInTestHarness()) return false; - public void markFolderClingDismissedIfNecessary() { - SharedPreferences prefs = mLauncher.getSharedPrefs(); - if (!prefs.getBoolean(FOLDER_CLING_DISMISSED_KEY, false)) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(FOLDER_CLING_DISMISSED_KEY, true); - editor.apply(); + // Disable clings for accessibility when explore by touch is enabled + final AccessibilityManager a11yManager = (AccessibilityManager) mLauncher.getSystemService( + Launcher.ACCESSIBILITY_SERVICE); + if (a11yManager.isTouchExplorationEnabled()) { + return false; } - } - - public void dismissMigrationClingCopyApps(View v) { - // Copy the shortcuts from the old database - LauncherModel model = mLauncher.getModel(); - model.resetLoadedState(false, true); - model.startLoader(false, PagedView.INVALID_RESTORE_PAGE, - LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE - | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS); - - // Set the flag to skip the folder cling - String spKey = LauncherAppState.getSharedPreferencesKey(); - SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = sp.edit(); - editor.putBoolean(Launcher.USER_HAS_MIGRATED, true); - editor.apply(); - - // Disable the migration cling - dismissMigrationCling(); - } - - public void dismissMigrationClingUseDefault(View v) { - // Don't need to do anything special here. We've already loaded the default workspace, - // (which is the default loader behavior triggered from Launcher#onCreate.). - // Disable the migration cling - dismissMigrationCling(); - } - - public void dismissMigrationWorkspaceCling(View v) { - Cling cling = (Cling) mLauncher.findViewById(R.id.migration_workspace_cling); - dismissAnyWorkspaceCling(cling, MIGRATION_WORKSPACE_CLING_DISMISSED_KEY, v); + // Restricted secondary users (child mode) will potentially have very few apps + // seeded when they start up for the first time. Clings won't work well with that + boolean supportsLimitedUsers = + android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; + Account[] accounts = AccountManager.get(mLauncher).getAccounts(); + if (supportsLimitedUsers && accounts.length == 0) { + UserManager um = (UserManager) mLauncher.getSystemService(Context.USER_SERVICE); + Bundle restrictions = um.getUserRestrictions(); + if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) { + return false; + } + } + if (Settings.Secure.getInt(mLauncher.getContentResolver(), SKIP_FIRST_USE_HINTS, 0) + == 1) { + return false; + } + return true; } - public void dismissWorkspaceCling(View v) { - Cling cling = (Cling) mLauncher.findViewById(R.id.workspace_cling); - dismissAnyWorkspaceCling(cling, WORKSPACE_CLING_DISMISSED_KEY, v); + public boolean shouldShowFirstRunOrMigrationClings() { + SharedPreferences sharedPrefs = mLauncher.getSharedPrefs(); + return areClingsEnabled() && + !sharedPrefs.getBoolean(WORKSPACE_CLING_DISMISSED_KEY, false) && + !sharedPrefs.getBoolean(MIGRATION_CLING_DISMISSED_KEY, false); } - public void dismissFolderCling(View v) { - Cling cling = (Cling) mLauncher.findViewById(R.id.folder_cling); - dismissCling(cling, null, FOLDER_CLING_DISMISSED_KEY, - DISMISS_CLING_DURATION, true); + public static void synchonouslyMarkFirstRunClingDismissed(Context ctx) { + SharedPreferences prefs = ctx.getSharedPreferences( + LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(WORKSPACE_CLING_DISMISSED_KEY, true); + editor.commit(); } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 6d217017e..866125147 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -596,7 +596,6 @@ public class Workspace extends SmoothPagedView mDefaultPage = mOriginalDefaultPage + 1; // Update the custom content hint - mLauncher.getLauncherClings().updateCustomContentHintVisibility(); if (mRestorePage != INVALID_RESTORE_PAGE) { mRestorePage = mRestorePage + 1; } else { @@ -625,7 +624,6 @@ public class Workspace extends SmoothPagedView mDefaultPage = mOriginalDefaultPage - 1; // Update the custom content hint - mLauncher.getLauncherClings().updateCustomContentHintVisibility(); if (mRestorePage != INVALID_RESTORE_PAGE) { mRestorePage = mRestorePage - 1; } else { @@ -2702,10 +2700,6 @@ public class Workspace extends SmoothPagedView if (child instanceof BubbleTextView) { BubbleTextView icon = (BubbleTextView) child; icon.clearPressedBackground(); - } else if (child instanceof FolderIcon) { - // The folder cling isn't flexible enough to be shown in non-default workspace positions - // Also if they are dragging it a folder, we assume they don't need to see the cling. - mLauncher.markFolderClingDismissedIfNecessary(); } if (child.getTag() == null || !(child.getTag() instanceof ItemInfo)) { @@ -3053,10 +3047,6 @@ public class Workspace extends SmoothPagedView // cell also contains a shortcut, then create a folder with the two shortcuts. if (!mInScrollArea && createUserFolderIfNecessary(cell, container, dropTargetLayout, mTargetCell, distance, false, d.dragView, null)) { - // The folder cling isn't flexible enough to be shown in non-default workspace - // positions. Also if they are creating a folder, we assume they don't need to - // see the cling. - mLauncher.markFolderClingDismissedIfNecessary(); return; } @@ -3965,10 +3955,6 @@ public class Workspace extends SmoothPagedView d.postAnimationRunnable = exitSpringLoadedRunnable; if (createUserFolderIfNecessary(view, container, cellLayout, mTargetCell, distance, true, d.dragView, d.postAnimationRunnable)) { - // The folder cling isn't flexible enough to be shown in non-default workspace - // positions. Also if they are creating a folder, we assume they don't need to - // see the cling. - mLauncher.markFolderClingDismissedIfNecessary(); return; } if (addToExistingFolderIfNecessary(view, cellLayout, mTargetCell, distance, d, |