Skip to content

Commit a46f768

Browse files
dsandlerAndroid (Google) Code Review
authored andcommitted
Merge "Long-press a notification to find out who sent it."
2 parents 5df19f0 + f7a1956 commit a46f768

File tree

7 files changed

+123
-3
lines changed

7 files changed

+123
-3
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/* apps/common/assets/default/default/skins/StatusBar.xml
4+
**
5+
** Copyright 2012, The Android Open Source Project
6+
**
7+
** Licensed under the Apache License, Version 2.0 (the "License");
8+
** you may not use this file except in compliance with the License.
9+
** You may obtain a copy of the License at
10+
**
11+
** http://www.apache.org/licenses/LICENSE-2.0
12+
**
13+
** Unless required by applicable law or agreed to in writing, software
14+
** distributed under the License is distributed on an "AS IS" BASIS,
15+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
** See the License for the specific language governing permissions and
17+
** limitations under the License.
18+
*/
19+
-->
20+
<menu xmlns:android="http://schemas.android.com/apk/res/android">
21+
<item android:id="@+id/notification_inspect_item" android:title="@string/status_bar_notification_inspect_item_title" />
22+
</menu>

packages/SystemUI/res/values/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,4 +365,8 @@
365365

366366
<!-- Description of the desk dock action that invokes the Android Dreams screen saver feature -->
367367
<string name="dreams_dock_launcher">Activate screen saver</string>
368+
369+
<!-- Title shown in notification popup for inspecting the responsible
370+
application -->
371+
<string name="status_bar_notification_inspect_item_title">App info</string>
368372
</resources>

packages/SystemUI/src/com/android/systemui/SwipeHelper.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@
2323
import android.animation.ValueAnimator;
2424
import android.animation.ValueAnimator.AnimatorUpdateListener;
2525
import android.graphics.RectF;
26+
import android.os.Handler;
2627
import android.util.Log;
28+
import android.view.accessibility.AccessibilityEvent;
2729
import android.view.animation.LinearInterpolator;
2830
import android.view.MotionEvent;
2931
import android.view.VelocityTracker;
3032
import android.view.View;
33+
import android.view.ViewConfiguration;
3134

3235
public class SwipeHelper implements Gefingerpoken {
3336
static final String TAG = "com.android.systemui.SwipeHelper";
@@ -57,6 +60,7 @@ public class SwipeHelper implements Gefingerpoken {
5760

5861
private float mPagingTouchSlop;
5962
private Callback mCallback;
63+
private Handler mHandler;
6064
private int mSwipeDirection;
6165
private VelocityTracker mVelocityTracker;
6266

@@ -67,15 +71,24 @@ public class SwipeHelper implements Gefingerpoken {
6771
private boolean mCanCurrViewBeDimissed;
6872
private float mDensityScale;
6973

74+
private boolean mLongPressSent;
75+
private View.OnLongClickListener mLongPressListener;
76+
private Runnable mWatchLongPress;
77+
7078
public SwipeHelper(int swipeDirection, Callback callback, float densityScale,
7179
float pagingTouchSlop) {
7280
mCallback = callback;
81+
mHandler = new Handler();
7382
mSwipeDirection = swipeDirection;
7483
mVelocityTracker = VelocityTracker.obtain();
7584
mDensityScale = densityScale;
7685
mPagingTouchSlop = pagingTouchSlop;
7786
}
7887

88+
public void setLongPressListener(View.OnLongClickListener listener) {
89+
mLongPressListener = listener;
90+
}
91+
7992
public void setDensityScale(float densityScale) {
8093
mDensityScale = densityScale;
8194
}
@@ -167,38 +180,68 @@ public static void invalidateGlobalRegion(View view, RectF childBounds) {
167180
}
168181
}
169182

183+
private void removeLongPressCallback() {
184+
if (mWatchLongPress != null) {
185+
mHandler.removeCallbacks(mWatchLongPress);
186+
}
187+
}
188+
170189
public boolean onInterceptTouchEvent(MotionEvent ev) {
171190
final int action = ev.getAction();
172191

173192
switch (action) {
174193
case MotionEvent.ACTION_DOWN:
175194
mDragging = false;
195+
mLongPressSent = false;
176196
mCurrView = mCallback.getChildAtPosition(ev);
177197
mVelocityTracker.clear();
178198
if (mCurrView != null) {
179199
mCurrAnimView = mCallback.getChildContentView(mCurrView);
180200
mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
181201
mVelocityTracker.addMovement(ev);
182202
mInitialTouchPos = getPos(ev);
203+
204+
if (mLongPressListener != null) {
205+
if (mWatchLongPress == null) {
206+
mWatchLongPress = new Runnable() {
207+
@Override
208+
public void run() {
209+
if (mCurrView != null && !mLongPressSent) {
210+
mLongPressSent = true;
211+
mCurrView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
212+
mLongPressListener.onLongClick(mCurrView);
213+
}
214+
}
215+
};
216+
}
217+
mHandler.postDelayed(mWatchLongPress, ViewConfiguration.getLongPressTimeout());
218+
}
219+
183220
}
184221
break;
222+
185223
case MotionEvent.ACTION_MOVE:
186-
if (mCurrView != null) {
224+
if (mCurrView != null && !mLongPressSent) {
187225
mVelocityTracker.addMovement(ev);
188226
float pos = getPos(ev);
189227
float delta = pos - mInitialTouchPos;
190228
if (Math.abs(delta) > mPagingTouchSlop) {
191229
mCallback.onBeginDrag(mCurrView);
192230
mDragging = true;
193231
mInitialTouchPos = getPos(ev) - getTranslation(mCurrAnimView);
232+
233+
removeLongPressCallback();
194234
}
195235
}
236+
196237
break;
238+
197239
case MotionEvent.ACTION_UP:
198240
case MotionEvent.ACTION_CANCEL:
199241
mDragging = false;
200242
mCurrView = null;
201243
mCurrAnimView = null;
244+
mLongPressSent = false;
202245
break;
203246
}
204247
return mDragging;
@@ -269,6 +312,10 @@ public void onAnimationUpdate(ValueAnimator animation) {
269312
}
270313

271314
public boolean onTouchEvent(MotionEvent ev) {
315+
if (mLongPressSent) {
316+
return true;
317+
}
318+
272319
if (!mDragging) {
273320
return false;
274321
}

packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,20 @@
2626
import android.content.pm.ApplicationInfo;
2727
import android.content.pm.PackageManager.NameNotFoundException;
2828
import android.graphics.Rect;
29+
import android.net.Uri;
2930
import android.os.Build;
3031
import android.os.Handler;
3132
import android.os.IBinder;
3233
import android.os.Message;
3334
import android.os.RemoteException;
3435
import android.os.ServiceManager;
36+
import android.provider.Settings;
3537
import android.util.Log;
3638
import android.util.Slog;
3739
import android.view.Display;
3840
import android.view.IWindowManager;
3941
import android.view.LayoutInflater;
42+
import android.view.MenuItem;
4043
import android.view.MotionEvent;
4144
import android.view.View;
4245
import android.view.ViewGroup;
@@ -45,6 +48,7 @@
4548
import android.view.WindowManagerImpl;
4649
import android.widget.LinearLayout;
4750
import android.widget.RemoteViews;
51+
import android.widget.PopupMenu;
4852

4953
import com.android.internal.statusbar.IStatusBarService;
5054
import com.android.internal.statusbar.StatusBarIcon;
@@ -214,6 +218,39 @@ protected void applyLegacyRowBackground(StatusBarNotification sbn, View content)
214218
}
215219
}
216220

221+
private void startApplicationDetailsActivity(String packageName) {
222+
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
223+
Uri.fromParts("package", packageName, null));
224+
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
225+
mContext.startActivity(intent);
226+
}
227+
228+
protected View.OnLongClickListener getNotificationLongClicker() {
229+
return new View.OnLongClickListener() {
230+
@Override
231+
public boolean onLongClick(View v) {
232+
final String packageNameF = (String) v.getTag();
233+
if (packageNameF == null) return false;
234+
PopupMenu popup = new PopupMenu(mContext, v);
235+
popup.getMenuInflater().inflate(R.menu.notification_popup_menu, popup.getMenu());
236+
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
237+
public boolean onMenuItemClick(MenuItem item) {
238+
if (item.getItemId() == R.id.notification_inspect_item) {
239+
startApplicationDetailsActivity(packageNameF);
240+
animateCollapse();
241+
} else {
242+
return false;
243+
}
244+
return true;
245+
}
246+
});
247+
popup.show();
248+
249+
return true;
250+
}
251+
};
252+
}
253+
217254
public void dismissIntruder() {
218255
// pass
219256
}
@@ -355,6 +392,9 @@ protected boolean inflateViews(NotificationData.Entry entry, ViewGroup parent)
355392
Context.LAYOUT_INFLATER_SERVICE);
356393
View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
357394

