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:
committed by
Android (Google) Code Review
commit
c691c16811
@@ -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.
|
||||
|
||||
29
packages/SystemUI/res/drawable/ic_camera_blocked.xml
Normal file
29
packages/SystemUI/res/drawable/ic_camera_blocked.xml
Normal 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>
|
||||
29
packages/SystemUI/res/drawable/ic_mic_blocked.xml
Normal file
29
packages/SystemUI/res/drawable/ic_mic_blocked.xml
Normal 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>
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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] -->
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -105,11 +105,6 @@ public interface StatusBarPolicyModule {
|
||||
@Binds
|
||||
SecurityController provideSecurityController(SecurityControllerImpl controllerImpl);
|
||||
|
||||
/** */
|
||||
@Binds
|
||||
SensorPrivacyController provideSensorPrivacyControllerImpl(
|
||||
SensorPrivacyControllerImpl controllerImpl);
|
||||
|
||||
/** */
|
||||
@Binds
|
||||
UserInfoController provideUserInfoContrller(UserInfoControllerImpl controllerImpl);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user