RK3288[android 7.1]调试笔记 在安卓下拉状态栏的亮度进度条增加一条控制副屏亮度的进度条

由于我们双屏项目使用的背光是两路pwm通道,所以会产生两个背光节点

C:\Users\Caozhaoyang>adb shell
P710-08:/ $ cat sys/class/backlight/
backlight/        pwm3-backlight/      	//这里可以看到系统产生了两个背光节点,主屏背光节点sys/class/backlight/backlight 和 副屏背光节点sys/class/backlight/ pwm3-backlight
P710-08:/ $ cat sys/class/backlight/backlight/                      //进去主屏背光节点sys/class/backlight/backlight 节点可以看到它的属性
actual_brightness   bl_power            brightness          device/             max_brightness      power/              subsystem/          type
P710-08:/ $ cat sys/class/backlight/backlight/brightness    //查看主屏背光节点sys/class/backlight/backlight 节点背光亮度
163
P710-08:/ $ echo 255 > sys/class/backlight/backlight/brightness   //通过写值调试 sys/class/backlight/backlight 节点背光亮度 亮度范围为 0~255
P710-08:/ $ cat sys/class/backlight/backlight/brightness   //可以查看sys/class/backlight/backlight 节点背光亮度有163变为255
255 


P710-08:/ $ cat sys/class/backlight/pwm3-backlight/brightness //查看副屏背光节点sys/class/backlight/pwm3-backlight/brightness 节点背光亮度
235
P710-08:/ $ echo 122 > sys/class/backlight/pwm3-backlight/brightness //通过写值调试 副屏背光节点sys/class/backlight/pwm3-backlight/brightness 节点背光亮度 亮度范围为 0~255
P710-08:/ $ cat sys/class/backlight/pwm3-backlight/brightness   //可以查看sys/class/backlight/backlight 节点背光亮度有235变为122
122

所以我们在安卓下拉状态栏的亮度进度条增加一条控制副屏亮度的进度条,主要是操作副屏背光节点sys/class/backlight/pwm3-backlight/brightness 节点背光亮度

1 进入下拉状态栏亮度进度条的位置,进度条的布局位于frameworks/base/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml

@build-server-99:~/work104/3288/work2/3288-7.1/haier$ git diff frameworks/base/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
diff --git a/haier/frameworks/base/packages/SystemUI/res/layout/quick_settin
old mode 100644
new mode 100755
index 5cbe635..9a10244
--- a/haier/frameworks/base/packages/SystemUI/res/layout/quick_settings_brig
+++ b/haier/frameworks/base/packages/SystemUI/res/layout/quick_settings_brig
@@ -41,4 +41,25 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res-auto"
    android:layout_height="48dp"
    android:layout_width="match_parent"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    style="@style/BrightnessDialogContainer">
//原生背光条的布局
    <ImageView
        android:id="@+id/brightness_icon"   //背光的图标的id
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginEnd="8dp"
        android:src="@drawable/ic_qs_brightness_auto_off"//背光的图标
        android:contentDescription="@null"
        android:visibility="gone" />

    <com.android.systemui.settings.ToggleSlider
        android:id="@+id/brightness_slider"  //滑动背光的图标的id
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"
        android:contentDescription="@string/accessibility_brightness"  //背光条的描述
        android:importantForAccessibility="no"
        systemui:text="@string/status_bar_settings_auto_brightness_label" /> //背光条的标签
 //下面是仿照原生背光条的布局  我增加副屏背光条的布局 
+<!-- 20190905 added by elink_dongsy for brightness Controller start-->
+    <ImageView
+        android:id="@+id/brightness_icon_other"  //副屏背光的图标的id
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:layout_marginEnd="8dp"
+        android:src="@drawable/ic_qs_brightness_auto_off_other"//副屏背光的图标
+        android:contentDescription="@null"
+        android:visibility="gone" />
+
+    <com.android.systemui.settings.ToggleSlider
+        android:id="@+id/brightness_slider_other" //副屏滑动背光的图标的id
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:layout_weight="1"
+        android:contentDescription="@string/accessibility_brightness" //背光条的描述是一个字符串所以直接引用原生的就行
+        android:importantForAccessibility="no"
+        systemui:text="@string/status_bar_settings_auto_brightness_label"/>   //背光条的标签是一个字符串所以直接引用原生的就行
+<!-- 20190905 added by elink_dongsy for brightness Controller end-->
 </LinearLayout>

1) 仿照原生的背光布局文件,增加布局文件frameworks/base/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off_other.xml 和frameworks/base/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on_other.xml
在这里插入图片描述
2) 仿照原生的布局文件,增加图片frameworks/base/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off_alpha_other.png 和 frameworks/base/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on_alpha_other.png
原生的frameworks/base/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml布局文件内容
在这里插入图片描述
增加frameworks/base/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off_other.xml布局文件
在这里插入图片描述
原生的frameworks/base/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml布局文件内容
在这里插入图片描述
增加frameworks/base/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on_other.xml布局文件内容
在这里插入图片描述

在这里插入图片描述

2 接下来quick_settings_brightness_dialog.xml布局会在frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java文件中被加载

