美文网首页
2021-05-19 [RK3399][Android7.1]

2021-05-19 [RK3399][Android7.1]

作者: fjasmin | 来源:发表于2021-05-19 15:40 被阅读0次

    系统环境:

    Platform: RK3399
    OS: Android 7.1
    Kernel: v4.4.83

    使用场景

    最近在研究AndroidL Settings的代码,写了一个简单的控件来操控屏幕亮度。
    其实,调节屏幕亮度的场景应用很广,例如很多视频应用都响应touch事件来进行亮度调节。
    [屏幕亮度调节模式]
    首先,需要明确屏幕亮度有两种调节模式:
    Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC:值为1,自动调节亮度。
    Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL:值为0,手动模式。
    如果需要实现亮度调节,首先需要设置屏幕亮度调节模式为手动模式

    BrightnessDialog及其控制

    # BrightnessDialog
    frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessDialog.java
    public class BrightnessDialog extends Activity {
    
        private BrightnessController mBrightnessController;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            final Window window = getWindow();
    
            window.setGravity(Gravity.TOP);
            window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
            window.requestFeature(Window.FEATURE_NO_TITLE);
    
            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);
        }
    
        @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();
        }
    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
                    || keyCode == KeyEvent.KEYCODE_VOLUME_UP
                    || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
                finish();
            }
    
            return super.onKeyDown(keyCode, event);
        }
    }
    
    

    BrightnessDialog控制

    # BrightnessDialog控制
    frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessController.java
    
    public class BrightnessController implements ToggleSlider.Listener {
        private static final String TAG = "StatusBar.BrightnessController";
        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 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(BrightnessController.this);
                            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;
                }
            }
        };
    
        public BrightnessController(Context context, ImageView icon, ToggleSlider control) {
            mContext = context;
            mIcon = icon;
            mControl = control;
            mBackgroundHandler = new Handler(Looper.getMainLooper());
            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() {
            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() {
            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) {
            updateIcon(mAutomatic);
            Log.e("fjasmin",":onChanged Backlight :"+ value);
            if (mExternalChange) return;
    
            if (mIsVrModeEnabled) {
                Log.e("fjasmin","------------ACTION_BRIGHTNESS_FOR_VR------------------");
                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) {
                Log.e("fjasmin","------------ACTION_BRIGHTNESS------------------");
                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 {
                Log.e("fjasmin","------------ACTION_BRIGHTNESS_AUTO------------------");
                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();
            }
        }
    
        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 :
                        com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
            }
        }
    
        private void updateVrMode(boolean isEnabled) {
            if (mIsVrModeEnabled != isEnabled) {
                mIsVrModeEnabled = isEnabled;
                mBackgroundHandler.post(mUpdateSliderRunnable);
            }
        }
    }
    
    
    private void updateSlider(int val, boolean inVrMode) {
        final int min;
        final int max;
        if (inVrMode) {
            min = mMinimumBacklightForVr;
            max = mMaximumBacklightForVr;
        } else {
            min = mMinimumBacklight;
            max = mMaximumBacklight;
        }
        if (val == convertGammaToLinear(mControl.getValue(), min, max)) {
            // If we have more resolution on the slider than we do in the actual setting, then
            // multiple slider positions will map to the same setting value. Thus, if we see a
            // setting value here that maps to the current slider position, we don't bother to
            // calculate the new slider position since it may differ and look like a brightness
            // change to the user even though it isn't one.
            return;
        }
        final int sliderVal = convertLinearToGamma(val, min, max);
        animateSliderTo(sliderVal);
    }
    
    

    相关文章

      网友评论

          本文标题:2021-05-19 [RK3399][Android7.1]

          本文链接:https://www.haomeiwen.com/subject/hzupjltx.html