395+
// for blaming (see SwipeHelper.setLongPressListener)
396+
row.setTag(sbn.pkg);
397+
358398
// XXX: temporary: while testing big notifications, auto-expand all of them
359399
ViewGroup.LayoutParams lp = row.getLayoutParams();
360400
if (large != null) {

packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ protected View makeStatusBarView() {
314314

315315
mExpandedDialog = new ExpandedDialog(context);
316316
mPile = (NotificationRowLayout)expanded.findViewById(R.id.latestItems);
317+
mPile.setLongPressListener(getNotificationLongClicker());
317318
mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
318319

319320
mClearButton = expanded.findViewById(R.id.clear_all_button);

packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ public void onChildViewRemoved(View parent, View child) {
104104
mExpandHelper = new ExpandHelper(mContext, this, minHeight, maxHeight);
105105
}
106106

107+
public void setLongPressListener(View.OnLongClickListener listener) {
108+
mSwipeHelper.setLongPressListener(listener);
109+
}
110+
107111
public void setAnimateBounds(boolean anim) {
108112
mAnimateBounds = anim;
109113
}

packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import com.android.systemui.statusbar.policy.CompatModeButton;
7575
import com.android.systemui.statusbar.policy.LocationController;
7676
import com.android.systemui.statusbar.policy.NetworkController;
77+
import com.android.systemui.statusbar.policy.NotificationRowLayout;
7778
import com.android.systemui.statusbar.policy.Prefs;
7879

7980
import java.io.FileDescriptor;
@@ -153,7 +154,7 @@ public class TabletStatusBar extends BaseStatusBar implements
153154
int mNotificationPeekTapDuration;
154155
int mNotificationFlingVelocity;
155156

156-
ViewGroup mPile;
157+
NotificationRowLayout mPile;
157158

158159
BatteryController mBatteryController;
159160
BluetoothController mBluetoothController;
@@ -375,8 +376,9 @@ protected void addPanelWindows() {
375376

376377
mRecentButton.setOnTouchListener(mRecentsPanel);
377378

378-
mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content);
379+
mPile = (NotificationRowLayout)mNotificationPanel.findViewById(R.id.content);
379380
mPile.removeAllViews();
381+
mPile.setLongPressListener(getNotificationLongClicker());
380382

381383
ScrollView scroller = (ScrollView)mPile.getParent();
382384
scroller.setFillViewport(true);

0 commit comments

Comments
 (0)