public QSPanel(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;

        setOrientation(VERTICAL);

        mBrightnessView = LayoutInflater.from(context).inflate(
                R.layout.quick_settings_brightness_dialog, this, false);
        addView(mBrightnessView);

        setupTileLayout();

        mFooter = new QSFooter(this, context);
        addView(mFooter.getView());

        updateResources();
		 //可以在BrightnessController这个类里面来具体实现亮度控制的逻辑
        mBrightnessController = new BrightnessController(getContext(),
                (ImageView) findViewById(R.id.brightness_icon),
                (ToggleSlider) findViewById(R.id.brightness_slider));
		  //仿照BrightnessController这个类内容,复制BrightnessController2这个类来具体实现副屏亮度控制的逻辑
       //20190905 added by elink_dongsy for brightness Controller start
        mBrightnessControllerOther = new BrightnessController2(getContext(), 
                (ImageView) findViewById(R.id.brightness_icon_other),
                (ToggleSlider) findViewById(R.id.brightness_slider_other));
       //20190905 added by elink_dongsy for brightness Controller end
     
    }

我们可以看到通过LayoutInflater.from方法获取到了亮度进度条的View,然后添加到了QSPanel,QSPanel就是我们下拉状态栏看到的快捷设置面板,接下来我们可以看到创建了一个BrightnessController对象,对象的构造传入了(ImageView)findViewById(R.id.brightness_icon)和(ToggleSlider) findViewById(R.id.brightness_slider)这两个
控件对象,从这个对象的命名其实就可以看出来,亮度控制者,状态栏上亮度调节具体逻辑的实现全部是在这个类里面实现的

所以在frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java这个文件中仿照原生的背光布局加载和相关操作做如下修改:

build-server-99:~/work104/3288/work2/3288-7.1/haier$ git diff frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
diff --git a/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/haier/frameworks/base/packages/SystemUI
old mode 100644
new mode 100755
index 61812b6..b1283b6
--- a/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -35,6 +35,7 @@ import com.android.systemui.qs.QSTile.Host.Callback;
 import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.settings.BrightnessController;
+import com.android.systemui.settings.BrightnessController2;
 import com.android.systemui.settings.ToggleSlider;
 import com.android.systemui.statusbar.phone.QSTileHost;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
@@ -61,6 +62,9 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
 
     private Callback mCallback;
     private BrightnessController mBrightnessController;
+    //20190905 added by elink_dongsy for brightness Controller start
+    private BrightnessController2 mBrightnessControllerOther;
+    //20190905 added by elink_dongsy for brightness Controller end
     protected QSTileHost mHost;
 
     protected QSFooter mFooter;
@@ -72,6 +76,9 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
     private Record mDetailRecord;
 
     private BrightnessMirrorController mBrightnessMirrorController;
+     //20190905 added by elink_dongsy for brightness Controller start
+    private BrightnessMirrorController mBrightnessMirrorControllerOther;
+    //20190905 added by elink_dongsy for brightness Controller end

    public QSPanel(Context context) {
         this(context, null);
@@ -98,6 +105,11 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
                 (ImageView) findViewById(R.id.brightness_icon),
                 (ToggleSlider) findViewById(R.id.brightness_slider));
 
+       //20190905 added by elink_dongsy for brightness Controller start
+        mBrightnessControllerOther = new BrightnessController2(getContext(),
+                (ImageView) findViewById(R.id.brightness_icon_other),
+                (ToggleSlider) findViewById(R.id.brightness_slider_other));
+       //20190905 added by elink_dongsy for brightness Controller end
     }
 
     protected void setupTileLayout() {
@@ -163,6 +175,13 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
         ToggleSlider mirror = (ToggleSlider) c.getMirror().findViewById(R.id.brightness_slider);
         brightnessSlider.setMirror(mirror);
         brightnessSlider.setMirrorController(c);
+         //20190905 added by elink_dongsy for brightness Controller start
+        mBrightnessMirrorControllerOther = c;
+        ToggleSlider brightnessSliderOther = (ToggleSlider) findViewById(R.id.brightness_slider_other);
+        ToggleSlider mirrorOther = (ToggleSlider) c.getMirror().findViewById(R.id.brightness_slider_other);
+        brightnessSliderOther.setMirror(mirrorOther);
+        brightnessSliderOther.setMirrorController(c);
+         //20190905 added by elink_dongsy for brightness Controller end      
     }
 
     View getBrightnessView() {
@@ -183,6 +202,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
             mCustomizePanel.setHost(mHost);
         }
         mBrightnessController.setBackgroundLooper(host.getLooper());
