Skip to content

Commit

Permalink
SystemUI: make long pressing recent switch to last app
Browse files Browse the repository at this point in the history
With this patch, long pressing the recents key on the navigation bar
will attempt to switch to your last application in the activity stack
before the active one.

The user's current home launcher package is ignored as well as SystemUI (so that
RecentsActivity does not influence the behavior).

Change-Id: I38771e0fce16b55bb5186af47115b4e812cb60b0
Signed-off-by: Roman Birg <roman@cyngn.com>
Signed-off-by: Adnan Begovic <adnan@cyngn.com>
  • Loading branch information
romanbb authored and Adnan Begovic committed Dec 10, 2014
1 parent ccb215c commit d9ad9af
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 1 deletion.
37 changes: 37 additions & 0 deletions packages/SystemUI/res/anim/last_app_in.xml
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The CyanogenMod 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.
-->

<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/linear">

<translate android:fromXDelta="0%" android:toXDelta="-35%"
android:zAdjustment="bottom"
android:duration="@android:integer/config_shortAnimTime"
/>
<scale android:fromXScale="0.80" android:toXScale="1.0"
android:fromYScale="0.80" android:toYScale="1.0"
android:pivotX="50%" android:pivotY="50%"
android:duration="@android:integer/config_shortAnimTime"
/>
<translate android:fromXDelta="-35%" android:toXDelta="35%"
android:zAdjustment="top"
android:startOffset="@android:integer/config_shortAnimTime"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha android:fromAlpha="0.6" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>
37 changes: 37 additions & 0 deletions packages/SystemUI/res/anim/last_app_out.xml
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The CyanogenMod 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.
-->

<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/linear">

<translate android:fromXDelta="-35%" android:toXDelta="35%"
android:zAdjustment="top"
android:duration="@android:integer/config_shortAnimTime"
/>
<scale android:fromXScale="1.0" android:toXScale="0.80"
android:fromYScale="1.0" android:toYScale="0.80"
android:pivotX="50%" android:pivotY="50%"
android:duration="@android:integer/config_shortAnimTime"
/>
<translate android:fromXDelta="35%" android:toXDelta="-35%"
android:zAdjustment="bottom"
android:startOffset="@android:integer/config_shortAnimTime"
android:duration="@android:integer/config_shortAnimTime"
/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.6"
android:duration="@android:integer/config_shortAnimTime"
/>
</set>
Expand Up @@ -38,6 +38,7 @@
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.IActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
Expand All @@ -47,6 +48,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
Expand Down Expand Up @@ -4305,6 +4308,7 @@ public void onScreenTurnedOn() {
private void handleLongPressBackRecents(View v) {
try {
boolean sendBackLongPress = false;
boolean hijackRecentsLongPress = false;
IActivityManager activityManager = ActivityManagerNative.getDefault();
boolean isAccessiblityEnabled = mAccessibilityManager.isEnabled();
if (activityManager.isInLockTaskMode() && !isAccessiblityEnabled) {
Expand All @@ -4318,12 +4322,16 @@ private void handleLongPressBackRecents(View v) {
// If we aren't pressing recents right now then they presses
// won't be together, so send the standard long-press action.
sendBackLongPress = true;
} else if ((v.getId() == R.id.recent_apps)) {
hijackRecentsLongPress = true;
}
mLastLockToAppLongPress = time;
} else {
// If this is back still need to handle sending the long-press event.
if (v.getId() == R.id.back) {
sendBackLongPress = true;
} else if (v.getId() == R.id.recent_apps) {
hijackRecentsLongPress = true;
} else if (isAccessiblityEnabled && activityManager.isInLockTaskMode()) {
// When in accessibility mode a long press that is recents (not back)
// should stop lock task.
Expand All @@ -4335,11 +4343,48 @@ private void handleLongPressBackRecents(View v) {
keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
}

if (hijackRecentsLongPress) {
final ActivityManager am =
(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.RunningTaskInfo lastTask = getLastTask(am);

if (lastTask != null) {
if (DEBUG) Log.d(TAG, "switching to " + lastTask.topActivity.getPackageName());
final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.last_app_in, R.anim.last_app_out);
am.moveTaskToFront(lastTask.id, ActivityManager.MOVE_TASK_NO_USER_ACTION,
opts.toBundle());
}
}
} catch (RemoteException e) {
Log.d(TAG, "Unable to reach activity manager", e);
}
}

private ActivityManager.RunningTaskInfo getLastTask(final ActivityManager am) {
final String defaultHomePackage = resolveCurrentLauncherPackage();
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(5);

for (int i = 1; i < tasks.size(); i++) {
String packageName = tasks.get(i).topActivity.getPackageName();
if (!packageName.equals(defaultHomePackage)
&& !packageName.equals(mContext.getPackageName())) {
return tasks.get(i);
}
}

return null;
}

private String resolveCurrentLauncherPackage() {
final Intent launcherIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME);
final PackageManager pm = mContext.getPackageManager();
final ResolveInfo launcherInfo = pm.resolveActivity(launcherIntent, 0);
return launcherInfo.activityInfo.packageName;
}

// Recents

@Override
Expand Down
Expand Up @@ -73,13 +73,15 @@ public class KeyButtonView extends ImageView {
private Animator mAnimateToQuiescent = new ObjectAnimator();

private PowerManager mPm;
private boolean mPerformedLongClick;

private final Runnable mCheckLongPress = new Runnable() {
public void run() {
if (isPressed()) {
// Log.d("KeyButtonView", "longpressed: " + this);
if (isLongClickable()) {
// Just an old-fashioned ImageView
mPerformedLongClick = true;
performLongClick();
} else {
sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
Expand Down Expand Up @@ -228,13 +230,14 @@ && x < getWidth() + mTouchSlop
}
} else {
// no key code, just a regular ImageView
if (doIt) {
if (doIt && !mPerformedLongClick) {
performClick();
}
}
if (mSupportsLongpress) {
removeCallbacks(mCheckLongPress);
}
mPerformedLongClick = false;
break;
}

Expand Down

0 comments on commit d9ad9af

Please sign in to comment.