summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java255
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java7
2 files changed, 178 insertions, 84 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java
index 86fc49e..ee47339 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java
@@ -19,10 +19,8 @@ package com.android.systemui.qs;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.ActivityManager;
-import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
@@ -32,12 +30,10 @@ import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff;
-import android.graphics.drawable.Animatable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.UserHandle;
-import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.ArrayMap;
@@ -49,7 +45,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
-import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -59,17 +54,16 @@ import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.cm.UserContentObserver;
import com.android.systemui.qs.tiles.EditTile;
-import com.android.systemui.qs.tiles.IntentTile;
import com.android.systemui.settings.BrightnessController;
import com.android.systemui.settings.ToggleSlider;
import com.android.systemui.statusbar.phone.QSTileHost;
-import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.tuner.QsTuner;
import com.viewpagerindicator.CirclePageIndicator;
import cyanogenmod.app.StatusBarPanelCustomTile;
import cyanogenmod.providers.CMSettings;
import org.cyanogenmod.internal.logging.CMMetricsLogger;
+import org.cyanogenmod.internal.util.QSConstants;
import org.cyanogenmod.internal.util.QSUtils;
import java.util.ArrayList;
@@ -355,7 +349,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
@Override
public boolean hasOverlappingRendering() {
- return mClipper.isAnimating() || mEditing;
+ return mClipper.isAnimating() || mEditing || !mCurrentlyAnimating.isEmpty();
}
@Override
@@ -465,7 +459,6 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
mLastRightShift = -1;
mQsPanelTop.onStopDrag();
- requestLayout();
}
protected View getDropTarget() {
@@ -501,14 +494,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
public void setTiles(final Collection<QSTile<?>> tilesCollection) {
- final List<QSTile<?>> tiles = new ArrayList<>(tilesCollection);
+ // we try to be as efficient as possible here because this can happen while the user
+ // is in edit mode, or maybe even while tiles are animating
+ // step 1: stop all animations
+ // step 2: remove tiles no longer to be used, cache ones that are still valid
+ // step 3: remove empty viewpager pages
+ // step 4: generate new tiles, re-add cached ones
+
if (DEBUG_TILES) {
- Log.i(TAG, "setTiles() called with " + "tiles = ["
- + tiles + "]");
+ Log.i(TAG, "setTiles() called with tiles = [" + tilesCollection + "]");
}
-
- int currentViewPagerPage = mViewPager.getCurrentItem();
-
if (mLastDragRecord != null && mRecords.indexOf(mLastDragRecord) == -1) {
// the last removed record might be stored in mLastDragRecord if we just shifted
// re-add it to the list so we'll clean it up below
@@ -516,25 +511,41 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
mLastDragRecord = null;
}
- Map<QSTile<?>, DragTileRecord> recordMap = new ArrayMap<>();
+ // step kinda-1
+ if (mDraggingRecord != null) {
+ // dragging record might be animating back, force it to finished position
+ mDraggingRecord.tileView.animate().cancel();
+ }
+
+ int currentViewPagerPage = mViewPager.getCurrentItem();
+ int removedPages = 0;
+
+ Map<QSTile<?>, DragTileRecord> cachedRecords = new ArrayMap<>();
ListIterator<TileRecord> iterator = mRecords.listIterator(mRecords.size());
int recordsRemoved = 0;
// cleanup current records
- while (iterator.hasPrevious()) {
+ while (iterator.hasPrevious()) { // mRecords
DragTileRecord dr = (DragTileRecord) iterator.previous();
- if (dr.page >= 0) {
- // clean up view
- mPages.get(dr.page).removeView(dr.tileView);
- }
+ // step 1
+ dr.tileView.animate().cancel();
- if (tiles.contains(dr.tile)) {
+ // step 2
+ if (tilesCollection.contains(dr.tile)) {
if (DEBUG_TILES) {
Log.i(TAG, "caching tile: " + dr.tile);
}
- recordMap.put(dr.tile, dr);
+ cachedRecords.put(dr.tile, dr);
} else {
+ if (dr.page >= 0) {
+ if (DEBUG_TILES) {
+ Log.w(TAG, "removed dr.tileView: " + dr.tileView + " from page: "
+ + dr.page + " (dest page: " + dr.destinationPage + ")");
+ }
+
+ removeTileView(dr.tileView);
+ }
if (DEBUG_TILES) {
Log.i(TAG, "removing tile: " + dr.tile);
}
@@ -543,74 +554,92 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
iterator.remove();
recordsRemoved++;
- if (dr.page >= getCurrentMaxPageCount() - 1) {
- final int childCount = mPages.get(dr.page).getChildCount();
-
- if (childCount == 0) {
- final int currentIndex = mViewPager.getCurrentItem();
- if (currentIndex > 0 && currentViewPagerPage == currentIndex) {
- // if we are about to remove the page we are currently on, move back
- currentViewPagerPage--;
- }
- final int pageIndex = dr.page + (mEditing ? 1 : 0);
- mPagerAdapter.startUpdate(mViewPager);
- mPagerAdapter.destroyItem(mViewPager, pageIndex, mPages.get(dr.page));
- mPagerAdapter.finishUpdate(mViewPager);
- mPagerAdapter.notifyDataSetChanged();
- }
- }
+ dr.page = -1;
+ dr.destinationPage = -1;
}
- dr.page = -1;
- dr.destinationPage = -1;
}
- // at this point recordMap should have all retained tiles, no new or old tiles
- int delta = tiles.size() - recordMap.size() - recordsRemoved;
+ // at this point cachedRecords should have all retained tiles, no new or old tiles
+ int delta = tilesCollection.size() - cachedRecords.size() - recordsRemoved;
if (DEBUG_TILES) {
Log.i(TAG, "record map delta: " + delta);
}
- mRecords.ensureCapacity(tiles.size());
- mPagerAdapter.notifyDataSetChanged();
+ // step 3
+ final Iterator<QSPage> pageIterator = mPages.iterator();
+ while (pageIterator.hasNext()) {
+ final QSPage page = pageIterator.next();
+ final int viewpagerIndex = page.getPageIndex() + (mEditing ? 1 : 0);
+ final int childCount = page.getChildCount();
- // even though we explicitly destroy old pages, without this call,
- // the viewpager doesn't seem to want to pick up the fact that we have less pages
- // and allows "empty" scrolls to the right where there is no page.
- mViewPager.setAdapter(mPagerAdapter);
+ if (DEBUG_TILES) {
+ Log.d(TAG, "page " + viewpagerIndex + " has " + childCount);
+ }
+ if (page.getPageIndex() >= getCurrentMaxPageCount() - 1) {
+ if (DEBUG_TILES) {
+ Log.d(TAG, "page : " + page + " has " + childCount + " children");
+ }
+ if (childCount == 0) {
+ removedPages++;
+
+ page.removeAllViews();
+ mPagerAdapter.startUpdate(mViewPager);
+ mPagerAdapter.destroyItem(mViewPager, viewpagerIndex, page);
+ mPagerAdapter.finishUpdate(mViewPager);
+ mPagerAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+
+ if (removedPages > 0) {
+ // even though we explicitly destroy old pages, without this call,
+ // the viewpager doesn't seem to want to pick up the fact that we have less pages
+ // and allows "empty" scrolls to the right where there is no page.
+ if (DEBUG_TILES) {
+ Log.d(TAG, "re-setting adapter, page: " + currentViewPagerPage);
+ }
+ mViewPager.setAdapter(mPagerAdapter);
+ mViewPager.setCurrentItem(Math.min(currentViewPagerPage, mPagerAdapter.getCount()),
+ false);
+ mPagerAdapter.notifyDataSetChanged();
+ }
+
+ // step 4
+ mRecords.ensureCapacity(tilesCollection.size());
+ int runningCount = 0;
- // add new tiles
- for (int i = 0; i < tiles.size(); i++) {
- QSTile<?> tile = tiles.get(i);
- final int tileDestPage = getPagesForCount(i + 1) - 1;
+ final Iterator<QSTile<?>> newTileIterator = tilesCollection.iterator();
+ while (newTileIterator.hasNext()) {
+ QSTile<?> tile = newTileIterator.next();
+ final int tileDestPage = getPagesForCount(runningCount + 1) - 1;
if (DEBUG_TILES) {
- Log.d(TAG, "tile at : " + i + ": " + tile + " to dest page: " + tileDestPage);
+ Log.d(TAG, "tile at : " + runningCount + ": " + tile
+ + " to dest page: " + tileDestPage);
}
DragTileRecord record;
- if (!recordMap.containsKey(tile)) {
+ if (!cachedRecords.containsKey(tile)) {
if (DEBUG_TILES) {
- Log.d(TAG, "tile at: " + i + " not cached, adding it to records");
+ Log.d(TAG, "tile at: " + runningCount + " not cached, adding it to records");
}
record = makeRecord(tile);
record.destinationPage = tileDestPage;
- recordMap.put(tile, record);
- mRecords.add(i, record);
+ mRecords.add(runningCount, record);
mPagerAdapter.notifyDataSetChanged();
} else {
- record = recordMap.get(tile);
+ record = cachedRecords.get(tile);
if (DEBUG_TILES) {
- Log.d(TAG, "tile at : " + i + ": cached, restoring: " + record);
+ Log.d(TAG, "tile at : " + runningCount + ": cached, restoring: " + record);
}
- int indexOf = mRecords.indexOf(record);
- if (indexOf != i) {
- if (DEBUG_TILES) {
- Log.w(TAG, "moving index of " + record + " from "
- + indexOf + " to " + i);
- }
- Collections.swap(mRecords, indexOf, i);
- }
+ mPages.get(record.page).removeView(record.tileView);
+
+ record.page = -1;
record.destinationPage = tileDestPage;
+
+ mRecords.remove(record);
+ mRecords.add(runningCount, record);
+ mPagerAdapter.notifyDataSetChanged();
}
if (record.page == -1) {
// add the view
@@ -620,11 +649,9 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
Log.d(TAG, "added view " + record);
}
}
+ runningCount++;
}
- // restore the visible page
- mViewPager.setCurrentItem(currentViewPagerPage, false);
-
if (isShowingDetail()) {
mDetail.bringToFront();
}
@@ -718,10 +745,18 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
return r;
}
+ private void removeTileView(QSTileView v) {
+ for (QSPage page : mPages) {
+ page.removeView(v);
+ page.removeTransientView(v);
+ }
+
+ }
+
private void removeDraggingRecord() {
// what spec is this tile?
String spec = mHost.getSpec(mDraggingRecord.tile);
- if (DEBUG_DRAG) {
+ if (DEBUG_TILES) {
Log.w(TAG, "removing tile: " + mDraggingRecord + " with spec: " + spec);
}
onStopDrag();
@@ -1014,7 +1049,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
if (originatingTileEvent && !event.getResult()) {
// view pager probably ate the event
- restoreDraggingTilePosition(v);
+ restoreDraggingTilePosition(v, null);
}
break;
@@ -1032,15 +1067,27 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
Log.d(TAG, "dropping on delete target!!");
}
if (mDraggingRecord.tile instanceof EditTile) {
+ final QSTileView editTileView = mDraggingRecord.tileView;
+
mQsPanelTop.toast(R.string.quick_settings_cannot_delete_edit_tile);
- restoreDraggingTilePosition(v);
+ restoreDraggingTilePosition(v, new Runnable() {
+ @Override
+ public void run() {
+ // move edit tile to the back
+ final TileRecord editTile = getRecord(editTileView);
+ if (mRecords.remove(editTile)) {
+ // we depend on mHost.setTiles() placing it on the end
+ persistRecords();
+ }
+ }
+ });
break;
} else {
mRestored = true;
removeDraggingRecord();
}
} else {
- restoreDraggingTilePosition(v);
+ restoreDraggingTilePosition(v, null);
}
break;
@@ -1171,7 +1218,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
return false;
}
- private void restoreDraggingTilePosition(View v) {
+ private void restoreDraggingTilePosition(View v, final Runnable onAnimationFinishedRunnable) {
if (mRestored) {
return;
}
@@ -1251,6 +1298,20 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
@Override
+ public void onAnimationCancel(Animator animation) {
+ mViewPager.requestDisallowInterceptTouchEvent(false);
+ removeTransientView(mDraggingRecord.tileView);
+ mCurrentlyAnimating.remove(mDraggingRecord);
+ mRestoring = false;
+ mPagerAdapter.notifyDataSetChanged();
+ onStopDrag();
+
+ if (onAnimationFinishedRunnable != null) {
+ postOnAnimation(onAnimationFinishedRunnable);
+ }
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
mViewPager.requestDisallowInterceptTouchEvent(false);
@@ -1265,8 +1326,8 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
Log.i(TAG, "drag record was attached");
}
}
- mDraggingRecord.page = mDraggingRecord.destinationPage;
targetP.addView(mDraggingRecord.tileView);
+ mDraggingRecord.page = mDraggingRecord.destinationPage;
mDraggingRecord.tileView.setX(mDraggingRecord.destination.x);
// reset this to be in the coords of the page, not viewpager anymore
@@ -1281,6 +1342,12 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
mPagerAdapter.notifyDataSetChanged();
}
onStopDrag();
+
+ if (onAnimationFinishedRunnable != null) {
+ postOnAnimation(onAnimationFinishedRunnable);
+ } else {
+ requestLayout();
+ }
}
});
}
@@ -1497,10 +1564,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
.y(ti.destination.y)
.setListener(new AnimatorListenerAdapter() {
@Override
+ public void onAnimationCancel(Animator animation) {
+ tilePageSource.removeTransientView(ti.tileView);
+ mCurrentlyAnimating.remove(ti);
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
tilePageSource.removeTransientView(ti.tileView);
- ti.page = tilePageTarget.getPageIndex();
tilePageTarget.addView(ti.tileView);
+ ti.page = tilePageTarget.getPageIndex();
ti.tileView.setX(ti.destination.x);
ti.tileView.setY(ti.destination.y);
@@ -1516,6 +1589,11 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
.y(ti.destination.y)
.setListener(new AnimatorListenerAdapter() {
@Override
+ public void onAnimationCancel(Animator animation) {
+ mCurrentlyAnimating.remove(ti);
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
mCurrentlyAnimating.remove(ti);
final boolean dual = getPage(ti.destinationPage).dualRecord(ti);
@@ -1551,10 +1629,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
.y(last.destination.y)
.setListener(new AnimatorListenerAdapter() {
@Override
+ public void onAnimationCancel(Animator animation) {
+ tilePageSource.removeTransientView(last.tileView);
+ mCurrentlyAnimating.remove(last);
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
tilePageSource.removeTransientView(last.tileView);
- last.page = tilePageTarget.getPageIndex();
tilePageTarget.addView(last.tileView);
+ last.page = tilePageTarget.getPageIndex();
last.tileView.setX(last.destination.x);
last.tileView.setY(last.destination.y);
@@ -1573,6 +1657,11 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
.y(last.destination.y)
.setListener(new AnimatorListenerAdapter() {
@Override
+ public void onAnimationCancel(Animator animation) {
+ mCurrentlyAnimating.remove(last);
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
if (DEBUG_DRAG) {
Log.i(TAG, "shift finished: " + last);
@@ -1654,10 +1743,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
@Override
+ public void onAnimationCancel(Animator animation) {
+ page.removeTransientView(ti.tileView);
+ mCurrentlyAnimating.remove(ti);
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
page.removeTransientView(ti.tileView);
- ti.page = page.getPageIndex();
page.addView(ti.tileView);
+ ti.page = page.getPageIndex();
mCurrentlyAnimating.remove(ti);
requestLayout();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index b190edc..2c68c62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -399,11 +399,10 @@ public class QSTileHost implements QSTile.Host, Tunable {
tiles.add(tile);
}
}
- // ensure edit tile is present
- if (tiles.size() < TILES_PER_PAGE && !tiles.contains("edit")) {
+ // ensure edit tile is present, default placement should be handled in the default
+ // tile list.
+ if (!tiles.contains("edit")) {
tiles.add("edit");
- } else if (tiles.size() > TILES_PER_PAGE && !tiles.contains("edit")) {
- tiles.add((TILES_PER_PAGE - 1), "edit");
}
return tiles;
}