+
+        //20190905 added by elink_dongsy for brightness Controller start
+        mBrightnessControllerOther.setBackgroundLooper(host.getLooper());
+        //20190905 added by elink_dongsy for brightness Controller end
     }
 
     public QSTileHost getHost() {
@@ -249,8 +272,18 @@ public class QSPanel extends LinearLayout implements Tunable, Callback {
         if (mBrightnessView.getVisibility() == View.VISIBLE) {
             if (listening) {
                 mBrightnessController.registerCallbacks();
+
+                 //20190905 added by elink_dongsy for brightness Controller start
+                 mBrightnessControllerOther.registerCallbacks();
+                  //20190905 added by elink_dongsy for brightness Controller start
+
             } else {
                 mBrightnessController.unregisterCallbacks();
+
+                 //20190905 added by elink_dongsy for brightness Controller start
+                mBrightnessControllerOther.unregisterCallbacks();
+                 //20190905 added by elink_dongsy for brightness Controller start
+
             }
         }
     }

增加控制副屏背光逻辑的frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController2.java这个类与原生的frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java内容上有区别

在这里插入图片描述
frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController2.java所做的修改如下:

build-server-99:~/work104/3288/work2/3288-7.1/haier$ git diff frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController2.java
diff --git a/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController2.java b/haier/frameworks/ba
old mode 100644
new mode 100755
index 14c4161..6504cca
--- a/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController2.java
+++ b/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController2.java
@@ -40,8 +40,19 @@ import com.android.internal.logging.MetricsProto.MetricsEvent;
 
 import java.util.ArrayList;
 
-public class BrightnessController implements ToggleSlider.Listener {
-    private static final String TAG = "StatusBar.BrightnessController";
+import android.util.Log;
+import android.content.Context;
+import android.os.AsyncTask;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class BrightnessController2 implements ToggleSlider.Listener {
+    private static final String TAG = "StatusBar.BrightnessController2";
     private static final boolean SHOW_AUTOMATIC_ICON = false;
 
     /**
@@ -81,6 +92,8 @@ public class BrightnessController implements ToggleSlider.Listener {
     private boolean mListening;
     private boolean mExternalChange;
 
+    public static final String sys_path = "/sys/class/backlight/pwm3-backlight/brightness";
+
     public interface BrightnessStateChangeCallback {
         public void onBrightnessLevelChanged();
     }
@@ -108,24 +121,24 @@ public class BrightnessController implements ToggleSlider.Listener {
 
         @Override
         public void onChange(boolean selfChange, Uri uri) {
-            if (selfChange) return;
-
-            if (BRIGHTNESS_MODE_URI.equals(uri)) {
-                mBackgroundHandler.post(mUpdateModeRunnable);
-                mBackgroundHandler.post(mUpdateSliderRunnable);
-            } else if (BRIGHTNESS_URI.equals(uri) && !mAutomatic) {
-                mBackgroundHandler.post(mUpdateSliderRunnable);
-            } else if (BRIGHTNESS_FOR_VR_URI.equals(uri)) {
-                mBackgroundHandler.post(mUpdateSliderRunnable);
-            } else if (BRIGHTNESS_ADJ_URI.equals(uri) && mAutomatic) {
-                mBackgroundHandler.post(mUpdateSliderRunnable);
-            } else {
-                mBackgroundHandler.post(mUpdateModeRunnable);
-                mBackgroundHandler.post(mUpdateSliderRunnable);
-            }
-            for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
-                cb.onBrightnessLevelChanged();
-            }
+            // if (selfChange) return;
+
+            // if (BRIGHTNESS_MODE_URI.equals(uri)) {
+            //     mBackgroundHandler.post(mUpdateModeRunnable);
+            //     mBackgroundHandler.post(mUpdateSliderRunnable);
+            // } else if (BRIGHTNESS_URI.equals(uri) && !mAutomatic) {
+            //     mBackgroundHandler.post(mUpdateSliderRunnable);
+            // } else if (BRIGHTNESS_FOR_VR_URI.equals(uri)) {
+            //     mBackgroundHandler.post(mUpdateSliderRunnable);
+            // } else if (BRIGHTNESS_ADJ_URI.equals(uri) && mAutomatic) {
+            //     mBackgroundHandler.post(mUpdateSliderRunnable);
+            // } else {
+            //     mBackgroundHandler.post(mUpdateModeRunnable);
+            //     mBackgroundHandler.post(mUpdateSliderRunnable);
+            // }
+            // for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
+            //     cb.onBrightnessLevelChanged();
+            // }
         }
 
         public void startObserving() {
@@ -255,7 +268,7 @@ public class BrightnessController implements ToggleSlider.Listener {
                         mControl.setChecked(msg.arg1 != 0);
                         break;
                     case MSG_ATTACH_LISTENER:
-                        mControl.setOnChangedListener(BrightnessController.this);
+                        mControl.setOnChangedListener(BrightnessController2.this);
                         break;
                     case MSG_DETACH_LISTENER:
                         mControl.setOnChangedListener(null);
@@ -272,11 +285,13 @@ public class BrightnessController implements ToggleSlider.Listener {
         }
     };
 
-    public BrightnessController(Context context, ImageView icon, ToggleSlider control) {
+    public BrightnessController2(Context context, ImageView icon, ToggleSlider control) {
         mContext = context;
         mIcon = icon;
         mControl = control;
         mBackgroundHandler = new Handler(Looper.getMainLooper());
+
+         Log.i(TAG, "----------com in BrightnessController2------------");
         mUserTracker = new CurrentUserTracker(mContext) {
             @Override
             public void onUserSwitched(int newUserId) {
@@ -298,6 +313,8 @@ public class BrightnessController implements ToggleSlider.Listener {
         mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService("vrmanager"));
     }
 
+    
+
     public void setBackgroundLooper(Looper backgroundLooper) {
         mBackgroundHandler = new Handler(backgroundLooper);
     }
@@ -316,6 +333,8 @@ public class BrightnessController implements ToggleSlider.Listener {
     }
 
     public void registerCallbacks() {
+         Log.i(TAG, "----------com in registerCallbacks------------");
+
         if (mListening) {
             return;
         }
@@ -335,6 +354,8 @@ public class BrightnessController implements ToggleSlider.Listener {
 
     /** Unregister all call backs, both to and from the controller */
     public void unregisterCallbacks() {
+        Log.i(TAG, "----------com in unregisterCallbacks------------");
+
         if (!mListening) {
             return;
         }
@@ -354,58 +375,37 @@ public class BrightnessController implements ToggleSlider.Listener {
     @Override
     public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
             boolean stopTracking) {
-        updateIcon(mAutomatic);
-        if (mExternalChange) return;
+         Log.i(TAG, "----------com in onChanged------------");
 
-        if (mIsVrModeEnabled) {
-            final int val = value + mMinimumBacklightForVr;
-            if (stopTracking) {
-                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_FOR_VR, val);
-            }
-            setBrightness(val);
-            if (!tracking) {
-                AsyncTask.execute(new Runnable() {
-                        public void run() {
-                            Settings.System.putIntForUser(mContext.getContentResolver(),
-                                    Settings.System.SCREEN_BRIGHTNESS_FOR_VR, val,
-                                    UserHandle.USER_CURRENT);
-                        }
-                    });
-            }
-        } else if (!mAutomatic) {
-            final int val = value + mMinimumBacklight;
-            if (stopTracking) {
-                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val);
-            }
-            setBrightness(val);
-            if (!tracking) {
-                AsyncTask.execute(new Runnable() {
-                        public void run() {
-                            Settings.System.putIntForUser(mContext.getContentResolver(),
-                                    Settings.System.SCREEN_BRIGHTNESS, val,
-                                    UserHandle.USER_CURRENT);
-                        }
-                    });
-            }
-        } else {
-            final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1;
-            if (stopTracking) {
-                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_AUTO, value);
-            }
-            setBrightnessAdj(adj);
-            if (!tracking) {
-                AsyncTask.execute(new Runnable() {
-                    public void run() {
-                        Settings.System.putFloatForUser(mContext.getContentResolver(),
-                                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj,
-                                UserHandle.USER_CURRENT);
-                    }
-                });
-            }
+             writeSysFile(sys_path,  value +"");   
+
+
+    }
+
+
+
+
+      public static void writeSysFile(String sys_path, String value) {
+
+        if (sys_path == null || sys_path.length() == 0) return;
+
+        File file = new File(sys_path);
+        if (!file.exists()) {
+            return;
         }
 
-        for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
-            cb.onBrightnessLevelChanged();
+        if (file.isDirectory()) {
+        } else {
+            BufferedWriter writer = null;
+            try {
+
+                writer = new BufferedWriter(new FileWriter(sys_path));
+                writer.write(value);//写值操作
+                writer.flush();
+                writer.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
         }
     }
 
@@ -432,8 +432,8 @@ public class BrightnessController implements ToggleSlider.Listener {
     private void updateIcon(boolean automatic) {
         if (mIcon != null) {
             mIcon.setImageResource(automatic && SHOW_AUTOMATIC_ICON ?
-                    com.android.systemui.R.drawable.ic_qs_brightness_auto_on :
-                    com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
+                    com.android.systemui.R.drawable.ic_qs_brightness_auto_on_other :
+                    com.android.systemui.R.drawable.ic_qs_brightness_auto_off_other);
         }
     }

3 接下来会在BrightnessDialog中初始化拖动条等相关控件,并实例化了BrightnessController.java BrightnessController2.java
frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java BrightnessController2.java

        setContentView(R.layout.quick_settings_brightness_dialog);
      
        final ImageView icon = (ImageView) findViewById(R.id.brightness_icon);
        final ToggleSlider slider = (ToggleSlider) findViewById(R.id.brightness_slider);
        mBrightnessController = new BrightnessController(this, icon, slider);

并注册和注销BrightnessController的回调方法:

   @Override
    protected void onStart() {
        super.onStart();
        mBrightnessController.registerCallbacks();
        MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG);
    }

    @Override
    protected void onStop() {
        super.onStop();
        MetricsLogger.hidden(this, MetricsEvent.BRIGHTNESS_DIALOG);
        mBrightnessController.unregisterCallbacks();
    }

所以我们在/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java文件中仿照其实例化BrightnessController2.java这个类,做如下修改:

zqb@build-server-99:~/work104/3288/work2/3288-7.1/haier$ git diff frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
diff --git a/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/haier/frameworks/base/pa
old mode 100644
new mode 100755
index 4952234..9fee845
--- a/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/haier/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -32,6 +32,9 @@ import com.android.systemui.R;
 public class BrightnessDialog extends Activity {
 
     private BrightnessController mBrightnessController;
+    //20190905 added by elink_dongsy for brightness Controller start
+    private BrightnessController2 mBrightnessControllerOther;
+    //20190905 added by elink_dongsy for brightness Controller end
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -48,12 +51,22 @@ public class BrightnessDialog extends Activity {
         final ImageView icon = (ImageView) findViewById(R.id.brightness_icon);
         final ToggleSlider slider = (ToggleSlider) findViewById(R.id.brightness_slider);
         mBrightnessController = new BrightnessController(this, icon, slider);
+
+        //20190905 added by elink_dongsy for brightness Controller start
+        final ImageView iconOther = (ImageView) findViewById(R.id.brightness_icon_other);
+        final ToggleSlider sliderOther = (ToggleSlider) findViewById(R.id.brightness_slider_other);
+        mBrightnessControllerOther = new BrightnessController2(this, iconOther, sliderOther);
+        //20190905 added by elink_dongsy for brightness Controller end
+    
     }


     @Override
     protected void onStart() {
         super.onStart();
         mBrightnessController.registerCallbacks();
+        //20190905 added by elink_dongsy for brightness Controller start
+        mBrightnessControllerOther.registerCallbacks();
+        //20190905 added by elink_dongsy for brightness Controller end
         MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG);
     }
 
@@ -62,6 +75,9 @@ public class BrightnessDialog extends Activity {
         super.onStop();
         MetricsLogger.hidden(this, MetricsEvent.BRIGHTNESS_DIALOG);
         mBrightnessController.unregisterCallbacks();
+        //20190905 added by elink_dongsy for brightness Controller start
+        mBrightnessControllerOther.unregisterCallbacks();
+        //20190905 added by elink_dongsy for brightness Controller end
     }
 
     @Override

BrightnessController

BrightnessController的回调方法

 public void registerCallbacks() { 
        Log.i(TAG, "----------com in registerCallbacks------------");
        if (mListening) {
            return;
        }

        if (mVrManager != null) {
            try {
                mVrManager.registerListener(mVrStateCallbacks);
                mIsVrModeEnabled = mVrManager.getVrModeState();
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to register VR mode state listener: ", e);
            }
        }

        mBackgroundHandler.post(mStartListeningRunnable);
        mListening = true;
    }

    /** Unregister all call backs, both to and from the controller */
    public void unregisterCallbacks() {

        Log.i(TAG, "----------com in unregisterCallbacks------------");
        if (!mListening) {
            return;
        }

        if (mVrManager != null) {
            try {
                mVrManager.unregisterListener(mVrStateCallbacks);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to unregister VR mode state listener: ", e);
            }
        }

        mBackgroundHandler.post(mStopListeningRunnable);
        mListening = false;
    }

BrightnessController的回调方法主要是在亮度调节模式改变时更新系统保存的模式,在亮度调节时更新拖动条(此拖动条和下拉栏的亮度条保持一致)。这里主要看亮度设置时的操作。
因为BrightnessController实现了对ToggleSlider的监听,在拖动条改变时设置亮度:

 @Override
    public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
            boolean stopTracking) {
        Log.i(TAG, "----------com in onChanged------------");
        
        updateIcon(mAutomatic);
        if (mExternalChange) return;

        if (mIsVrModeEnabled) {
            final int val = value + mMinimumBacklightForVr;
            if (stopTracking) {
                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_FOR_VR, val);
            }

             Log.i(TAG, "brightness mode:"+mAutomatic+"value:"+value+"value set:"+val);
            setBrightness(val);

            android.util.Log.e(TAG, "BrightnessController val "+value);
            if (!tracking) {
                AsyncTask.execute(new Runnable() {
                        public void run() {
                            Settings.System.putIntForUser(mContext.getContentResolver(),
                                    Settings.System.SCREEN_BRIGHTNESS_FOR_VR, val,
                                    UserHandle.USER_CURRENT);
                        }
                    });
            }
        } else if (!mAutomatic) {
            final int val = value + mMinimumBacklight;
            if (stopTracking) {
                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val);
            }
            setBrightness(val);
            if (!tracking) {
                AsyncTask.execute(new Runnable() {
                        public void run() {
                            Settings.System.putIntForUser(mContext.getContentResolver(),
                                    Settings.System.SCREEN_BRIGHTNESS, val,
                                    UserHandle.USER_CURRENT);
                        }
                    });
            }
        } else {
            final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1;
            if (stopTracking) {
                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_AUTO, value);
            }
            setBrightnessAdj(adj);
            if (!tracking) {
                AsyncTask.execute(new Runnable() {
                    public void run() {
                        Settings.System.putFloatForUser(mContext.getContentResolver(),
                                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj,
                                UserHandle.USER_CURRENT);
                    }
                });
            }
        }

        for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
            cb.onBrightnessLevelChanged();
        }
    }

