一、kernel部分主要发按键信息到android上层。

diff --git a/kernel/drivers/misc/key/reset_key.c b/kernel-4.14/drivers/misc/key/reset_key.c
index 127319a29fa..8d954fc28c5 100755
--- a/kernel/drivers/misc/key/reset_key.c
+++ b/kernel/drivers/misc/key/reset_key.c
@@ -12,12 +12,14 @@#include <linux/jiffies.h>#include <linux/reset.h>#include <linux/reboot.h>
-
+#include <linux/input.h>
+#include <linux/miscdevice.h>struct reset_key {struct device_node *nd;int reset_gpio;unsigned int irq;struct delayed_work rest_work;
+    struct input_dev *reset_key_dev ;};struct reset_key key;
@@ -28,39 +30,53 @@ struct file_operations reset_key_fops = {struct miscdevice reset_key_misc = {.minor = MISC_DYNAMIC_MINOR,
-   .name = "reset_key",
-   .fops = &reset_key_fops,
+   .name = "reset_key",
+   .fops = &reset_key_fops,};void rest_work_func(struct work_struct *work){-    int value = 0;
-
+    int value = 0 ;
+    static int key_is_down = 0;
+  disable_irq(key.irq);value = gpio_get_value(key.reset_gpio);
-    printk("[%s] value = %d\n",__func__,value);
+    printk(" [%s] value = %d  irq=%d\n",__func__,value,key.irq);if(1 == value){// orderly_reboot();
-        kernel_restart(NULL);
+       // kernel_restart(NULL);// 重置// reset_control_reset(struct reset_control *rstc);
-        irq_set_irq_type(key.irq,IRQF_TRIGGER_FALLING);
+     //   test_temp = irq_set_irq_type(key.irq,IRQ_TYPE_LEVEL_LOW);
+  if(key_is_down){
+  input_report_key(key.reset_key_dev, KEY_F10, 0);
+  input_sync(key.reset_key_dev);
+  }
+  key_is_down = 0;printk("[%s] if value = %d\n",__func__,value);}else{// orderly_reboot();
-        irq_set_irq_type(key.irq,IRQF_TRIGGER_RISING);
+      //   test_temp = irq_set_irq_type(key.irq,IRQ_TYPE_LEVEL_HIGH);
+  if(key_is_down == 0){
+  input_report_key(key.reset_key_dev, KEY_F10, 1);
+  input_sync(key.reset_key_dev);
+  key_is_down = 1;
+  }
+  printk("[%s] else value = %d\n",__func__,value);}
+  enable_irq(key.irq);//  orderly_reboot();}irqreturn_t reset_key_irq_handler(int data, void *arg){-    schedule_delayed_work(&key.rest_work,msecs_to_jiffies(20));
+    schedule_delayed_work(&key.rest_work, msecs_to_jiffies(50));
+   // schedule_work  结构体名不一样return IRQ_HANDLED;}
@@ -93,14 +109,15 @@ int reset_key_probe(struct platform_device *dev)printk("gpio_request failed\n");return -1;}
-
+gpio_direction_input(key.reset_gpio);// INIT_WORK(&key.rest_work,rest_work_func);INIT_DELAYED_WORK(&key.rest_work,rest_work_func);//中断注册 中断下文用工作队列key.irq = irq_of_parse_and_map(key.nd,0);
-    ret = request_irq(key.irq,reset_key_irq_handler,IRQF_TRIGGER_FALLING,
+    ret = request_irq(key.irq,reset_key_irq_handler,IRQ_TYPE_EDGE_BOTH,"reset_key_irq", NULL);
+  //gpio_set_debounce(key.reset_gpio, 10 * 1000);if(ret < 0){printk("request_irq failed\n");
@@ -115,6 +132,14 @@ int reset_key_probe(struct platform_device *dev)printk("misc_register failed\n");return -1;}
+  key.reset_key_dev = input_allocate_device();
+  key.reset_key_dev->name = "reset-key";
+  __set_bit(EV_KEY, key.reset_key_dev->evbit);
+  __set_bit(KEY_F10, key.reset_key_dev->keybit);
+  ret = input_register_device(key.reset_key_dev);
+  if(ret){
+      printk("key.reset_key_dev register  input err!\n");
+  }//定时器  可以使用函数来消抖return 0;}
--
2.25.1

二、frameworks里面PhoneWindowManager.java接收kernel 上传上来的按键信息,然后发广播进行恢复出厂设置。核心是发广播。用event.getDownTime()和 event.getEventTime()计算按键的时间。

三、frameworks里面处理按键的部分的代码如下:

---frameworks/base/api/test-current.txt          |  2 +-.../base/core/java/android/view/KeyEvent.java |  4 +++-frameworks/base/core/res/res/values/attrs.xml |  1 +frameworks/base/data/keyboards/Generic.kl     |  2 +-.../server/policy/PhoneWindowManager.java     | 19 +++++++++++++++++++frameworks/native/include/android/keycodes.h  |  4 +++-.../native/include/input/InputEventLabels.h   |  1 +7 files changed, 29 insertions(+), 4 deletions(-)diff --git a/frameworks/base/api/test-current.txt b/frameworks/base/api/test-current.txt
index 539aaa0a5fa..cff226972b1 100644
--- a/frameworks/base/api/test-current.txt
+++ b/frameworks/base/api/test-current.txt
@@ -5125,7 +5125,7 @@ package android.view {public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable {method public static String actionToString(int);method public final void setDisplayId(int);
-    field public static final int LAST_KEYCODE = 289; // 0x121
+    field public static final int LAST_KEYCODE = 290; // 0x122}public final class KeyboardShortcutGroup implements android.os.Parcelable {
diff --git a/frameworks/base/core/java/android/view/KeyEvent.java b/frameworks/base/core/java/android/view/KeyEvent.java
index f1bc5ee216b..7a8e81486f2 100644
--- a/frameworks/base/core/java/android/view/KeyEvent.java
+++ b/frameworks/base/core/java/android/view/KeyEvent.java
@@ -826,12 +826,14 @@ public class KeyEvent extends InputEvent implements Parcelable {public static final int KEYCODE_PROFILE_SWITCH = 288;/** @hide */public static final int KEYCODE_SCREEN_SHOT = 289;
+    /** @hide */
+    public static final int KEYCODE_FACTORY_RESET = 290;/*** Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.* @hide*/@TestApi
-    public static final int LAST_KEYCODE = KEYCODE_SCREEN_SHOT;
+    public static final int LAST_KEYCODE = KEYCODE_FACTORY_RESET;// NOTE: If you add a new keycode here you must also add it to://  isSystem()
diff --git a/frameworks/base/core/res/res/values/attrs.xml b/frameworks/base/core/res/res/values/attrs.xml
index cfad781a8e6..0aeb8bb7726 100644
--- a/frameworks/base/core/res/res/values/attrs.xml
+++ b/frameworks/base/core/res/res/values/attrs.xml
@@ -1927,6 +1927,7 @@<enum name="KEYCODE_THUMBS_DOWN" value="287" /><enum name="KEYCODE_PROFILE_SWITCH" value="288" /><enum name="KEYCODE_SCREEN_SHOT" value="289" />
+        <enum name="KEYCODE_FACTORY_RESET" value="290" /></attr><!-- ***************************************************************** -->
diff --git a/frameworks/base/data/keyboards/Generic.kl b/frameworks/base/data/keyboards/Generic.kl
index 28be888fe0c..fa461d22ca2 100644
--- a/frameworks/base/data/keyboards/Generic.kl
+++ b/frameworks/base/data/keyboards/Generic.kl
@@ -87,7 +87,7 @@ key 64    F6key 65    F7key 66    F8key 67    F9
-key 68    F10
+key 68    FACTORY_RESETkey 69    NUM_LOCKkey 70    SCROLL_LOCKkey 71    NUMPAD_7
diff --git a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
index f0db3107b72..c8675119557 100644
--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -577,6 +577,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {private boolean mScreenshotChordPowerKeyTriggered;private long mScreenshotChordPowerKeyTime;private long mScreenshotDownKeyTime;
+    private static final long FACTORY_RESET_DELAY_MILLIS = 8*1000;
+    private long mFactoryResetDownKeyTime;
+    private long mFactoryResetEventKeyTime;
+    private long mFactoryResetEndkeyTime;// Ringer toggle should reuse timing and triggering from screenshot power and a11y vol upprivate int mRingerToggleChord = VOLUME_HUSH_OFF;
@@ -1358,6 +1362,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());}}
+
+    private void factoryReset(){
+        long endKeyTime = mFactoryResetEventKeyTime - mFactoryResetDownKeyTime;
+        if(endKeyTime >= FACTORY_RESET_DELAY_MILLIS){
+            Intent intent = new Intent("android.intent.action.MASTER_CLEAR");
+            intent.setPackage("android");
+            mContext.sendBroadcast(intent);
+       }
+    }private void interceptAccessibilityShortcutChord() {if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(isKeyguardLocked())&& mScreenshotChordVolumeDownKeyTriggered && mA11yShortcutChordVolumeUpKeyTriggered
@@ -3722,6 +3735,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {}break;}
+            case KeyEvent.KEYCODE_FACTORY_RESET:{
+                 mFactoryResetDownKeyTime = event.getDownTime();
+                 mFactoryResetEventKeyTime = event.getEventTime();
+                 factoryReset();
+                 break;
+            }case KeyEvent.KEYCODE_VOLUME_DOWN:case KeyEvent.KEYCODE_VOLUME_UP:case KeyEvent.KEYCODE_VOLUME_MUTE: {
diff --git a/frameworks/native/include/android/keycodes.h b/frameworks/native/include/android/keycodes.h
index 9061eeeba95..9d9944e7087 100644
--- a/frameworks/native/include/android/keycodes.h
+++ b/frameworks/native/include/android/keycodes.h
@@ -778,7 +778,9 @@ enum {* May be consumed by system to switch current viewer profile. */AKEYCODE_PROFILE_SWITCH = 288,/** @hide */
-    AKEYCODE_SCREEN_SHOT = 289
+    AKEYCODE_SCREEN_SHOT = 289,
+    /** @hide */
+    AKEYCODE_FACTORY_RESET = 290// NOTE: If you add a new keycode here you must also add it to several other files.//       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.};
diff --git a/frameworks/native/include/input/InputEventLabels.h b/frameworks/native/include/input/InputEventLabels.h
index 0891d00a84d..5773a829e1b 100644
--- a/frameworks/native/include/input/InputEventLabels.h
+++ b/frameworks/native/include/input/InputEventLabels.h
@@ -329,6 +329,7 @@ static const InputEventLabel KEYCODES[] = {DEFINE_KEYCODE(THUMBS_DOWN),DEFINE_KEYCODE(PROFILE_SWITCH),DEFINE_KEYCODE(SCREEN_SHOT),
+    DEFINE_KEYCODE(FACTORY_RESET),{ nullptr, 0 }
--
2.25.1

四、收到广播后进入恢复出厂设置

1、\frameworks\base\core\res\AndroidManifest.xml

2、frameworks\base\services\core\java\com\android\server\MasterClearReceiver.java

/** Copyright (C) 2008 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.*/package com.android.server;import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.RecoverySystem;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import android.view.WindowManager;import com.android.internal.R;import java.io.IOException;public class MasterClearReceiver extends BroadcastReceiver {private static final String TAG = "MasterClear";private boolean mWipeExternalStorage;private boolean mWipeEsims;@Overridepublic void onReceive(final Context context, final Intent intent) {if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {if (!"google.com".equals(intent.getStringExtra("from"))) {Slog.w(TAG, "Ignoring master clear request -- not from trusted server.");return;}}if (Intent.ACTION_MASTER_CLEAR.equals(intent.getAction())) {Slog.w(TAG, "The request uses the deprecated Intent#ACTION_MASTER_CLEAR, "+ "Intent#ACTION_FACTORY_RESET should be used instead.");}if (intent.hasExtra(Intent.EXTRA_FORCE_MASTER_CLEAR)) {Slog.w(TAG, "The request uses the deprecated Intent#EXTRA_FORCE_MASTER_CLEAR, "+ "Intent#EXTRA_FORCE_FACTORY_RESET should be used instead.");}final String factoryResetPackage = context.getString(com.android.internal.R.string.config_factoryResetPackage);if (Intent.ACTION_FACTORY_RESET.equals(intent.getAction())&& !TextUtils.isEmpty(factoryResetPackage)) {intent.setPackage(factoryResetPackage).setComponent(null);context.sendBroadcastAsUser(intent, UserHandle.SYSTEM);return;}final boolean shutdown = intent.getBooleanExtra("shutdown", false);final String reason = intent.getStringExtra(Intent.EXTRA_REASON);mWipeExternalStorage = intent.getBooleanExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);mWipeEsims = intent.getBooleanExtra(Intent.EXTRA_WIPE_ESIMS, false);final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false)|| intent.getBooleanExtra(Intent.EXTRA_FORCE_FACTORY_RESET, false);Slog.w(TAG, "!!! FACTORY RESET !!!");// The reboot call is blocking, so we need to do it on another thread.Thread thr = new Thread("Reboot") {@Overridepublic void run() {try {RecoverySystem.rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims);Log.wtf(TAG, "Still running after master clear?!");} catch (IOException e) {Slog.e(TAG, "Can't perform master clear/factory reset", e);} catch (SecurityException e) {Slog.e(TAG, "Can't perform master clear/factory reset", e);}}};if (mWipeExternalStorage) {// thr will be started at the end of this task.new WipeDataTask(context, thr).execute();} else {thr.start();}}private class WipeDataTask extends AsyncTask<Void, Void, Void> {private final Thread mChainedTask;private final Context mContext;private final ProgressDialog mProgressDialog;public WipeDataTask(Context context, Thread chainedTask) {mContext = context;mChainedTask = chainedTask;mProgressDialog = new ProgressDialog(context);}@Overrideprotected void onPreExecute() {mProgressDialog.setIndeterminate(true);mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);mProgressDialog.setMessage(mContext.getText(R.string.progress_erasing));mProgressDialog.show();}@Overrideprotected Void doInBackground(Void... params) {Slog.w(TAG, "Wiping adoptable disks");if (mWipeExternalStorage) {StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);sm.wipeAdoptableDisks();}return null;}@Overrideprotected void onPostExecute(Void result) {mProgressDialog.dismiss();mChainedTask.start();}}
}

五、长按相应的按键后,机器会重启进入恢复出厂设置,看log,又相应的打印。

2021-11-12 Android 11 长按按键进入恢复出厂设置的实现方法-PhoneWindowManager里面用发广播的模式相关推荐

  1. 恢复出厂设置android手机号码,安卓手机怎么正确恢复出厂设置的简单方法

    手机难免会出现一些比较难处理的一些现象,比如手机机身无法清理的软件残骸导致的手机卡机现象,不知所云的设置,找不到设置按钮了,严重影响使用感觉,这都是难免出现的一些问题这个时候可能就需要通过一些强硬的手 ...

  2. Android知识点 431 -- recovery 强制执行恢复出厂设置(Rescue Party)

    转载原文:https://www.cnblogs.com/codeking100/p/10339258.html 返回知识列表:Android知识点list 1 Incremented rescue ...

  3. Android L集成新特性之恢复出厂设置保护之如何实现,类似苹果ID的远程控制功能

    在Android 5.0 以后以后的设备默认开启恢复出厂设置保护功能,主要是为了减少用户在丢失手机的带来的损失,比如手机上的一些照片和其他一些重要资料被偷盗者非法利用.此功能可以让用户可以通过谷歌账号 ...

  4. Android 8.1 recovery 强制执行恢复出厂设置

    在工作中开发过程中,我们经常调试apk,然后推进机器里面去会已停止运行,你点几下就会恢复出厂设置. 意思是说,不能加载正常的安卓系统,可能数据损坏,如果你继续收到此消息,请执行恢复出厂设置擦除所有的用 ...

  5. Android 如何才能捕获系统的恢复出厂设置事件

    点击恢复出厂设置后,系统重启,再次进入系统后,一切数据都被清空,怎样可以得知之前到底是否恢复出厂设置了呢?怎样可以标记 恢复出厂设置事件 ?我希望在系统重启后,根据客户需求,判断出刚刚恢复过出厂设置, ...

  6. android恢复出厂设置,关机,重启以及系统升级和充电器连接广播

    恢复出厂设置 <uses-permission android:name="android.permission.MASTER_CLEAR" /> if (Build. ...

  7. Android 8.0接收通知后会手机崩溃,闪屏,恢复出厂设置的解决方法

    最近用极光推送,发现有新的SDK,就试试用.我的手机是Nexus 6P,原生8.0,结果一更新,手机就不断闪屏,系统崩溃,说要恢复出厂设置了 幸亏重启前截停了.然后求助极光推送,可得到的答复不是SDK ...

  8. Android 8.1中Settings中恢复出厂设置流程

    1.Settings中点击重置选项后进入的布局如下 packages/apps/Settings/res/xml/reset_dashboard_fragment.xml <?xml versi ...

  9. 魅蓝s6启动android密码_魅蓝s6怎么恢复出厂设置?忘记密码怎么办

    魅蓝s6怎么恢复出厂设置?忘记密码怎么办?手机是现代生活必不可少的工具之一,在使用时我们常常会忘记手机密码.本次就给大家介绍手机密码忘了怎么恢复出厂设置,快来看看吧. 我们知道手机恢复出厂设置的注意事 ...

最新文章

  1. 亲历dataguard的一些经验问答题
  2. 从古希腊神话说起,讲讲英语里的偏旁部首
  3. JVM垃圾回收机制总结(3) :按代垃圾收集器
  4. 除了游戏和医疗,腾讯区块链还准备做什么?
  5. 使用BeetleX.ESDoc构建文档搜索功能
  6. java编写猫抓老鼠程序_Java抓鱼程序
  7. linux上ftp和lftp冲突,Linux FTP客户端 Lftp 使用方法,该如何解决
  8. oracle 调用java 类_oracle数据库PL SQL调用Java类程序代码
  9. #ifndef/#define/#endif 防止该头文件被重复引用
  10. 易语言与python爬虫_022 Python爬虫原理与python爬虫实例大全
  11. php支付宝接口开发流程,对接支付宝支付接口开发详细步骤(证书签名方式)
  12. python定义一个变量为整型怎么写_python里怎么定义一个变量
  13. 华为、中兴、大亚等光猫或路由器DDNS设置方法
  14. 惊爆:普通人也能监听你MSN聊天(转)
  15. linux wifi开机自动连接 wifi连接
  16. vue-生成随机颜色
  17. 制作自己的标注数据集
  18. 在python中遍历字典元素
  19. 黄希庭:心理学的研究要走中国人自己的道路,要做中国化的心理学研究
  20. 分布式论文精读1:MapReduce

热门文章

  1. Python 多线程实例
  2. Weka安装及简单应用
  3. 静态NAT 如何配置?
  4. 实现微信小程序web-view内嵌H5中的下载功能(大文件切片下载)
  5. 软件设计模式——监听模式
  6. 计算机图形学(二):三维图形变换及应用(平移、旋转、缩放、仿射)
  7. JVM的mixed mode
  8. Java分页查询详解
  9. 单例模式破坏单例模式
  10. 透彻理解BN(Batch Normalization)层