blob: 3dcb4cf996c406345f7132a795366ba94bb4af68 [file] [log] [blame]
/*
* 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.
*/
package com.android.server.sensorprivacy;
import android.os.Handler;
import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.internal.util.function.pooled.PooledLambda;
import java.util.Objects;
class SensorPrivacyStateControllerImpl extends SensorPrivacyStateController {
private static final String SENSOR_PRIVACY_XML_FILE = "sensor_privacy_impl.xml";
private static SensorPrivacyStateControllerImpl sInstance;
private PersistedState mPersistedState;
private SensorPrivacyListener mListener;
private Handler mListenerHandler;
static SensorPrivacyStateController getInstance() {
if (sInstance == null) {
sInstance = new SensorPrivacyStateControllerImpl();
}
return sInstance;
}
private SensorPrivacyStateControllerImpl() {
mPersistedState = PersistedState.fromFile(SENSOR_PRIVACY_XML_FILE);
persistAll();
}
@Override
SensorState getStateLocked(int toggleType, int userId, int sensor) {
SensorState sensorState = mPersistedState.getState(toggleType, userId, sensor);
if (sensorState != null) {
return new SensorState(sensorState);
}
return getDefaultSensorState();
}
private static SensorState getDefaultSensorState() {
return new SensorState(false);
}
@Override
void setStateLocked(int toggleType, int userId, int sensor, boolean enabled,
Handler callbackHandler, SetStateResultCallback callback) {
// Changing the SensorState's mEnabled updates the timestamp of its last change.
// A nonexistent state -> unmuted should not set the timestamp.
SensorState lastState = mPersistedState.getState(toggleType, userId, sensor);
if (lastState == null) {
if (!enabled) {
sendSetStateCallback(callbackHandler, callback, false);
return;
} else if (enabled) {
SensorState sensorState = new SensorState(true);
mPersistedState.setState(toggleType, userId, sensor, sensorState);
notifyStateChangeLocked(toggleType, userId, sensor, sensorState);
sendSetStateCallback(callbackHandler, callback, true);
return;
}
}
if (lastState.setEnabled(enabled)) {
notifyStateChangeLocked(toggleType, userId, sensor, lastState);
sendSetStateCallback(callbackHandler, callback, true);
return;
}
sendSetStateCallback(callbackHandler, callback, false);
}
private void notifyStateChangeLocked(int toggleType, int userId, int sensor,
SensorState sensorState) {
if (mListenerHandler != null && mListener != null) {
mListenerHandler.sendMessage(PooledLambda.obtainMessage(
SensorPrivacyListener::onSensorPrivacyChanged, mListener,
toggleType, userId, sensor, new SensorState(sensorState)));
}
schedulePersistLocked();
}
@Override
void setSensorPrivacyListenerLocked(Handler handler, SensorPrivacyListener listener) {
Objects.requireNonNull(handler);
Objects.requireNonNull(listener);
if (mListener != null) {
throw new IllegalStateException("Listener is already set");
}
mListener = listener;
mListenerHandler = handler;
}
@Override
void schedulePersistLocked() {
mPersistedState.schedulePersist();
}
@Override
void forEachStateLocked(SensorPrivacyStateConsumer consumer) {
mPersistedState.forEachKnownState(consumer::accept);
}
@Override
void resetForTestingImpl() {
mPersistedState.resetForTesting();
mListener = null;
mListenerHandler = null;
sInstance = null;
}
@Override
void dumpLocked(DualDumpOutputStream dumpStream) {
mPersistedState.dump(dumpStream);
}
}