value就是拖动条的值,在初始化的时候,亮度条的范围和值都被设置:
思路就是在 public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
boolean stopTracking)这个监听拖动条改变的事件中,把拖动条的值value写进副屏背光节点/sys/class/backlight/pwm3-backlight/brightness中

1) 增加往节点的写值方法

import android.util.Log;
import android.content.Context;
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public static final String sys_path = "/sys/class/backlight/pwm3-backlight/brightness";

    public static void writeSysFile(String sys_path, String value) {

        if (sys_path == null || sys_path.length() == 0) return;

        File file = new File(sys_path);
        if (!file.exists()) {
            return;
        }

        if (file.isDirectory()) {
        } else {
            BufferedWriter writer = null;
            try {

                writer = new BufferedWriter(new FileWriter(sys_path));
                writer.write(value);//写值操作
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

写值方法writeSysFile的使用writeSysFile(sys_path, value+ “”);

public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
boolean stopTracking)这个监听拖动条改变的事件中把拖动条的值value写进副屏背光节点/sys/class/backlight/pwm3-backlight/brightness中

    @Override
    public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
            boolean stopTracking) {
         Log.i(TAG, "----------com in onChanged------------");

             writeSysFile(sys_path,  value +"");   
    }

frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController2.java控制背光逻辑类内容如下

/*
 * Copyright (C) 2013 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.settings;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IPowerManager;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.util.Log;
import android.widget.ImageView;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;

import java.util.ArrayList;

import android.util.Log;
import android.content.Context;
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
//这个BrightnessController2.java类名
public class BrightnessController2 implements ToggleSlider.Listener {
    private static final String TAG = "StatusBar.BrightnessController2";
    private static final boolean SHOW_AUTOMATIC_ICON = false;

    /**
     * {@link android.provider.Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ} uses the range [-1, 1].
     * Using this factor, it is converted to [0, BRIGHTNESS_ADJ_RESOLUTION] for the SeekBar.
     */
    private static final float BRIGHTNESS_ADJ_RESOLUTION = 2048;

    private static final int MSG_UPDATE_ICON = 0;
    private static final int MSG_UPDATE_SLIDER = 1;
    private static final int MSG_SET_CHECKED = 2;
    private static final int MSG_ATTACH_LISTENER = 3;
    private static final int MSG_DETACH_LISTENER = 4;
    private static final int MSG_VR_MODE_CHANGED = 5;

    private final int mMinimumBacklight;
    private final int mMaximumBacklight;
    private final int mMinimumBacklightForVr;
    private final int mMaximumBacklightForVr;

    private final Context mContext;
    private final ImageView mIcon;
    private final ToggleSlider mControl;
    private final boolean mAutomaticAvailable;
    private final IPowerManager mPower;
    private final CurrentUserTracker mUserTracker;
    private final IVrManager mVrManager;

    private Handler mBackgroundHandler;
    private final BrightnessObserver mBrightnessObserver;

    private ArrayList<BrightnessStateChangeCallback> mChangeCallbacks =
            new ArrayList<BrightnessStateChangeCallback>();

    private volatile boolean mAutomatic;  // Brightness adjusted automatically using ambient light.
    private volatile boolean mIsVrModeEnabled;
    private boolean mListening;
    private boolean mExternalChange;

    public static final String sys_path = "/sys/class/backlight/pwm3-backlight/brightness";

    public interface BrightnessStateChangeCallback {
        public void onBrightnessLevelChanged();
    }

    /** ContentObserver to watch brightness **/
    private class BrightnessObserver extends ContentObserver {

        private final Uri BRIGHTNESS_MODE_URI =
                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE);
        private final Uri BRIGHTNESS_URI =
                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
        private final Uri BRIGHTNESS_FOR_VR_URI =
                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR);
        private final Uri BRIGHTNESS_ADJ_URI =
                Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ);

        public BrightnessObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            onChange(selfChange, null);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) { //这里面的内容是同步主屏背光节点信息的必须屏蔽掉
            // if (selfChange) return;

            // if (BRIGHTNESS_MODE_URI.equals(uri)) {
            //     mBackgroundHandler.post(mUpdateModeRunnable);
            //     mBackgroundHandler.post(mUpdateSliderRunnable);
            // } else if (BRIGHTNESS_URI.equals(uri) && !mAutomatic) {
            //     mBackgroundHandler.post(mUpdateSliderRunnable);
            // } else if (BRIGHTNESS_FOR_VR_URI.equals(uri)) {
            //     mBackgroundHandler.post(mUpdateSliderRunnable);
            // } else if (BRIGHTNESS_ADJ_URI.equals(uri) && mAutomatic) {
            //     mBackgroundHandler.post(mUpdateSliderRunnable);
            // } else {
            //     mBackgroundHandler.post(mUpdateModeRunnable);
            //     mBackgroundHandler.post(mUpdateSliderRunnable);
            // }
            // for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
            //     cb.onBrightnessLevelChanged();
            // }
        }

        public void startObserving() {
            final ContentResolver cr = mContext.getContentResolver();
            cr.unregisterContentObserver(this);
            cr.registerContentObserver(
                    BRIGHTNESS_MODE_URI,
                    false, this, UserHandle.USER_ALL);
            cr.registerContentObserver(
                    BRIGHTNESS_URI,
                    false, this, UserHandle.USER_ALL);
            cr.registerContentObserver(
                    BRIGHTNESS_FOR_VR_URI,
                    false, this, UserHandle.USER_ALL);
            cr.registerContentObserver(
                    BRIGHTNESS_ADJ_URI,
                    false, this, UserHandle.USER_ALL);
        }

        public void stopObserving() {
            final ContentResolver cr = mContext.getContentResolver();
            cr.unregisterContentObserver(this);
        }

    }

    private final Runnable mStartListeningRunnable = new Runnable() {
        @Override
        public void run() {
            mBrightnessObserver.startObserving();
            mUserTracker.startTracking();

            // Update the slider and mode before attaching the listener so we don't
            // receive the onChanged notifications for the initial values.
            mUpdateModeRunnable.run();
            mUpdateSliderRunnable.run();

            mHandler.sendEmptyMessage(MSG_ATTACH_LISTENER);
        }
    };

    private final Runnable mStopListeningRunnable = new Runnable() {
        @Override
        public void run() {
            mBrightnessObserver.stopObserving();
            mUserTracker.stopTracking();

            mHandler.sendEmptyMessage(MSG_DETACH_LISTENER);
        }
    };

    /**
     * Fetch the brightness mode from the system settings and update the icon. Should be called from
     * background thread.
     */
    private final Runnable mUpdateModeRunnable = new Runnable() {
        @Override
        public void run() {
            if (mAutomaticAvailable) {
                int automatic;
                automatic = Settings.System.getIntForUser(mContext.getContentResolver(),
                        Settings.System.SCREEN_BRIGHTNESS_MODE,
                        Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
                        UserHandle.USER_CURRENT);
                mAutomatic = automatic != Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
                mHandler.obtainMessage(MSG_UPDATE_ICON, mAutomatic ? 1 : 0).sendToTarget();
            } else {
                mHandler.obtainMessage(MSG_SET_CHECKED, 0).sendToTarget();
                mHandler.obtainMessage(MSG_UPDATE_ICON, 0 /* automatic */).sendToTarget();
            }
        }
    };

    /**
     * Fetch the brightness from the system settings and update the slider. Should be called from
     * background thread.
     */
    private final Runnable mUpdateSliderRunnable = new Runnable() {
        @Override
        public void run() {
            if (mIsVrModeEnabled) {
                int value = Settings.System.getIntForUser(mContext.getContentResolver(),
                        Settings.System.SCREEN_BRIGHTNESS_FOR_VR, mMaximumBacklight,
                        UserHandle.USER_CURRENT);
                mHandler.obtainMessage(MSG_UPDATE_SLIDER,
                        mMaximumBacklightForVr - mMinimumBacklightForVr,
                        value - mMinimumBacklightForVr).sendToTarget();
            } else if (mAutomatic) {
                float value = Settings.System.getFloatForUser(mContext.getContentResolver(),
                        Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0,
                        UserHandle.USER_CURRENT);
                mHandler.obtainMessage(MSG_UPDATE_SLIDER, (int) BRIGHTNESS_ADJ_RESOLUTION,
                        (int) ((value + 1) * BRIGHTNESS_ADJ_RESOLUTION / 2f)).sendToTarget();
            } else {
                int value;
                value = Settings.System.getIntForUser(mContext.getContentResolver(),
                        Settings.System.SCREEN_BRIGHTNESS, mMaximumBacklight,
                        UserHandle.USER_CURRENT);
                mHandler.obtainMessage(MSG_UPDATE_SLIDER, mMaximumBacklight - mMinimumBacklight,
                        value - mMinimumBacklight).sendToTarget();
            }
        }
    };

    private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
        @Override
        public void onVrStateChanged(boolean enabled) {
            mHandler.obtainMessage(MSG_VR_MODE_CHANGED, enabled ? 1 : 0, 0)
                    .sendToTarget();
        }
    };

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mExternalChange = true;
            try {
                switch (msg.what) {
                    case MSG_UPDATE_ICON:
                        updateIcon(msg.arg1 != 0);
                        break;
                    case MSG_UPDATE_SLIDER:
                        mControl.setMax(msg.arg1);
                        mControl.setValue(msg.arg2);
                        break;
                    case MSG_SET_CHECKED:
                        mControl.setChecked(msg.arg1 != 0);
                        break;
                    case MSG_ATTACH_LISTENER:
                        mControl.setOnChangedListener(BrightnessController2.this);//这个方法名必须与BrightnessController2.java类名相同
                        break;
                    case MSG_DETACH_LISTENER:
                        mControl.setOnChangedListener(null);
                        break;
                    case MSG_VR_MODE_CHANGED:
                        updateVrMode(msg.arg1 != 0);
                        break;
                    default:
                        super.handleMessage(msg);
                }
            } finally {
                mExternalChange = false;
            }
        }
    };
