在开发中,有些需求需要用到节点功能,比如手电筒,展瑞芯片无法使用原生逻辑开启/关闭手电筒,这个时候驱动部门使用节点实现驱动逻辑,上层根据写节点来实现控制手电筒,开发如下
路径
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
/*
* 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.qs.tiles;
import android.app.ActivityManager;
import android.content.Intent;
import android.provider.MediaStore;
import android.service.quicksettings.Tile;
import android.widget.Switch;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.FlashlightController;
import javax.inject.Inject;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import android.text.TextUtils;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
/** Quick settings tile: Control flashlight **/
public class FlashlightTile extends QSTileImpl<BooleanState> implements
FlashlightController.FlashlightListener {
private static String TAG = "FlashlightTile";
//手电筒节点
private static final String LIGHT_PATH = "/sys/devices/virtual/misc/sprd_flash/test";
private static final String ON = "0x12";
private static final String OFF = "0x13";
private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_flashlight);
private final FlashlightController mFlashlightController;
@Inject
public FlashlightTile(QSHost host, FlashlightController flashlightController) {
super(host);
mFlashlightController = flashlightController;
mFlashlightController.observe(getLifecycle(), this);
}
@Override
protected void handleDestroy() {
super.handleDestroy();
}
@Override
public BooleanState newTileState() {
BooleanState state = new BooleanState();
//state.handlesLongClick = false; //Unisoc: modify for bug1113905
return state;
}
@Override
public void handleSetListening(boolean listening) {
}
@Override
protected void handleUserSwitch(int newUserId) {
}
@Override
public Intent getLongClickIntent() {
return new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
}
@Override
public boolean isAvailable() {
return mFlashlightController.hasFlashlight();
}
@Override
protected void handleClick() {
if (ActivityManager.isUserAMonkey()) {
return;
}
//boolean newState = !mState.value;
boolean newState = !getLightState();
refreshState(newState);
// mFlashlightController.setFlashlight(newState);
setLightState(newState);
}
@Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.quick_settings_flashlight_label);
}
@Override
protected void handleLongClick() {
//handleClick(); //Unisoc: modify for bug1113905
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
if (state.slash == null) {
state.slash = new SlashState();
}
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
// if (!mFlashlightController.isAvailable()) {
// state.icon = mIcon;
// state.slash.isSlashed = true;
// state.contentDescription = mContext.getString(
// R.string.accessibility_quick_settings_flashlight_unavailable);
// state.state = Tile.STATE_UNAVAILABLE;
// return;
// }
// if (arg instanceof Boolean) {
// boolean value = (Boolean) arg;
// if (value == state.value) {
// return;
// }
// state.value = value;
// } else {
// state.value = mFlashlightController.isEnabled();
// }
state.value = getLightState();
state.icon = mIcon;
state.slash.isSlashed = !state.value;
state.contentDescription = mContext.getString(R.string.quick_settings_flashlight_label);
state.expandedAccessibilityClassName = Switch.class.getName();
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.QS_FLASHLIGHT;
}
@Override
protected String composeChangeAnnouncement() {
if (mState.value) {
return mContext.getString(R.string.accessibility_quick_settings_flashlight_changed_on);
} else {
return mContext.getString(R.string.accessibility_quick_settings_flashlight_changed_off);
}
}
@Override
public void onFlashlightChanged(boolean enabled) {
refreshState(enabled);
}
@Override
public void onFlashlightError() {
refreshState(false);
}
@Override
public void onFlashlightAvailabilityChanged(boolean available) {
refreshState();
}
//获取手电筒状态
public boolean getLightState(){
String lightStr = read(LIGHT_PATH);
Log.d(TAG, "lightStr == " + lightStr);
if (!TextUtils.isEmpty(lightStr) && TextUtils.equals("0x"+lightStr, ON)){
return true;
}
return false;
}
private String read(String sysPath) {
try {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("cat " + sysPath);
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while (null != (line = br.readLine())) {
return line;
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "read light error:"+e.getMessage());
}
return null;
}
private void setLightState(boolean state) {
Log.d(TAG, "setLightState(), state == " + state);
String data = state ? ON : OFF;
try {
BufferedWriter bufWriter = new BufferedWriter(new FileWriter(LIGHT_PATH));
bufWriter.write(data);
bufWriter.close();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "setLightState light error:"+e.getMessage());
}
}
}
如上,LIGHT_PATH 变量就是节点,这样直接修改节点值就可以实现逻辑了。别忘记还有一步最重要的,节点权限
diff --git a/common/rootdir/root/init.common.rc b/common/rootdir/root/init.common.rc
index 25e6df2e..76cf2f09 100755
--- a/common/rootdir/root/init.common.rc
+++ b/common/rootdir/root/init.common.rc
@@ -286,6 +286,8 @@ on boot
chmod 664 /sys/touchscreen/ts_suspend
chown root system /sys/touchscreen/ts_suspend
+ chmod 666 /sys/devices/virtual/misc/sprd_flash/test
这样就可以了