Merge changes from topic "CameraMicQSTile"

* changes:
  Provide IndividualSensorPrivacyController instead of bind it
  Add mic sensor privacy QS tile
  Hook up camera toggle QS tile to SensorPrivacyManager
  Create camera toggle tile
This commit is contained in:
Philip P. Moltmann
2021-01-15 19:00:34 +00:00
committed by Android (Google) Code Review
18 changed files with 543 additions and 17 deletions

View File

@@ -3512,6 +3512,17 @@ public abstract class PackageManager {
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_TUNER = "android.hardware.tv.tuner";
/**
* Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device supports a enabling/disabling sensor privacy for
* camera. When sensory privacy for the camera is enabled no camera data is send to clients,
* e.g. the view finder in a camera app would appear blank.
*
* @hide
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_CAMERA_TOGGLE = "android.hardware.camera.toggle";
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device has
* the necessary changes to support app enumeration.

View File

@@ -0,0 +1,29 @@
<!--
~ Copyright (C) 2021 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="m18,12c-2.75,0 -5,2.25 -5,5 0,2.75 2.25,5 5,5 2.75,0 5,-2.25 5,-5 0,-2.75 -2.1667,-5 -5,-5zM15.5,17.8333h5v-1.6666h-5z"
android:fillColor="#30302a"
android:fillType="evenOdd"/>
<path
android:pathData="m16.4,5.5004h-2.536l-1.464,-1.6H7.6l-1.464,1.6H3.6c-0.88,0 -1.6,0.72 -1.6,1.6v9.6c0,0.88 0.72,1.6 1.6,1.6h8.5413C12.0488,17.8817 12,17.4465 12,17c0,-0.1005 0.0025,-0.2004 0.0073,-0.2996H3.6V7.1004H16.4V11.2157C16.9094,11.0751 17.4459,11 18,11V7.1004c0,-0.88 -0.72,-1.6 -1.6,-1.6zM6.8,11.9004c0,-1.768 1.432,-3.2 3.2,-3.2 1.768,0 3.2,1.432 3.2,3.2 0,1.768 -1.432,3.2 -3.2,3.2 -1.768,0 -3.2,-1.432 -3.2,-3.2z"
android:fillColor="#30302a"
android:fillType="evenOdd"/>
</vector>

View File

@@ -0,0 +1,29 @@
<!--
~ Copyright (C) 2021 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="m17,12c-2.75,0 -5,2.25 -5,5 0,2.75 2.25,5 5,5 2.75,0 5,-2.25 5,-5 0,-2.75 -2.1667,-5 -5,-5zM14.5,17.8333h5v-1.6666h-5z"
android:fillColor="#30302a"
android:fillType="evenOdd"/>
<path
android:pathData="m12,12c0,1.66 -1.34,3 -3,3C7.34,15 6,13.66 6,12L6,6C6,4.34 7.34,3 9,3c1.66,0 3,1.34 3,3zM9,5C8.45,5 8,5.45 8,6v6c0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1L10,6C10,5.45 9.55,5 9,5ZM11.0147,16.577C10.3983,16.849 9.7167,17 9,17 6.24,17 4,14.76 4,12L2,12c0,3.53 2.61,6.43 6,6.92L8,22h2v-3.08c0.4212,-0.0609 0.8303,-0.1589 1.2238,-0.2908C11.078,18.1111 11,17.5647 11,17c0,-0.1422 0.0049,-0.2832 0.0147,-0.423z"
android:fillColor="#30302a"
android:fillType="evenOdd"/>
</vector>

View File

@@ -107,7 +107,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness
wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness,cameratoggle,mictoggle
</string>
<!-- The tiles to display in QuickSettings -->

View File

@@ -821,6 +821,10 @@
<string name="quick_settings_location_label">Location</string>
<!-- QuickSettings: Location (Off) [CHAR LIMIT=NONE] -->
<string name="quick_settings_location_off_label">Location Off</string>
<!-- QuickSettings: Camera [CHAR LIMIT=NONE] -->
<string name="quick_settings_camera_label">Block Camera</string>
<!-- QuickSettings: Microphone [CHAR LIMIT=NONE] -->
<string name="quick_settings_mic_label">Mute Microphone</string>
<!-- QuickSettings: Media device [CHAR LIMIT=NONE] -->
<string name="quick_settings_media_device_label">Media device</string>
<!-- QuickSettings: RSSI [CHAR LIMIT=NONE] -->

View File

@@ -50,6 +50,10 @@
android:key="bluetooth"
android:title="@string/quick_settings_bluetooth_label" />
<com.android.systemui.tuner.StatusBarSwitch
android:key="cameratoggle"
android:title="@string/quick_settings_camera_label" />
<!-- nfc -->
<!-- tty -->
<!-- speakerphone -->

View File

@@ -20,6 +20,7 @@ import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME
import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
import android.content.Context;
import android.hardware.SensorPrivacyManager;
import android.os.Handler;
import android.os.PowerManager;
@@ -62,6 +63,10 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyControllerImpl;
import com.android.systemui.statusbar.policy.SensorPrivacyController;
import com.android.systemui.statusbar.policy.SensorPrivacyControllerImpl;
import javax.inject.Named;
@@ -116,6 +121,25 @@ public abstract class SystemUIDefaultModule {
return bC;
}
@Provides
@SysUISingleton
static SensorPrivacyController provideSensorPrivacyController(
SensorPrivacyManager sensorPrivacyManager) {
SensorPrivacyController spC = new SensorPrivacyControllerImpl(sensorPrivacyManager);
spC.init();
return spC;
}
@Provides
@SysUISingleton
static IndividualSensorPrivacyController provideIndividualSensorPrivacyController(
SensorPrivacyManager sensorPrivacyManager) {
IndividualSensorPrivacyController spC = new IndividualSensorPrivacyControllerImpl(
sensorPrivacyManager);
spC.init();
return spC;
}
@Binds
@SysUISingleton
public abstract QSFactory bindQSFactory(QSFactoryImpl qsFactoryImpl);

View File

@@ -30,6 +30,7 @@ import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tiles.AirplaneModeTile;
import com.android.systemui.qs.tiles.BatterySaverTile;
import com.android.systemui.qs.tiles.BluetoothTile;
import com.android.systemui.qs.tiles.CameraToggleTile;
import com.android.systemui.qs.tiles.CastTile;
import com.android.systemui.qs.tiles.CellularTile;
import com.android.systemui.qs.tiles.ColorInversionTile;
@@ -39,6 +40,7 @@ import com.android.systemui.qs.tiles.FlashlightTile;
import com.android.systemui.qs.tiles.HotspotTile;
import com.android.systemui.qs.tiles.InternetTile;
import com.android.systemui.qs.tiles.LocationTile;
import com.android.systemui.qs.tiles.MicrophoneToggleTile;
import com.android.systemui.qs.tiles.NfcTile;
import com.android.systemui.qs.tiles.NightDisplayTile;
import com.android.systemui.qs.tiles.ReduceBrightColorsTile;
@@ -83,6 +85,8 @@ public class QSFactoryImpl implements QSFactory {
private final Provider<UiModeNightTile> mUiModeNightTileProvider;
private final Provider<ScreenRecordTile> mScreenRecordTileProvider;
private final Provider<ReduceBrightColorsTile> mReduceBrightColorsTileProvider;
private final Provider<CameraToggleTile> mCameraToggleTileProvider;
private final Provider<MicrophoneToggleTile> mMicrophoneToggleTileProvider;
private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@@ -115,7 +119,9 @@ public class QSFactoryImpl implements QSFactory {
Provider<GarbageMonitor.MemoryTile> memoryTileProvider,
Provider<UiModeNightTile> uiModeNightTileProvider,
Provider<ScreenRecordTile> screenRecordTileProvider,
Provider<ReduceBrightColorsTile> reduceBrightColorsTileProvider) {
Provider<ReduceBrightColorsTile> reduceBrightColorsTileProvider,
Provider<CameraToggleTile> cameraToggleTileProvider,
Provider<MicrophoneToggleTile> microphoneToggleTileProvider) {
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
@@ -143,6 +149,8 @@ public class QSFactoryImpl implements QSFactory {
mUiModeNightTileProvider = uiModeNightTileProvider;
mScreenRecordTileProvider = screenRecordTileProvider;
mReduceBrightColorsTileProvider = reduceBrightColorsTileProvider;
mCameraToggleTileProvider = cameraToggleTileProvider;
mMicrophoneToggleTileProvider = microphoneToggleTileProvider;
}
public QSTile createTile(String tileSpec) {
@@ -198,6 +206,10 @@ public class QSFactoryImpl implements QSFactory {
return mScreenRecordTileProvider.get();
case "reduce_brightness":
return mReduceBrightColorsTileProvider.get();
case "cameratoggle":
return mCameraToggleTileProvider.get();
case "mictoggle":
return mMicrophoneToggleTileProvider.get();
}
// Custom tiles

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2020 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 static android.service.SensorPrivacyIndividualEnabledSensorProto.CAMERA;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.annotation.StringRes;
import android.os.Handler;
import android.os.Looper;
import android.provider.DeviceConfig;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
import javax.inject.Inject;
public class CameraToggleTile extends SensorPrivacyToggleTile {
@Inject
protected CameraToggleTile(QSHost host,
@Background Looper backgroundLooper,
@Main Handler mainHandler,
MetricsLogger metricsLogger,
StatusBarStateController statusBarStateController,
ActivityStarter activityStarter,
QSLogger qsLogger,
IndividualSensorPrivacyController sensorPrivacyController) {
super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
activityStarter, qsLogger, sensorPrivacyController);
}
@Override
public boolean isAvailable() {
return /*getHost().getContext().getPackageManager().hasSystemFeature(FEATURE_CAMERA_TOGGLE)
&& */whitelistIpcs(() -> DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
"camera_toggle_enabled",
false));
}
@Override
public @DrawableRes int getIconRes() {
return R.drawable.ic_camera_blocked;
}
@Override
public @NonNull CharSequence getTileLabel() {
return mContext.getString(R.string.quick_settings_camera_label);
}
@Override
public int getSensorId() {
return CAMERA;
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2020 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 static android.service.SensorPrivacyIndividualEnabledSensorProto.MICROPHONE;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.os.Handler;
import android.os.Looper;
import android.provider.DeviceConfig;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
import javax.inject.Inject;
public class MicrophoneToggleTile extends SensorPrivacyToggleTile {
@Inject
protected MicrophoneToggleTile(QSHost host,
@Background Looper backgroundLooper,
@Main Handler mainHandler,
MetricsLogger metricsLogger,
StatusBarStateController statusBarStateController,
ActivityStarter activityStarter,
QSLogger qsLogger,
IndividualSensorPrivacyController sensorPrivacyController) {
super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
activityStarter, qsLogger, sensorPrivacyController);
}
@Override
public boolean isAvailable() {
return whitelistIpcs(() -> DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
"mic_toggle_enabled",
false));
}
@Override
public @DrawableRes int getIconRes() {
return R.drawable.ic_mic_blocked;
}
@Override
public @NonNull CharSequence getTileLabel() {
return mContext.getString(R.string.quick_settings_mic_label);
}
@Override
public int getSensorId() {
return MICROPHONE;
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (C) 2020 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.content.Intent;
import android.hardware.SensorPrivacyManager.IndividualSensor;
import android.os.Handler;
import android.os.Looper;
import android.service.quicksettings.Tile;
import android.widget.Switch;
import androidx.annotation.DrawableRes;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
/**
* Superclass to toggle individual sensor privacy via quick settings tiles
*/
public abstract class SensorPrivacyToggleTile extends QSTileImpl<QSTile.BooleanState> implements
IndividualSensorPrivacyController.Callback {
private IndividualSensorPrivacyController mSensorPrivacyController;
/**
* @return Id of the sensor that will be toggled
*/
public abstract @IndividualSensor int getSensorId();
/**
* @return icon for the QS tile
*/
public abstract @DrawableRes int getIconRes();
protected SensorPrivacyToggleTile(QSHost host,
@Background Looper backgroundLooper,
@Main Handler mainHandler,
MetricsLogger metricsLogger,
StatusBarStateController statusBarStateController,
ActivityStarter activityStarter,
QSLogger qsLogger,
IndividualSensorPrivacyController sensorPrivacyController) {
super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
activityStarter, qsLogger);
mSensorPrivacyController = sensorPrivacyController;
mSensorPrivacyController.observe(getLifecycle(), this);
}
@Override
public BooleanState newTileState() {
return new BooleanState();
}
@Override
protected void handleClick() {
mSensorPrivacyController.setSensorBlocked(getSensorId(),
!mSensorPrivacyController.isSensorBlocked(getSensorId()));
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
boolean isBlocked = arg == null ? mSensorPrivacyController.isSensorBlocked(getSensorId())
: (boolean) arg;
state.icon = ResourceIcon.get(getIconRes());
state.state = isBlocked ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.value = isBlocked;
state.label = getTileLabel();
state.handlesLongClick = false;
state.contentDescription = state.label;
state.expandedAccessibilityClassName = Switch.class.getName();
}
@Override
public int getMetricsCategory() {
return 0;
}
@Override
public Intent getLongClickIntent() {
return null;
}
@Override
public void onSensorBlockedChanged(int sensor, boolean blocked) {
if (sensor == getSensorId()) {
refreshState(blocked);
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2020 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.statusbar.policy;
import android.hardware.SensorPrivacyManager.IndividualSensor;
public interface IndividualSensorPrivacyController extends
CallbackController<IndividualSensorPrivacyController.Callback> {
void init();
boolean isSensorBlocked(@IndividualSensor int sensor);
void setSensorBlocked(@IndividualSensor int sensor, boolean blocked);
interface Callback {
void onSensorBlockedChanged(@IndividualSensor int sensor, boolean blocked);
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2020 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.statusbar.policy;
import static android.service.SensorPrivacyIndividualEnabledSensorProto.CAMERA;
import static android.service.SensorPrivacyIndividualEnabledSensorProto.MICROPHONE;
import android.hardware.SensorPrivacyManager;
import android.hardware.SensorPrivacyManager.IndividualSensor;
import android.util.ArraySet;
import android.util.SparseBooleanArray;
import androidx.annotation.NonNull;
import java.util.Set;
public class IndividualSensorPrivacyControllerImpl implements IndividualSensorPrivacyController {
private static final int[] SENSORS = new int[] {CAMERA, MICROPHONE};
private final @NonNull SensorPrivacyManager mSensorPrivacyManager;
private final SparseBooleanArray mState = new SparseBooleanArray();
private final Set<Callback> mCallbacks = new ArraySet<>();
public IndividualSensorPrivacyControllerImpl(
@NonNull SensorPrivacyManager sensorPrivacyManager) {
mSensorPrivacyManager = sensorPrivacyManager;
}
@Override
public void init() {
for (int sensor : SENSORS) {
mSensorPrivacyManager.addSensorPrivacyListener(sensor,
(enabled) -> onSensorPrivacyChanged(sensor, enabled));
mState.put(sensor, mSensorPrivacyManager.isIndividualSensorPrivacyEnabled(sensor));
}
}
@Override
public boolean isSensorBlocked(@IndividualSensor int sensor) {
return mState.get(sensor, false);
}
@Override
public void setSensorBlocked(@IndividualSensor int sensor, boolean blocked) {
mSensorPrivacyManager.setIndividualSensorPrivacyForProfileGroup(sensor, blocked);
}
@Override
public void addCallback(@NonNull Callback listener) {
mCallbacks.add(listener);
}
@Override
public void removeCallback(@NonNull Callback listener) {
mCallbacks.remove(listener);
}
private void onSensorPrivacyChanged(@IndividualSensor int sensor, boolean blocked) {
mState.put(sensor, blocked);
for (Callback callback : mCallbacks) {
callback.onSensorBlockedChanged(sensor, blocked);
}
}
}

View File

@@ -22,6 +22,11 @@ package com.android.systemui.statusbar.policy;
public interface SensorPrivacyController extends
CallbackController<SensorPrivacyController.OnSensorPrivacyChangedListener> {
/**
* Initialize the controller. Needs to be called after constructing the object
*/
void init();
/**
* Returns whether sensor privacy is enabled.
*/

View File

@@ -35,20 +35,21 @@ import javax.inject.Inject;
public class SensorPrivacyControllerImpl implements SensorPrivacyController,
SensorPrivacyManager.OnSensorPrivacyChangedListener {
private SensorPrivacyManager mSensorPrivacyManager;
private final List<OnSensorPrivacyChangedListener> mListeners;
private final List<OnSensorPrivacyChangedListener> mListeners = new ArrayList<>(1);
private Object mLock = new Object();
private boolean mSensorPrivacyEnabled;
/**
* Public constructor.
*/
@Inject
public SensorPrivacyControllerImpl(Context context) {
mSensorPrivacyManager = (SensorPrivacyManager) context.getSystemService(
Context.SENSOR_PRIVACY_SERVICE);
public SensorPrivacyControllerImpl(@NonNull SensorPrivacyManager sensorPrivacyManager) {
mSensorPrivacyManager = sensorPrivacyManager;
}
@Override
public void init() {
mSensorPrivacyEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled();
mSensorPrivacyManager.addSensorPrivacyListener(this);
mListeners = new ArrayList<>(1);
}
/**

View File

@@ -105,11 +105,6 @@ public interface StatusBarPolicyModule {
@Binds
SecurityController provideSecurityController(SecurityControllerImpl controllerImpl);
/** */
@Binds
SensorPrivacyController provideSensorPrivacyControllerImpl(
SensorPrivacyControllerImpl controllerImpl);
/** */
@Binds
UserInfoController provideUserInfoContrller(UserInfoControllerImpl controllerImpl);

View File

@@ -20,6 +20,7 @@ import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME
import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
import android.content.Context;
import android.hardware.SensorPrivacyManager;
import android.os.Handler;
import android.os.PowerManager;
@@ -63,6 +64,10 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyControllerImpl;
import com.android.systemui.statusbar.policy.SensorPrivacyController;
import com.android.systemui.statusbar.policy.SensorPrivacyControllerImpl;
import com.android.systemui.statusbar.tv.notifications.TvNotificationHandler;
import javax.inject.Named;
@@ -109,6 +114,25 @@ public abstract class TvSystemUIModule {
return bC;
}
@Provides
@SysUISingleton
static SensorPrivacyController provideSensorPrivacyController(
SensorPrivacyManager sensorPrivacyManager) {
SensorPrivacyController spC = new SensorPrivacyControllerImpl(sensorPrivacyManager);
spC.init();
return spC;
}
@Provides
@SysUISingleton
static IndividualSensorPrivacyController provideIndividualSensorPrivacyController(
SensorPrivacyManager sensorPrivacyManager) {
IndividualSensorPrivacyController spC = new IndividualSensorPrivacyControllerImpl(
sensorPrivacyManager);
spC.init();
return spC;
}
@Binds
@SysUISingleton
abstract QSFactory bindQSFactory(QSFactoryImpl qsFactoryImpl);

View File

@@ -283,11 +283,16 @@ public final class SensorPrivacyService extends SystemService {
mIndividualEnabled.put(userId, userIndividualEnabled);
if (!enable) {
// Remove any notifications prompting the user to disable sensory privacy
NotificationManager notificationManager =
mContext.getSystemService(NotificationManager.class);
long token = Binder.clearCallingIdentity();
try {
// Remove any notifications prompting the user to disable sensory privacy
NotificationManager notificationManager =
mContext.getSystemService(NotificationManager.class);
notificationManager.cancel(sensor);
notificationManager.cancel(sensor);
} finally {
Binder.restoreCallingIdentity(token);
}
}
persistSensorPrivacyState();
}