//这个方法名必须与BrightnessController2.java类名相同
    public BrightnessController2(Context context, ImageView icon, ToggleSlider control) {
        mContext = context;
        mIcon = icon;
        mControl = control;
        mBackgroundHandler = new Handler(Looper.getMainLooper());

         Log.i(TAG, "----------com in BrightnessController2------------");
        mUserTracker = new CurrentUserTracker(mContext) {
            @Override
            public void onUserSwitched(int newUserId) {
                mBackgroundHandler.post(mUpdateModeRunnable);
                mBackgroundHandler.post(mUpdateSliderRunnable);
            }
        };
        mBrightnessObserver = new BrightnessObserver(mHandler);

        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mMinimumBacklight = pm.getMinimumScreenBrightnessSetting();
        mMaximumBacklight = pm.getMaximumScreenBrightnessSetting();
        mMinimumBacklightForVr = pm.getMinimumScreenBrightnessForVrSetting();
        mMaximumBacklightForVr = pm.getMaximumScreenBrightnessForVrSetting();

        mAutomaticAvailable = context.getResources().getBoolean(
                com.android.internal.R.bool.config_automatic_brightness_available);
        mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
        mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService("vrmanager"));
    }

    

    public void setBackgroundLooper(Looper backgroundLooper) {
        mBackgroundHandler = new Handler(backgroundLooper);
    }

    public void addStateChangedCallback(BrightnessStateChangeCallback cb) {
        mChangeCallbacks.add(cb);
    }

    public boolean removeStateChangedCallback(BrightnessStateChangeCallback cb) {
        return mChangeCallbacks.remove(cb);
    }

    @Override
    public void onInit(ToggleSlider control) {
        // Do nothing
    }
