软件:Android11
硬件:QCS6125
需求:功耗考虑,需要在系统息屏5分钟后,进入飞行模式,系统唤醒后,关闭飞行模式。
考虑这个动作需要做到开机即可启动里边,因此添加了一个自定义服务,由SystemUI拉起来,具体实现如下:
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index dcfcfb8597a..bc965c805d3 100755
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -307,6 +307,10 @@
android:exported="true"
/>
+ <service android:name=".power.Yfds2PowerService"
+ android:exported="false"
+ />
+
<!-- Service for dumping extremely verbose content during a bug report -->
<service android:name=".dump.SystemUIAuxiliaryDumpService"
android:exported="false"
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 1f41038c260..6c3b8b76997 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -29,6 +29,7 @@ import android.util.Slog;
import com.android.internal.os.BinderInternal;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.power.Yfds2PowerService;
import com.android.systemui.dump.DumpHandler;
import com.android.systemui.dump.LogBufferFreezer;
import com.android.systemui.dump.SystemUIAuxiliaryDumpService;
@@ -101,7 +102,12 @@ public class SystemUIService extends Service {
startServiceAsUser(
new Intent(getApplicationContext(), SystemUIAuxiliaryDumpService.class),
UserHandle.SYSTEM);
- }
+
+ // Start Yfd PowerService
+ startServiceAsUser(
+ new Intent(getApplicationContext(), Yfds2PowerService.class),
+ UserHandle.SYSTEM);
+ }
@Override
public IBinder onBind(Intent intent) {
以上部分首先是在manifest注册自定义服务,下边是从SystemUIService将自定义服务拉起来,下边接入自定义服务的内容:
diff --git a/packages/SystemUI/src/com/android/systemui/power/Yfds2PowerService.java b/packages/SystemUI/src/com/android/systemui/power/Yfds2PowerService.java
new file mode 100644
index 00000000000..ec7696d1e9e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/Yfds2PowerService.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014 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.systemui.power;
import android.app.Service;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.provider.Settings;
import android.os.SystemClock;
import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.os.Message;
import android.os.PowerManager;
import android.os.UserHandle;
import android.util.Slog;
public class Yfds2PowerService extends Service {
public static final String TAG = "Yfds2PowerService";
private static final String DELAYED_AIRPLANE_ACTION = "com.yfd.power.DELAYED_AIRPLANE_ACTION";
public static final boolean DEBUG = true;
private Context mContext;
private PowerManager mPM;
private PowerManager.WakeLock mWakeLock;
private static final int MESSAGE_ENABLE_AIRPLANE = 100;
private static final int MESSAGE_DISABLE_AIRPLANE = 101;
private static final int DELAY_MILLISECOND = 3000*100;
//private static final int DELAY_MILLISECOND = 3000*10;
@Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
registerReceiver();
mPM = (PowerManager) getSystemService(Context.POWER_SERVICE);
}
private void registerReceiver() {
//registerReceiver
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(DELAYED_AIRPLANE_ACTION);
mContext.registerReceiver(broadcastReceiver, filter);
}
private void YfdAlarmOp(boolean op) {
Intent intent = new Intent();
intent.setAction(DELAYED_AIRPLANE_ACTION);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
if (op) {
Slog.d(TAG, "will exec alram after 30s.");
alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 30*1000, sender);
} else {
Slog.d(TAG, "will cancel alram.");
alarm.cancel(sender);
}
}
public void setupLock() {
Slog.d(TAG, "setup and require wakelock.");
synchronized (this) {
mWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.setReferenceCounted(false);
mWakeLock.acquire();
}
}
public void releaseLock() {
Slog.d(TAG, "release wakelock.");
synchronized (this) {
mWakeLock.release();
}
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null) {
switch (action) {
case Intent.ACTION_SCREEN_OFF:
if (DEBUG) {
Slog.d(TAG, "get Intent.ACTION_SCREEN_OFF");
}
//mHandler.sendEmptyMessageDelayed(MESSAGE_ENABLE_AIRPLANE, DELAY_MILLISECOND);
YfdAlarmOp(true);
setupLock();
break;
case Intent.ACTION_SCREEN_ON:
Slog.d(TAG, "get Intent.ACTION_SCREEN_ON");
YfdAlarmOp(false);
if (mWakeLock != null && mWakeLock.isHeld())
releaseLock();
mHandler.sendEmptyMessage(MESSAGE_DISABLE_AIRPLANE);
if (DEBUG) {
Slog.d(TAG, "remove all msg.");
}
break;
case DELAYED_AIRPLANE_ACTION:
Slog.d(TAG, "get DELAYED_AIRPLANE_ACTION");
mHandler.sendEmptyMessage(MESSAGE_ENABLE_AIRPLANE);
if (DEBUG) {
Slog.d(TAG, "remove all msg.");
}
break;
}
}
}
};
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
int what = msg.what;
switch (msg.what) {
case MESSAGE_ENABLE_AIRPLANE:
mHandler.removeCallbacksAndMessages(null);
setAirplaneModeOn(true);
if (mWakeLock != null && mWakeLock.isHeld()) {
Slog.d(TAG, "already setAirplaneModeOn: true and will release lock then goToSleep.");
releaseLock();
//mPM.goToSleep(SystemClock.uptimeMillis());
}
//if (DEBUG) {
//Slog.d(TAG, "setAirplaneModeOn: true");
//}
break;
case MESSAGE_DISABLE_AIRPLANE:
mHandler.removeCallbacksAndMessages(null);
setAirplaneModeOn(false);
Slog.d(TAG, "setAirplaneModeOn: false");
break;
}
}
};
private void setAirplaneModeOn(boolean enabling) {
// Change the system setting
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
enabling ? 1 : 0);
// Post the intent
final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", enabling);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
此服务主要的功能框架就是监听系统息屏的广播,在接受到此广播后,起五分钟之后的定时器任务,触发五分钟后发送广播消息,交给Handler去处理,从而开启飞行模式,之所以采用alarm的方式是因为系统休眠后,handler可能无法发送延迟消息。本来是想也监测亮屏的广播,但是发现这个位置监测会比PMS执行wakeup方法概率性慢1s左右,因此从PMS添加wakeup中关闭飞行模式的逻辑:
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index f4ac9928064..a966319253e 100755
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1675,6 +1675,21 @@ public final class PowerManagerService extends SystemService
}
}
+ private void setAirplaneModeOn(boolean enabling) {
+ // Change the system setting
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
+ enabling ? 1 : 0);
+
+ // Post the intent
+ final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", enabling);
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+ }
+
+ private boolean isAirplaneModeOn() {
+ return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
+ }
+
private boolean wakeUpNoUpdateLocked(long eventTime, @WakeReason int reason, String details,
int reasonUid, String opPackageName, int opUid) {
if (DEBUG_SPEW) {
@@ -1686,6 +1701,10 @@ public final class PowerManagerService extends SystemService
return false;
}
+ if (isAirplaneModeOn()) {
+ setAirplaneModeOn(false);
+ }
+
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
这块改动在系统资源紧张的时候,可能会导致系统死锁,因此可直接用上文添加的服务中,在亮屏之后再做退出飞行模式的处理。
Mark…
版权声明:本文为DKBDKBDKB原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。