summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java')
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java549
1 files changed, 366 insertions, 183 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..13f552c 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;
@@ -58,12 +53,12 @@ import com.android.internal.logging.MetricsLogger;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.cm.UserContentObserver;
+import com.android.systemui.qs.tiles.CustomQSTile;
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.NotificationPanelView;
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;
@@ -80,6 +75,8 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+
public class QSDragPanel extends QSPanel implements View.OnDragListener, View.OnLongClickListener {
private static final String TAG = "QSDragPanel";
@@ -94,6 +91,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
protected final ArrayList<QSPage> mPages = new ArrayList<>();
+ private NotificationPanelView mPanelView;
protected QSViewPager mViewPager;
protected PagerAdapter mPagerAdapter;
QSPanelTopView mQsPanelTop;
@@ -102,6 +100,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
private TextView mDetailRemoveButton;
private DragTileRecord mDraggingRecord, mLastDragRecord;
+ private ViewGroup mDetailButtons;
private boolean mEditing;
private boolean mDragging;
private float mLastTouchLocationX, mLastTouchLocationY;
@@ -119,15 +118,13 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
List<TileRecord> mCurrentlyAnimating
= Collections.synchronizedList(new ArrayList<TileRecord>());
- private Point mDisplaySize;
- private int[] mTmpLoc;
-
private Runnable mResetPage = new Runnable() {
@Override
public void run() {
- if (!mListening) {
+ if (!mExpanded) {
// only reset when the user isn't interacting at all
mViewPager.setCurrentItem(0);
+ mPagerAdapter.notifyDataSetChanged();
}
}
};
@@ -145,6 +142,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
updateResources();
mDetail = LayoutInflater.from(mContext).inflate(R.layout.qs_detail, this, false);
+ mDetailButtons = (ViewGroup) mDetail.findViewById(R.id.buttons);
mDetailContent = (ViewGroup) mDetail.findViewById(android.R.id.content);
mDetailRemoveButton = (TextView) mDetail.findViewById(android.R.id.button3);
mDetailSettingsButton = (TextView) mDetail.findViewById(android.R.id.button2);
@@ -355,7 +353,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
@@ -370,7 +368,14 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
protected void drawTile(TileRecord r, QSTile.State state) {
if (mEditing) {
- state.visible = true;
+ if ((r.tile instanceof CustomQSTile)
+ && (((CustomQSTile) r.tile).isUserRemoved()
+ || ((CustomQSTile) r.tile).getTile() == null)) {
+ // don't modify visibility state if removed, or not yet published
+ } else {
+ state.visible = true;
+ state.enabled = true;
+ }
}
final int visibility = state.visible ? VISIBLE : GONE;
setTileVisibility(r.tileView, visibility);
@@ -382,12 +387,6 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
public void setListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
- // reset the page when inactive for a while
- if (listening) {
- removeCallbacks(mResetPage);
- } else {
- postDelayed(mResetPage, PAGE_RESET_DELAY);
- }
for (TileRecord r : mRecords) {
r.tile.setListening(mListening);
}
@@ -465,7 +464,6 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
mLastRightShift = -1;
mQsPanelTop.onStopDrag();
- requestLayout();
}
protected View getDropTarget() {
@@ -501,14 +499,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 +516,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 +559,99 @@ 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();
+ if (tile instanceof CustomQSTile) {
+ if (((CustomQSTile) tile).isUserRemoved()
+ || ((CustomQSTile) tile).getTile() == null) {
+ // tile not published yet
+ continue;
+ }
+ }
+ 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 +661,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 +757,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();
@@ -736,13 +783,6 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
@Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- mTmpLoc = null;
- mDisplaySize = null;
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = MeasureSpec.getSize(widthMeasureSpec);
@@ -756,37 +796,18 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
if (mFooter.hasFooter()) {
h += mFooter.getView().getMeasuredHeight();
}
+ mGridHeight = h;
+
mDetail.measure(exactly(width), MeasureSpec.UNSPECIFIED);
+
if (mDetail.getMeasuredHeight() < h) {
mDetail.measure(exactly(width), exactly(h));
}
-
- // Check if the detail view would be overflowing below the physical height of the device
- // and cutting the content off. If it is, reduce the detail height to fit.
- if (isShowingDetail()) {
- if (mDisplaySize == null) {
- mDisplaySize = new Point();
- getDisplay().getSize(mDisplaySize);
- }
- if (mTmpLoc == null) {
- mTmpLoc = new int[2];
- mDetail.getLocationOnScreen(mTmpLoc);
- }
-
- final int containerTop = mTmpLoc[1];
- final int detailBottom = containerTop + mDetail.getMeasuredHeight();
- if (detailBottom >= mDisplaySize.y) {
- // panel is hanging below the screen
- final int detailMinHeight = mDisplaySize.y - containerTop;
- mDetail.measure(exactly(width), exactly(detailMinHeight));
- }
- setMeasuredDimension(width, mDetail.getMeasuredHeight());
- mGridHeight = mDetail.getMeasuredHeight();
- } else {
- setMeasuredDimension(width, h);
- mGridHeight = h;
+ if (isShowingDetail() && !isClosingDetail() && mExpanded) {
+ h = mDetail.getMeasuredHeight();
}
+ setMeasuredDimension(width, h);
for (TileRecord record : mRecords) {
setupRecord(record);
}
@@ -816,11 +837,13 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
r.tile.setDetailListening(show);
int x = (int) ((DragTileRecord) r).destination.x + r.tileView.getWidth() / 2;
- int y = mViewPager.getTop() + (int) ((DragTileRecord) r).destination.y + r.tileView.getHeight() / 2;
+ int y = mViewPager.getTop()
+ + (int) ((DragTileRecord) r).destination.y + r.tileView.getHeight() / 2;
handleShowDetailImpl(r, show, x, y);
} else {
super.handleShowDetailTile(r, show);
}
+ mPageIndicator.setVisibility(!show ? View.VISIBLE : View.INVISIBLE);
}
@Override
@@ -833,9 +856,6 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
// view pager laid out from top of brightness view to bottom to page through settings
mViewPager.layout(0, 0, w, viewPagerBottom);
- // layout page indicator inside viewpager inset
- mPageIndicator.layout(0, b - mPageIndicatorHeight, w, b);
-
mDetail.layout(0, 0, w, mDetail.getMeasuredHeight());
if (mFooter.hasFooter()) {
@@ -846,7 +866,10 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
if (!isShowingDetail() && !isClosingDetail()) {
mQsPanelTop.bringToFront();
+
}
+ // layout page indicator inside viewpager inset
+ mPageIndicator.layout(0, b - mPageIndicatorHeight, w, b);
}
protected int getRowTop(int row) {
@@ -1014,7 +1037,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 +1055,38 @@ 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 if (mDraggingRecord.tile instanceof CustomQSTile) {
+ ((CustomQSTile) mDraggingRecord.tile).setUserRemoved(true);
+ final String spec = mHost.getSpec(mDraggingRecord.tile);
+ restoreDraggingTilePosition(v, new Runnable() {
+ @Override
+ public void run() {
+ // it might get added back later by the app, but that's ok,
+ // we just want to reset its position after it has been removed.
+ mHost.remove(spec);
+ }
+ });
} else {
mRestored = true;
removeDraggingRecord();
}
} else {
- restoreDraggingTilePosition(v);
+ restoreDraggingTilePosition(v, null);
}
break;
@@ -1171,7 +1217,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 +1297,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 +1325,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 +1341,12 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
mPagerAdapter.notifyDataSetChanged();
}
onStopDrag();
+
+ if (onAnimationFinishedRunnable != null) {
+ postOnAnimation(onAnimationFinishedRunnable);
+ } else {
+ requestLayout();
+ }
}
});
}
@@ -1497,10 +1563,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 +1588,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 +1628,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 +1656,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 +1742,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();
@@ -1710,17 +1804,27 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
});
}
+ mPanelView.setDetailRequestedScrollLock(mExpanded && show
+ && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE);
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
FontSizeUtils.updateFontSize(mDetailRemoveButton, R.dimen.qs_detail_button_text_size);
+ mPanelView.setDetailRequestedScrollLock(mExpanded && isShowingDetail()
+ && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE);
}
@Override
public void setExpanded(boolean expanded) {
super.setExpanded(expanded);
+ // reset the page when inactive for a while
+ if (expanded) {
+ removeCallbacks(mResetPage);
+ } else {
+ postDelayed(mResetPage, PAGE_RESET_DELAY);
+ }
if (!expanded) {
if (mEditing) {
mHost.setEditing(false);
@@ -1747,10 +1851,11 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
for (TileRecord r : mRecords) {
r.tile.clearState();
}
+ updateDetailText();
+ mQsPanelTop.updateResources();
if (mListening) {
refreshAllTiles();
}
- updateDetailText();
}
}
@@ -1764,6 +1869,10 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
}
+ public void setPanelView(NotificationPanelView panelView) {
+ this.mPanelView = panelView;
+ }
+
public static class TilesListAdapter extends BaseExpandableListAdapter
implements QSTile.DetailAdapter {
@@ -1790,7 +1899,8 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
final Iterator<String> i = tiles.iterator();
while (i.hasNext()) {
final String spec = i.next();
- if (QSUtils.isStaticQsTile(spec) || QSUtils.isDynamicQsTile(spec)) {
+ if (QSUtils.isStaticQsTile(spec)
+ || QSUtils.isDynamicQsTile(extractTileTagFromSpec(spec))) {
List<String> packageList = mPackageTileMap.get(PACKAGE_ANDROID);
packageList.add(spec);
} else {
@@ -1803,13 +1913,122 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
}
}
+ final Map<String, ?> stringMap = CustomQSTile.getCustomQSTilePrefs(mContext).getAll();
+ for (Map.Entry<String, ?> entry : stringMap.entrySet()) {
+ if (entry.getValue() instanceof Boolean) {
+ if ((Boolean)entry.getValue()) {
+ final String key = entry.getKey();
+ if (QSUtils.isDynamicQsTile(extractTileTagFromSpec(key))) {
+ mPackageTileMap.get(PACKAGE_ANDROID).add(key);
+ } else {
+ final String customTilePackage = getCustomTilePackage(key);
+ List<String> packageList = mPackageTileMap.get(customTilePackage);
+ if (packageList == null) {
+ mPackageTileMap.put(customTilePackage,
+ packageList = new ArrayList<>());
+ }
+ packageList.add(key);
+
+ }
+ }
+ }
+ };
+
final List<String> systemTiles = mPackageTileMap.get(PACKAGE_ANDROID);
Collections.sort(systemTiles);
}
private String getCustomTilePackage(String spec) {
- StatusBarPanelCustomTile sbc = mHost.getCustomTileData().get(spec).sbc;
- return sbc.getPackage();
+ if (mHost.getCustomTileData().get(spec) != null) {
+ StatusBarPanelCustomTile sbc = mHost.getCustomTileData().get(spec).sbc;
+ return sbc.getPackage();
+ } else {
+ return extractPackageFromCustomTileSpec(spec);
+ }
+ }
+
+ private static String extractPackageFromCustomTileSpec(String spec) {
+ if (spec != null && !spec.isEmpty()) {
+ final String[] split = spec.split("\\|");
+ if (split != null && split.length > 2) {
+ return split[1];
+ }
+ return spec;
+ }
+ return null;
+ }
+
+ private static String extractTileTagFromSpec(String spec) {
+ if (spec != null && !spec.isEmpty()) {
+ final String[] split = spec.split("\\|");
+ if (split != null && split.length == 5) {
+ /** for {@link cyanogenmod.app.StatusBarPanelCustomTile#key() **/
+ return split[3];
+ } else if (split != null && split.length == 3) {
+ /** for {@link cyanogenmod.app.StatusBarPanelCustomTile#persistableKey()} **/
+ return split[2];
+ }
+ return spec;
+ }
+ return null;
+ }
+
+ private Drawable getQSTileIcon(String spec) {
+ if (QSUtils.isDynamicQsTile(extractTileTagFromSpec(spec))) {
+ return QSTile.ResourceIcon.get(QSUtils.getDynamicQSTileResIconId(mContext,
+ UserHandle.myUserId(), extractTileTagFromSpec(spec))).getDrawable(mContext);
+ } else if (QSUtils.isStaticQsTile(spec)) {
+ final int res = QSTileHost.getIconResource(spec);
+ if (res != 0) {
+ return QSTile.ResourceIcon.get(res).getDrawable(mContext);
+ } else {
+ return mContext.getPackageManager().getDefaultActivityIcon();
+ }
+ } else {
+ QSTile<?> tile = mHost.getTile(spec);
+ if (tile != null) {
+ QSTile.State state = tile.getState();
+ if (state != null && state.icon != null) {
+ return state.icon.getDrawable(mContext);
+ }
+ }
+ return getPackageDrawable(getCustomTilePackage(spec));
+ }
+ }
+
+ private String getPackageLabel(String packageName) {
+ try {
+ return mContext.getPackageManager().getApplicationLabel(
+ mContext.getPackageManager().getApplicationInfo(packageName, 0)).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private Drawable getPackageDrawable(String packageName) {
+ try {
+ return mContext.getPackageManager().getApplicationIcon(packageName);
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private String getQSTileLabel(String spec) {
+ if (QSUtils.isStaticQsTile(spec)) {
+ int resource = QSTileHost.getLabelResource(spec);
+ if (resource != 0) {
+ return mContext.getText(resource).toString();
+ } else {
+ return spec;
+ }
+ } else if (QSUtils.isDynamicQsTile(extractTileTagFromSpec(spec))) {
+ return QSUtils.getDynamicQSTileLabel(mContext,
+ UserHandle.myUserId(), extractTileTagFromSpec(spec));
+ } else {
+ return getPackageLabel(getCustomTilePackage(spec));
+ }
}
@Override
@@ -1872,6 +2091,7 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
// special icon
systemOrAppIcon.setImageResource(R.drawable.ic_qs_tile_category_system);
} else {
+ group = getPackageLabel(group);
systemOrAppIcon.setImageResource(R.drawable.ic_qs_tile_category_other);
}
title.setText(group);
@@ -1910,57 +2130,6 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
return child;
}
- private String getQSTileLabel(String spec) {
- if (QSUtils.isStaticQsTile(spec)) {
- int resource = QSTileHost.getLabelResource(spec);
- return mContext.getText(resource).toString();
- } else if (QSUtils.isDynamicQsTile(spec)) {
- return QSUtils.getDynamicQSTileLabel(mContext,
- UserHandle.myUserId(), spec);
- } else {
- return getPackageLabel(getCustomTilePackage(spec));
- }
- }
-
- private Drawable getQSTileIcon(String spec) {
- if (QSUtils.isDynamicQsTile(spec)) {
- return QSTile.ResourceIcon.get(
- QSUtils.getDynamicQSTileResIconId(mContext, UserHandle.myUserId(), spec))
- .getDrawable(mContext);
- } else if (QSUtils.isStaticQsTile(spec)) {
- return QSTile.ResourceIcon.get(QSTileHost.getIconResource(spec))
- .getDrawable(mContext);
- } else {
- QSTile<?> tile = mHost.getTile(spec);
- if (tile != null) {
- QSTile.State state = tile.getState();
- if (state != null && state.icon != null) {
- return state.icon.getDrawable(mContext);
- }
- }
- return getPackageDrawable(getCustomTilePackage(spec));
- }
- }
-
- private String getPackageLabel(String packageName) {
- try {
- return mContext.getPackageManager().getApplicationLabel(
- mContext.getPackageManager().getApplicationInfo(packageName, 0)).toString();
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- private Drawable getPackageDrawable(String packageName) {
- try {
- return mContext.getPackageManager().getApplicationIcon(packageName);
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
@@ -2001,7 +2170,21 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
String spec = getChild(groupPosition, childPosition);
- mPanel.add(spec);
+
+ final QSTile<?> tile = mHost.getTile(spec);
+ if (tile != null && tile instanceof CustomQSTile) {
+ // already present
+ ((CustomQSTile) tile).setUserRemoved(false);
+ mPanel.refreshAllTiles();
+ } else {
+ // reset its state just in case it's not published
+ CustomQSTile.getCustomQSTilePrefs(mContext)
+ .edit()
+ .remove(spec)
+ .apply();
+ mPanel.add(spec);
+ // TODO notify user the app isn't publishing the tile, but it now can be!
+ }
mPanel.closeDetail();
return true;
}