Permalink
Browse files

kill app long press back

  • Loading branch information...
rascarlo committed Nov 12, 2014
1 parent b382699 commit cc7cbd4c359bb88d0f482ca19b1c2285643cbe71
@@ -4848,6 +4848,12 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
*/
public static final String SLEEP_TIMEOUT = "sleep_timeout";
/**
* Whether to allow killing of the foreground app by long-pressing the Back button
* @hide
*/
public static final String KILL_APP_LONGPRESS_BACK = "kill_app_longpress_back";
/**
* This are the settings to be backed up.
*
@@ -0,0 +1,63 @@
package com.android.internal.util.rastapop;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import java.util.List;
public class DevUtils {
/**
* Kills the top most / most recent user application, but leaves out the launcher.
* This is function governed by {@link Settings.Secure.KILL_APP_LONGPRESS_BACK}.
*
* @param context the current context, used to retrieve the package manager.
* @return {@code true} when a user application was found and closed.
*/
public static boolean killForegroundApplication(Context context) {
boolean targetKilled = false;
try {
final Intent intent = new Intent(Intent.ACTION_MAIN);
String defaultHomePackage = "com.android.launcher";
intent.addCategory(Intent.CATEGORY_HOME);
final ResolveInfo res = context.getPackageManager().resolveActivity(intent, 0);
if (res.activityInfo != null && !res.activityInfo.packageName.equals("android")) {
defaultHomePackage = res.activityInfo.packageName;
}
IActivityManager am = ActivityManagerNative.getDefault();
List<RunningAppProcessInfo> apps = am.getRunningAppProcesses();
for (RunningAppProcessInfo appInfo : apps) {
int uid = appInfo.uid;
// Make sure it's a foreground user application (not system,
// root, phone, etc.)
if (uid >= Process.FIRST_APPLICATION_UID && uid <= Process.LAST_APPLICATION_UID
&& appInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (appInfo.pkgList != null && (appInfo.pkgList.length > 0)) {
for (String pkg : appInfo.pkgList) {
if (!pkg.equals("com.android.systemui") && !pkg.equals(defaultHomePackage)) {
am.forceStopPackage(pkg, UserHandle.USER_CURRENT);
targetKilled = true;
break;
}
}
} else {
Process.killProcess(appInfo.pid);
targetKilled = true;
break;
}
}
}
} catch (RemoteException remoteException) {
// Do nothing; just let it go.
}
return targetKilled;
}
}
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2009, 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.
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- kill app long press back -->
<integer name="config_backKillTimeout">1500</integer>
</resources>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- kill app long press back -->
<string name="app_killed_message">Application killed. Happy now?</string>
</resources>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- kill app long press back -->
<java-symbol type="string" name="app_killed_message" />
<java-symbol type="integer" name="config_backKillTimeout" />
</resources>
@@ -100,6 +100,7 @@
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.policy.IKeyguardService;
@@ -108,6 +109,7 @@
import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate;
import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate.ShowListener;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.rastapop.DevUtils;
import com.android.internal.widget.PointerLocationView;
import com.android.server.LocalServices;
@@ -358,6 +360,7 @@ public void onShown(IBinder windowToken) {
boolean mHasSoftInput = false;
boolean mTranslucentDecorEnabled = true;
int mBackKillTimeout;
int mPointerLocationMode = 0; // guarded by mLock
// The last window we were told about in focusChanged.
@@ -901,6 +904,16 @@ public void run() {
}
};
Runnable mBackLongPress = new Runnable() {
public void run() {
if (DevUtils.killForegroundApplication(mContext)) {
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
Toast.makeText(mContext, R.string.app_killed_message, Toast.LENGTH_SHORT).show();
// Do nothing; just let it go.
}
}
};
@Override
public void showGlobalActions() {
mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
@@ -1022,6 +1035,8 @@ public void init(Context context, IWindowManager windowManager,
com.android.internal.R.bool.config_lidControlsSleep);
mTranslucentDecorEnabled = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enableTranslucentDecor);
mBackKillTimeout = mContext.getResources().getInteger(
com.android.internal.R.integer.config_backKillTimeout);
readConfigurationDependentBehaviors();
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
@@ -2186,6 +2201,10 @@ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int p
mPendingMetaAction = false;
}
if (keyCode == KeyEvent.KEYCODE_BACK && !down) {
mHandler.removeCallbacks(mBackLongPress);
}
// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second
@@ -2361,6 +2380,13 @@ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int p
mHandler.post(mScreenshotRunnable);
}
return -1;
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.KILL_APP_LONGPRESS_BACK, 0, UserHandle.USER_CURRENT) == 1) {
if (down && repeatCount == 0) {
mHandler.postDelayed(mBackLongPress, mBackKillTimeout);
}
}
} else if (keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP
|| keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN) {
if (down) {

0 comments on commit cc7cbd4

Please sign in to comment.