Android11 Framework添加Powerkey事件去抖

文章介绍了在Android系统中,为防止短时间内频繁触发PowerKey导致屏幕反复亮灭,采用了一个名为Debouncer的工具类来实现去抖动机制。Debouncer类检测两次事件触发的时间间隔,若小于预设值则忽略后续事件,确保每次执行完一次唤醒或休眠操作后才响应新的PowerKey事件。改动涉及PowerManagerService的内部逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    需求:短时间来回触控powerkey造成屏幕来回亮灭切换,需要去抖动,即在每次响应执行完一次休眠或者唤醒事件后,再响应powerkey事件。

1、首先在framework中做了一个去抖动的工具类:

diff --git a/api/current.txt b/api/current.txt
index 689cf4833a0..e2eab020325 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -61605,6 +61605,17 @@ package android.widget.inline {
 
 }
 
+package android.yuanfudao.util {
+
+  public class Debouncer {
+    ctor public Debouncer();
+    ctor public Debouncer(long);
+    method public boolean ignore();
+    method public void setDebounceTime(long);
+  }
+
+}
+
 package dalvik.annotation {
 
   @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.ANNOTATION_TYPE}) public @interface TestTarget {
diff --git a/core/java/android/yuanfudao/util/Debouncer.java b/core/java/android/yuanfudao/util/Debouncer.java
new file mode 100755
index 00000000000..83724e9e6d7
--- /dev/null
+++ b/core/java/android/yuanfudao/util/Debouncer.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 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 android.yuanfudao.util;
+
+import android.os.SystemClock;
+
+public class Debouncer {
+
+    private long debounceTime = 500L;
+
+    private long lastTriggerTimestamp;
+
+    public Debouncer() {}
+
+    public Debouncer(long paramLong) {
+        this.debounceTime = paramLong;
+    }
+
+    public boolean ignore() {
+        long l1 = SystemClock.elapsedRealtime();
+        long l2 = this.lastTriggerTimestamp;
+        if (l2 != 0L && l1 - l2 < this.debounceTime){
+            return true;
+        }else {
            this.lastTriggerTimestamp = l1;
+            return false;
+        }
+    }
+
+    public void setDebounceTime(long paramLong) {
+        this.debounceTime = paramLong;
+    }
+}
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index 07be752e01d..e9154685b05 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -59766,6 +59766,17 @@ package android.widget.inline {
 
 }
 
+package android.yuanfudao.util {
+
+  public class Debouncer {
+    ctor public Debouncer();
+    ctor public Debouncer(long);
+    method public boolean ignore();
+    method public void setDebounceTime(long);
+  }
+
+}
+
 package dalvik.annotation {
 
   @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.ANNOTATION_TYPE}) public @interface TestTarget {

2、PowerManagerService添加相关逻辑:

--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -118,6 +118,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import android.yuanfudao.util.Debouncer;
 
 /**
  * The power manager service is responsible for coordinating power management
@@ -612,6 +613,8 @@ public final class PowerManagerService extends SystemService
     // Per-profile state to track when a profile should be locked.
     private final SparseArray<ProfilePowerState> mProfilePowerState = new SparseArray<>();
 
+       private Debouncer debouncer = new Debouncer(2500L);
+
     private static final class ProfilePowerState {
         // Profile user id.
         final @UserIdInt int mUserId;
@@ -1701,6 +1704,13 @@ public final class PowerManagerService extends SystemService
             return false;
         }
 
+        //Heguodong add - begin
+        if (this.debouncer.ignore()) {
+            Slog.d(TAG, "[YFD_PowerManagerService]wakeUpNoUpdateLocked,!!!rejected!!!" );
+            return false;
+        }
+        //Heguodong add - end
+
         //if (isAirplaneModeOn()) {
            // setAirplaneModeOn(false);
         //}
@@ -1763,6 +1773,13 @@ public final class PowerManagerService extends SystemService
             return false;
         }
 
+        //Heguodong add - begin
+        if (this.debouncer.ignore()) {
+            Slog.d(TAG, "[YFD_PowerManagerService]goToSleepNoUpdateLocked,!!!rejected!!!" );
+            return false;
+        }
+        //Heguodong add - end
+
         Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
         try {
             reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,

增量编译验证:达到的效果是每次经历完一次完整的唤醒、休眠逻辑才会响应PowerKey事件。

Mark···

<think>好的,我现在需要帮助用户了解或开发与Android Settings相关的框架,特别是关于Settings Framework的开发文档或源码解析。首先,用户提到的参考资料里有三个引用,我需要仔细看看这些引用是否相关,并从中提取有用的信息。 首先,引用[1]提到了Android Settings解析,包括SettingsIntelligence和SettingsProvider,这可能涉及到Settings应用的结构和底层数据提供者。引用[2]是关于Android系统开发的指导,提到需要研究系统服务的源码,比如ActivityManagerService和WindowManagerService,这可能对理解Settings框架有帮助。引用[3]则介绍了源码目录中的data目录,里面包含资源文件,比如字体、声音等,这可能与Settings的UI资源有关。 用户的需求是寻找开发文档或源码解析,但可能官方文档不够详细,所以需要依赖源码分析和相关指南。我需要整理出Settings框架的主要组成部分,并指出源码的位置,以及如何分析这些代码。 首先,Android Settings应用的结构可能分为应用层(UI部分)和框架层(系统服务)。应用层可能位于packages/apps/Settings,而框架层可能涉及frameworks/base中的相关服务,比如SettingsProvider。需要指出这些模块的位置,并说明如何查阅源码。 其次,SettingsProvider作为系统Provider,处理设置的存储和访问,这部分源码可能在frameworks/base/packages/SettingsProvider。需要解释它的作用,比如存储系统设置、安全配置等,并给出关键类,如Settings.java。 然后,系统服务中的Settings相关的服务可能包括DevicePolicyManager,这些服务的管理逻辑可能在frameworks/base/services/core/java/com/android/server目录下,例如DevicePolicyManagerService。 另外,资源文件的位置也很重要,比如data目录中的资源,如布局和字符串,这些可能在packages/apps/Settings/res下,用户可能需要修改这些资源来自定义界面。 开发建议方面,用户可能需要学习如何定制Settings模块,比如添加新设置项或修改现有逻辑。需要指导他们如何修改布局文件,添加自定义Preference,或者修改SettingsProvider的逻辑。 此外,用户可能需要调试和测试他们的修改,比如使用adb命令访问设置项,或者查看数据库内容。例如,使用settings命令或查询SettingsProvider的数据库。 最后,生成的相关问题需要围绕Settings框架的组成部分、源码分析步骤、定制方法、调试工具等,帮助用户深入理解。 现在需要确保回答结构清晰,分点说明源码位置、关键模块、开发建议和调试方法,并正确引用提供的资料。同时,使用中文回答,行内公式用$...$,独立公式用$$...$$,但这里可能不太涉及数学公式,所以重点放在代码块和结构上。</think>### Android Settings Framework 开发与源码解析 Android Settings Framework 是系统设置功能的核心,涉及应用层交互、数据存储和系统服务整合。以下是开发与源码分析的关键点: --- #### 一、源码结构与核心模块 1. **Settings 应用层源码** - **路径**: `packages/apps/Settings/` - **功能**: 包含用户界面(如设置主界面、Wi-Fi、蓝牙等子模块),使用 `PreferenceFragment` 管理交互逻辑。 - **关键类**: - `Settings.java`: 入口 Activity - `WirelessSettings.java`: 网络相关设置 - `SecuritySettings.java`: 安全配置[^1] 2. **SettingsProvider 数据存储** - **路径**: `frameworks/base/packages/SettingsProvider/` - **作用**: 管理系统设置的持久化存储(如系统全局配置、安全策略),通过 `ContentProvider` 提供访问接口。 - **关键类**: - `Settings.java`: 定义 `System`, `Secure`, `Global` 三类命名空间的键值对[^3]。 - **数据库路径**: `/data/data/com.android.providers.settings/databases/settings.db` 3. **系统服务整合** - **路径**: `frameworks/base/services/core/java/com/android/server/` - **示例**: - `DevicePolicyManagerService.java`: 设备策略管理(如企业级限制) - `WifiService.java`: Wi-Fi 功能底层控制[^2] --- #### 二、开发与定制指南 1. **添加新设置项** - **步骤**: 1. **UI 层**: 在 `res/xml/` 下新增 Preference XML 文件,定义布局。 2. **逻辑层**: 继承 `PreferenceFragment`,绑定点击事件。 3. **数据层**: 通过 `Settings.System.putInt()` 等方法写入系统数据库。 - **代码片段**: ```java // 添加开关控件 SwitchPreference customPref = findPreference("custom_key"); customPref.setOnPreferenceChangeListener((preference, newValue) -> { Settings.System.putInt(getContentResolver(), "CUSTOM_SETTING", (Boolean) newValue ? 1 : 0); return true; }); ``` 2. **修改系统默认设置** - **路径**: `frameworks/base/packages/SettingsProvider/res/values/defaults.xml` - **示例**: 调整默认屏幕超时时间: ```xml <integer name="def_screen_off_timeout">300000</integer> <!-- 5分钟 --> ``` 3. **跨进程通信机制** - **Binder 与 AIDL**: Settings 通过 `SettingsProvider` 提供的 `ContentResolver` 与系统服务(如 `PowerManagerService`)交互[^2]。 --- #### 三、调试与分析工具 1. **ADB 命令调试** - 查看当前系统设置: ```bash adb shell settings get system screen_off_timeout ``` - 修改设置值: ```bash adb shell settings put secure bluetooth_name "MyDevice" ``` 2. **数据库直接访问** ```bash adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db > SELECT * FROM system WHERE name='screen_off_timeout'; ``` 3. **日志过滤** ```bash adb logcat -s SettingsProvider # 监控设置数据变更 ``` --- #### 四、参考文档与进阶学习 1. **官方资源**: - [Android 开发者设置指南](https://developer.android.com/guide/topics/ui/settings) - [AOSP 源码查看](https://android.googlesource.com/platform/packages/apps/Settings/) 2. **书籍推荐**: - *《Android 系统源码情景分析》*: 详解系统服务与 Framework 层设计。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值