//注册回调方法
    public void registerCallbacks() {
         Log.i(TAG, "----------com in registerCallbacks------------");

        if (mListening) {
            return;
        }

        if (mVrManager != null) {
            try {
                mVrManager.registerListener(mVrStateCallbacks);
                mIsVrModeEnabled = mVrManager.getVrModeState();
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to register VR mode state listener: ", e);
            }
        }

        mBackgroundHandler.post(mStartListeningRunnable);
        mListening = true;
    }
//注销回调方法
    /** Unregister all call backs, both to and from the controller */
    public void unregisterCallbacks() {
        Log.i(TAG, "----------com in unregisterCallbacks------------");

        if (!mListening) {
            return;
        }

        if (mVrManager != null) {
            try {
                mVrManager.unregisterListener(mVrStateCallbacks);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to unregister VR mode state listener: ", e);
            }
        }

        mBackgroundHandler.post(mStopListeningRunnable);
        mListening = false;
    }

    @Override
    public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
            boolean stopTracking) {
         Log.i(TAG, "----------com in onChanged------------");
//这里原来是监听拖动条改变的事件中,现在我们只需注意把拖动条的值value写进副屏背光节点/sys/class/backlight/pwm3-backlight/brightness 这个操作就可以了
             writeSysFile(sys_path,  value +"");   


    }



