Loading core/res/res/values/colors.xml +0 −4 Original line number Diff line number Diff line Loading @@ -552,10 +552,6 @@ <color name="accessibility_magnification_thumbnail_container_background_color">#99000000</color> <color name="accessibility_magnification_thumbnail_container_stroke_color">#FFFFFF</color> <!-- Color of camera light when camera is in use --> <color name="camera_privacy_light_day">#FFFFFF</color> <color name="camera_privacy_light_night">#FFFFFF</color> <!-- Lily Language Picker language item view colors --> <color name="language_picker_item_text_color">#202124</color> <color name="language_picker_item_text_color_secondary">#5F6368</color> Loading core/res/res/values/config.xml +13 −2 Original line number Diff line number Diff line Loading @@ -6441,8 +6441,19 @@ <!-- Interval in milliseconds to average light sensor values for camera light brightness --> <integer name="config_cameraPrivacyLightAlsAveragingIntervalMillis">3000</integer> <!-- Light sensor's lux value to use as the threshold between using day or night brightness --> <integer name="config_cameraPrivacyLightAlsNightThreshold">4</integer> <!-- Ambient Light sensor's lux values to use as the threshold between brightness colors defined by config_cameraPrivacyLightColors. If the ambient brightness less than the first element in this array then lights of type "camera" will be set to the color in position 0 of config_cameraPrivacyLightColors. This array must be strictly increasing and have a length of zero means there is only one brightness --> <integer-array name="config_cameraPrivacyLightAlsLuxThresholds"> </integer-array> <!-- Colors to configure the camera privacy light at different brightnesses. This array must have exactly one more entry than config_cameraPrivacyLightAlsLuxThresholds, or a length of zero if the feature isn't supported. If nonempty and the device doesn't have an ambient light sensor the last element in this array will be the only one used --> <array name="config_cameraPrivacyLightColors"> </array> <!-- List of system components which are allowed to receive ServiceState entries in an un-sanitized form, even if the location toggle is off. This is intended ONLY for system Loading core/res/res/values/symbols.xml +2 −3 Original line number Diff line number Diff line Loading @@ -4963,10 +4963,9 @@ <java-symbol type="string" name="vdm_camera_access_denied" /> <java-symbol type="string" name="vdm_secure_window" /> <java-symbol type="color" name="camera_privacy_light_day"/> <java-symbol type="color" name="camera_privacy_light_night"/> <java-symbol type="integer" name="config_cameraPrivacyLightAlsAveragingIntervalMillis"/> <java-symbol type="integer" name="config_cameraPrivacyLightAlsNightThreshold"/> <java-symbol type="array" name="config_cameraPrivacyLightAlsLuxThresholds"/> <java-symbol type="array" name="config_cameraPrivacyLightColors"/> <java-symbol type="bool" name="config_bg_current_drain_monitor_enabled" /> <java-symbol type="array" name="config_bg_current_drain_threshold_to_restricted_bucket" /> Loading services/core/java/com/android/server/sensorprivacy/CameraPrivacyLightController.java +45 −23 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.sensorprivacy; import static android.hardware.SensorManager.SENSOR_DELAY_NORMAL; import android.annotation.ColorInt; import android.app.AppOpsManager; import android.content.Context; import android.hardware.Sensor; Loading @@ -39,6 +38,7 @@ import android.util.Pair; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.FgThread; import java.util.ArrayDeque; Loading @@ -48,12 +48,10 @@ import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedListener, SensorEventListener { @VisibleForTesting static final double LIGHT_VALUE_MULTIPLIER = 1 / Math.log(1.1); private static final double LIGHT_VALUE_MULTIPLIER = 1 / Math.log(1.1); private final Handler mHandler; private final Executor mExecutor; Loading @@ -69,11 +67,6 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis private LightsManager.LightsSession mLightsSession = null; @ColorInt private final int mDayColor; @ColorInt private final int mNightColor; private final Sensor mLightSensor; private boolean mIsAmbientLightListenerRegistered = false; Loading @@ -81,7 +74,9 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis /** When average of the time integral over the past {@link #mMovingAverageIntervalMillis} * milliseconds of the log_1.1(lux(t)) is greater than this value, use the daytime brightness * else use nighttime brightness. */ private final long mNightThreshold; private final long[] mThresholds; private final int[] mColors; private final ArrayDeque<Pair<Long, Integer>> mAmbientLightValues = new ArrayDeque<>(); /** Tracks the Riemann sum of {@link #mAmbientLightValues} to avoid O(n) operations when sum is * needed */ Loading @@ -101,6 +96,20 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis @VisibleForTesting CameraPrivacyLightController(Context context, Looper looper) { mColors = context.getResources().getIntArray(R.array.config_cameraPrivacyLightColors); if (ArrayUtils.isEmpty(mColors)) { mHandler = null; mExecutor = null; mContext = null; mAppOpsManager = null; mLightsManager = null; mSensorManager = null; mLightSensor = null; mMovingAverageIntervalMillis = 0; mThresholds = null; // Return here before this class starts interacting with other services. return; } mContext = context; mHandler = new Handler(looper); Loading @@ -109,14 +118,20 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis mAppOpsManager = mContext.getSystemService(AppOpsManager.class); mLightsManager = mContext.getSystemService(LightsManager.class); mSensorManager = mContext.getSystemService(SensorManager.class); mDayColor = mContext.getColor(R.color.camera_privacy_light_day); mNightColor = mContext.getColor(R.color.camera_privacy_light_night); mMovingAverageIntervalMillis = mContext.getResources() .getInteger(R.integer.config_cameraPrivacyLightAlsAveragingIntervalMillis); mNightThreshold = (long) (Math.log(mContext.getResources() .getInteger(R.integer.config_cameraPrivacyLightAlsNightThreshold)) * LIGHT_VALUE_MULTIPLIER); int[] thresholdsLux = mContext.getResources().getIntArray( R.array.config_cameraPrivacyLightAlsLuxThresholds); if (thresholdsLux.length != mColors.length - 1) { throw new IllegalStateException("There must be exactly one more color than thresholds." + " Found " + mColors.length + " colors and " + thresholdsLux.length + " thresholds."); } mThresholds = new long[thresholdsLux.length]; for (int i = 0; i < thresholdsLux.length; i++) { int luxValue = thresholdsLux[i]; mThresholds[i] = (long) (Math.log(luxValue) * LIGHT_VALUE_MULTIPLIER); } List<Light> lights = mLightsManager.getLights(); for (int i = 0; i < lights.size(); i++) { Loading Loading @@ -223,13 +238,8 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis mLightsSession.close(); mLightsSession = null; } else { int lightColor; if (mLightSensor != null && getLiveAmbientLightTotal() < getCurrentIntervalMillis() * mNightThreshold) { lightColor = mNightColor; } else { lightColor = mDayColor; } int lightColor = mLightSensor == null ? mColors[mColors.length - 1] : computeCurrentLightColor(); if (mLastLightColor == lightColor && mLightsSession != null) { return; Loading @@ -252,6 +262,18 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis } } private int computeCurrentLightColor() { long liveAmbientLightTotal = getLiveAmbientLightTotal(); long currentInterval = getCurrentIntervalMillis(); for (int i = 0; i < mThresholds.length; i++) { if (liveAmbientLightTotal < currentInterval * mThresholds[i]) { return mColors[i]; } } return mColors[mColors.length - 1]; } private void updateSensorListener(boolean shouldSessionEnd) { if (shouldSessionEnd && mIsAmbientLightListenerRegistered) { mSensorManager.unregisterListener(this); Loading services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java +122 −190 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/res/res/values/colors.xml +0 −4 Original line number Diff line number Diff line Loading @@ -552,10 +552,6 @@ <color name="accessibility_magnification_thumbnail_container_background_color">#99000000</color> <color name="accessibility_magnification_thumbnail_container_stroke_color">#FFFFFF</color> <!-- Color of camera light when camera is in use --> <color name="camera_privacy_light_day">#FFFFFF</color> <color name="camera_privacy_light_night">#FFFFFF</color> <!-- Lily Language Picker language item view colors --> <color name="language_picker_item_text_color">#202124</color> <color name="language_picker_item_text_color_secondary">#5F6368</color> Loading
core/res/res/values/config.xml +13 −2 Original line number Diff line number Diff line Loading @@ -6441,8 +6441,19 @@ <!-- Interval in milliseconds to average light sensor values for camera light brightness --> <integer name="config_cameraPrivacyLightAlsAveragingIntervalMillis">3000</integer> <!-- Light sensor's lux value to use as the threshold between using day or night brightness --> <integer name="config_cameraPrivacyLightAlsNightThreshold">4</integer> <!-- Ambient Light sensor's lux values to use as the threshold between brightness colors defined by config_cameraPrivacyLightColors. If the ambient brightness less than the first element in this array then lights of type "camera" will be set to the color in position 0 of config_cameraPrivacyLightColors. This array must be strictly increasing and have a length of zero means there is only one brightness --> <integer-array name="config_cameraPrivacyLightAlsLuxThresholds"> </integer-array> <!-- Colors to configure the camera privacy light at different brightnesses. This array must have exactly one more entry than config_cameraPrivacyLightAlsLuxThresholds, or a length of zero if the feature isn't supported. If nonempty and the device doesn't have an ambient light sensor the last element in this array will be the only one used --> <array name="config_cameraPrivacyLightColors"> </array> <!-- List of system components which are allowed to receive ServiceState entries in an un-sanitized form, even if the location toggle is off. This is intended ONLY for system Loading
core/res/res/values/symbols.xml +2 −3 Original line number Diff line number Diff line Loading @@ -4963,10 +4963,9 @@ <java-symbol type="string" name="vdm_camera_access_denied" /> <java-symbol type="string" name="vdm_secure_window" /> <java-symbol type="color" name="camera_privacy_light_day"/> <java-symbol type="color" name="camera_privacy_light_night"/> <java-symbol type="integer" name="config_cameraPrivacyLightAlsAveragingIntervalMillis"/> <java-symbol type="integer" name="config_cameraPrivacyLightAlsNightThreshold"/> <java-symbol type="array" name="config_cameraPrivacyLightAlsLuxThresholds"/> <java-symbol type="array" name="config_cameraPrivacyLightColors"/> <java-symbol type="bool" name="config_bg_current_drain_monitor_enabled" /> <java-symbol type="array" name="config_bg_current_drain_threshold_to_restricted_bucket" /> Loading
services/core/java/com/android/server/sensorprivacy/CameraPrivacyLightController.java +45 −23 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.sensorprivacy; import static android.hardware.SensorManager.SENSOR_DELAY_NORMAL; import android.annotation.ColorInt; import android.app.AppOpsManager; import android.content.Context; import android.hardware.Sensor; Loading @@ -39,6 +38,7 @@ import android.util.Pair; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.FgThread; import java.util.ArrayDeque; Loading @@ -48,12 +48,10 @@ import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedListener, SensorEventListener { @VisibleForTesting static final double LIGHT_VALUE_MULTIPLIER = 1 / Math.log(1.1); private static final double LIGHT_VALUE_MULTIPLIER = 1 / Math.log(1.1); private final Handler mHandler; private final Executor mExecutor; Loading @@ -69,11 +67,6 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis private LightsManager.LightsSession mLightsSession = null; @ColorInt private final int mDayColor; @ColorInt private final int mNightColor; private final Sensor mLightSensor; private boolean mIsAmbientLightListenerRegistered = false; Loading @@ -81,7 +74,9 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis /** When average of the time integral over the past {@link #mMovingAverageIntervalMillis} * milliseconds of the log_1.1(lux(t)) is greater than this value, use the daytime brightness * else use nighttime brightness. */ private final long mNightThreshold; private final long[] mThresholds; private final int[] mColors; private final ArrayDeque<Pair<Long, Integer>> mAmbientLightValues = new ArrayDeque<>(); /** Tracks the Riemann sum of {@link #mAmbientLightValues} to avoid O(n) operations when sum is * needed */ Loading @@ -101,6 +96,20 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis @VisibleForTesting CameraPrivacyLightController(Context context, Looper looper) { mColors = context.getResources().getIntArray(R.array.config_cameraPrivacyLightColors); if (ArrayUtils.isEmpty(mColors)) { mHandler = null; mExecutor = null; mContext = null; mAppOpsManager = null; mLightsManager = null; mSensorManager = null; mLightSensor = null; mMovingAverageIntervalMillis = 0; mThresholds = null; // Return here before this class starts interacting with other services. return; } mContext = context; mHandler = new Handler(looper); Loading @@ -109,14 +118,20 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis mAppOpsManager = mContext.getSystemService(AppOpsManager.class); mLightsManager = mContext.getSystemService(LightsManager.class); mSensorManager = mContext.getSystemService(SensorManager.class); mDayColor = mContext.getColor(R.color.camera_privacy_light_day); mNightColor = mContext.getColor(R.color.camera_privacy_light_night); mMovingAverageIntervalMillis = mContext.getResources() .getInteger(R.integer.config_cameraPrivacyLightAlsAveragingIntervalMillis); mNightThreshold = (long) (Math.log(mContext.getResources() .getInteger(R.integer.config_cameraPrivacyLightAlsNightThreshold)) * LIGHT_VALUE_MULTIPLIER); int[] thresholdsLux = mContext.getResources().getIntArray( R.array.config_cameraPrivacyLightAlsLuxThresholds); if (thresholdsLux.length != mColors.length - 1) { throw new IllegalStateException("There must be exactly one more color than thresholds." + " Found " + mColors.length + " colors and " + thresholdsLux.length + " thresholds."); } mThresholds = new long[thresholdsLux.length]; for (int i = 0; i < thresholdsLux.length; i++) { int luxValue = thresholdsLux[i]; mThresholds[i] = (long) (Math.log(luxValue) * LIGHT_VALUE_MULTIPLIER); } List<Light> lights = mLightsManager.getLights(); for (int i = 0; i < lights.size(); i++) { Loading Loading @@ -223,13 +238,8 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis mLightsSession.close(); mLightsSession = null; } else { int lightColor; if (mLightSensor != null && getLiveAmbientLightTotal() < getCurrentIntervalMillis() * mNightThreshold) { lightColor = mNightColor; } else { lightColor = mDayColor; } int lightColor = mLightSensor == null ? mColors[mColors.length - 1] : computeCurrentLightColor(); if (mLastLightColor == lightColor && mLightsSession != null) { return; Loading @@ -252,6 +262,18 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis } } private int computeCurrentLightColor() { long liveAmbientLightTotal = getLiveAmbientLightTotal(); long currentInterval = getCurrentIntervalMillis(); for (int i = 0; i < mThresholds.length; i++) { if (liveAmbientLightTotal < currentInterval * mThresholds[i]) { return mColors[i]; } } return mColors[mColors.length - 1]; } private void updateSensorListener(boolean shouldSessionEnd) { if (shouldSessionEnd && mIsAmbientLightListenerRegistered) { mSensorManager.unregisterListener(this); Loading
services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java +122 −190 File changed.Preview size limit exceeded, changes collapsed. Show changes