//这里是新增加往节点里写值方法
      public static void writeSysFile(String sys_path, String value) {

        if (sys_path == null || sys_path.length() == 0) return;

        File file = new File(sys_path);
        if (!file.exists()) {
            return;
        }

        if (file.isDirectory()) {
        } else {
            BufferedWriter writer = null;
            try {

                writer = new BufferedWriter(new FileWriter(sys_path));
                writer.write(value);//写值操作
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void setMode(int mode) {
        Settings.System.putIntForUser(mContext.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS_MODE, mode,
                mUserTracker.getCurrentUserId());
    }

    private void setBrightness(int brightness) {
        try {
            mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
        } catch (RemoteException ex) {
        }
    }

    private void setBrightnessAdj(float adj) {
        try {
            mPower.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(adj);
        } catch (RemoteException ex) {
        }
    }

    private void updateIcon(boolean automatic) {
        if (mIcon != null) { //这里是加载背光图标布局需要修改
            mIcon.setImageResource(automatic && SHOW_AUTOMATIC_ICON ?
                    com.android.systemui.R.drawable.ic_qs_brightness_auto_on_other :
                    com.android.systemui.R.drawable.ic_qs_brightness_auto_off_other);
        }
    }

    private void updateVrMode(boolean isEnabled) {
        if (mIsVrModeEnabled != isEnabled) {
            mIsVrModeEnabled = isEnabled;
            mBackgroundHandler.post(mUpdateSliderRunnable);
        }
    }
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要将RK3288设备升级到Android 7.1并root,您可以按照以下步骤进行操作: 1. 下载适用于RK3288Android 7.1固件,确保固件是适用于您的设备型号的版本。 2. 将设备连接到电脑,并将固件文件复制到设备的内部存储或SD卡中。 3. 打开设备设置,找到“关于设备”选项,然后点击“软件版本”多次,直到开启开发者选项。 4. 返回上级菜单,找到“开发者选项”,然后进入并启用“USB调试”选项。 5. 断开设备与电脑的连接,并将设备关机。 6. 进入设备的恢复模式。不同设备的进入方法可能有所不同,通常是按住音量减和电源键直到进入恢复模式。 7. 在恢复模式下,使用音量键导航到“安装Zip文件”或类似选项,并使用电源键确认选择。 8. 导航到存储设备上的固件文件,选择并确认安装。 9. 安装完成后,在恢复模式下重新启动设备。 10. 下载适用于Android 7.1的root工具,如Magisk或SuperSU。 11. 确保设备已连接到电脑,将root工具复制到设备的内部存储或SD卡中。 12. 断开设备与电脑的连接,并将设备关机。 13. 重新进入恢复模式,导航到“安装Zip文件”或类似选项。 14. 选择并确认安装root工具。 15. 完成root工具的安装后,重新启动设备。 现在,您的RK3288设备应该已成功升级到Android 7.1并root。请注意,root操作可能会使设备的保修失效,并可能存在安全风险,请谨慎操作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值