summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcore/java/android/provider/Settings.java9
-rw-r--r--core/res/res/values/cm_strings.xml21
-rw-r--r--core/res/res/values/lineage_config.xml3
-rw-r--r--core/res/res/values/lineage_symbols.xml5
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java29
-rw-r--r--services/core/java/com/android/server/policy/AlertSliderObserver.java130
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java33
7 files changed, 227 insertions, 3 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c7b2fa3273af..a6f7941a66d9 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4802,6 +4802,15 @@ public final class Settings {
public static final String MULTI_AUDIO_FOCUS_ENABLED = "multi_audio_focus_enabled";
/**
+ * Whether user can swap the order of the Alert Slider.
+ * * Whether user can invert the order of the Alert Slider.
+ * 0: Default
+ * 1: Inverted
+ * @hide
+ */
+ public static final String ALERT_SLIDER_ORDER = "alert_slider_order";
+
+ /**
* IMPORTANT: If you add a new public settings you also have to add it to
* PUBLIC_SETTINGS below. If the new setting is hidden you have to add
* it to PRIVATE_SETTINGS below. Also add a validator that can validate
diff --git a/core/res/res/values/cm_strings.xml b/core/res/res/values/cm_strings.xml
new file mode 100644
index 000000000000..69d283cf42fa
--- /dev/null
+++ b/core/res/res/values/cm_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018-2021 The LineageOS 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.
+-->
+<resources>
+ <!-- Alert slider proc nodes paths. -->
+ <string name="alert_slider_state_path"></string>
+ <string name="alert_slider_uevent_match_path"></string>
+</resources>
diff --git a/core/res/res/values/lineage_config.xml b/core/res/res/values/lineage_config.xml
index 4b090379f5a9..60b256e45db1 100644
--- a/core/res/res/values/lineage_config.xml
+++ b/core/res/res/values/lineage_config.xml
@@ -34,4 +34,7 @@
<!-- The list of components which should be forced to be enabled. -->
<string-array name="config_forceEnabledComponents" translatable="false">
</string-array>
+
+ <!-- Whether device has an alert slider. -->
+ <bool name="config_hasAlertSlider">false</bool>
</resources>
diff --git a/core/res/res/values/lineage_symbols.xml b/core/res/res/values/lineage_symbols.xml
index 155da4479fb8..826062e7b715 100644
--- a/core/res/res/values/lineage_symbols.xml
+++ b/core/res/res/values/lineage_symbols.xml
@@ -25,4 +25,9 @@
<java-symbol type="array" name="config_deviceDisabledComponents" />
<java-symbol type="array" name="config_globallyDisabledComponents" />
<java-symbol type="array" name="config_forceEnabledComponents" />
+
+ <!-- Alert Slider -->
+ <java-symbol type="string" name="alert_slider_state_path" />
+ <java-symbol type="string" name="alert_slider_uevent_match_path" />
+ <java-symbol type="bool" name="config_hasAlertSlider" />
</resources>
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 01b4cc67fa44..607d701a4f4b 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -141,6 +141,7 @@ import android.view.KeyEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
@@ -612,6 +613,9 @@ public class AudioService extends IAudioService.Stub
private @AttributeSystemUsage int[] mSupportedSystemUsages =
new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
+ // Alert Slider
+ private boolean mHasAlertSlider = false;
+
// Defines the format for the connection "address" for ALSA devices
public static String makeAlsaAddressString(int card, int device) {
return "card=" + card + ";device=" + device + ";";
@@ -703,6 +707,10 @@ public class AudioService extends IAudioService.Stub
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
+ mHasAlertSlider = mContext.getResources().getBoolean(R.bool.config_hasAlertSlider)
+ && !TextUtils.isEmpty(mContext.getResources().getString(R.string.alert_slider_state_path))
+ && !TextUtils.isEmpty(mContext.getResources().getString(R.string.alert_slider_uevent_match_path));
+
// Initialize volume
// Priority 1 - Android Property
// Priority 2 - Audio Policy Service
@@ -2067,6 +2075,27 @@ public class AudioService extends IAudioService.Stub
}
}
+ if (mHasAlertSlider) {
+ int volumeType = mStreamVolumeAlias[streamType];
+ VolumeStreamState volumeState = mStreamStates[volumeType];
+ int state = getDeviceForStream(volumeType);
+ int index = volumeState.getIndex(state);
+ int ringerMode = getRingerModeInternal();
+ if ((volumeType == AudioSystem.STREAM_RING)
+ && (direction == AudioManager.ADJUST_LOWER)
+ && (index == 0)) {
+ direction = AudioManager.ADJUST_SAME;
+ }
+ if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
+ && (direction == AudioManager.ADJUST_RAISE
+ && volumeType != AudioSystem.STREAM_MUSIC
+ && volumeType != AudioSystem.STREAM_ALARM
+ && volumeType != AudioSystem.STREAM_VOICE_CALL
+ && !isInCommunication())) {
+ direction = AudioManager.ADJUST_SAME;
+ }
+ }
+
final boolean isMute = isMuteAdjust(direction);
ensureValidStreamType(streamType);
diff --git a/services/core/java/com/android/server/policy/AlertSliderObserver.java b/services/core/java/com/android/server/policy/AlertSliderObserver.java
new file mode 100644
index 000000000000..d64d744403e1
--- /dev/null
+++ b/services/core/java/com/android/server/policy/AlertSliderObserver.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2021 Paranoid Android
+ *
+ * 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.policy;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.UEventObserver;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class AlertSliderObserver extends UEventObserver {
+ private static final String TAG = AlertSliderObserver.class.getSimpleName();
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private int mState;
+
+ private final Context mContext;
+ private final AudioManager mAudioManager;
+ private final WakeLock mWakeLock;
+
+ public AlertSliderObserver(Context context) {
+ mContext = context;
+ mAudioManager = context.getSystemService(AudioManager.class);
+ PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AlertSliderObserver");
+ init();
+ }
+
+ protected void startObserving(int pathId) {
+ String matchPath = mContext.getResources().getString(pathId);
+ if (!TextUtils.isEmpty(matchPath)) {
+ super.startObserving(matchPath);
+ }
+ }
+
+ @Override
+ public void onUEvent(UEventObserver.UEvent event) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Slog.v(TAG, "Switch UEVENT: " + event.toString());
+ }
+
+ try {
+ int state = Integer.parseInt(event.get("SWITCH_STATE"));
+ if (state != mState) {
+ mState = state;
+ update();
+ }
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "Could not parse switch state from event " + event);
+ }
+ }
+
+ private void init() {
+ try {
+ final String path = mContext.getResources().getString(
+ com.android.internal.R.string.alert_slider_state_path);
+ FileReader file = new FileReader(path);
+ BufferedReader br = new BufferedReader(file);
+ String value = br.readLine();
+ file.close();
+ br.close();
+ mState = Integer.valueOf(value);
+ update();
+ } catch (IOException e) {
+ Slog.w(TAG, "This device does not have an Alert Slider");
+ stopObserving();
+ }
+ }
+
+ protected void update() {
+ // Acquire wakelock when slider state changes.
+ mWakeLock.acquire();
+ mHandler.sendEmptyMessageDelayed(mState, 100);
+ }
+
+ private Handler mHandler = new Handler(Looper.myLooper(), null, true) {
+ @Override
+ public void handleMessage(Message msg) {
+ final boolean inverted = isOrderInverted();
+ switch (mState) {
+ case 1:
+ mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_SILENT);
+ break;
+ case 2:
+ mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_VIBRATE);
+ break;
+ case 3:
+ mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL);
+ break;
+ }
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ }
+ };
+
+ // Check if ordered has been set to inverted.
+ private boolean isOrderInverted() {
+ return Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.ALERT_SLIDER_ORDER, 0,
+ UserHandle.USER_CURRENT) != 0;
+ }
+}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3b96ba5d9eba..d36d64e9d216 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -136,6 +136,7 @@ import android.media.AudioManagerInternal;
import android.media.AudioSystem;
import android.media.IAudioService;
import android.media.session.MediaSessionLegacyHelper;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.FactoryTest;
@@ -166,6 +167,7 @@ import android.service.dreams.IDreamManager;
import android.service.vr.IPersistentVrStateCallbacks;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
+import android.text.TextUtils;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.MutableBoolean;
@@ -400,6 +402,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
AppOpsManager mAppOpsManager;
PackageManager mPackageManager;
private boolean mHasFeatureAuto;
+ AlertSliderObserver mAlertSliderObserver;
private boolean mHasFeatureWatch;
private boolean mHasFeatureLeanback;
private boolean mHasFeatureHdmiCec;
@@ -724,6 +727,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private SwipeToScreenshotListener mSwipeToScreenshot;
+ private boolean mHasAlertSlider = false;
+
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
@@ -824,6 +829,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
};
class SettingsObserver extends ContentObserver {
+ private final Uri SWAP_ALERT_SLIDER_ORDER_URI =
+ Settings.System.getUriFor(Settings.System.ALERT_SLIDER_ORDER);
+
SettingsObserver(Handler handler) {
super(handler);
}
@@ -939,13 +947,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.THREE_FINGER_GESTURE), false, this,
UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.ALERT_SLIDER_ORDER), false, this,
+ UserHandle.USER_ALL);
updateSettings();
}
- @Override public void onChange(boolean selfChange) {
- updateSettings();
- updateRotation(false);
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (SWAP_ALERT_SLIDER_ORDER_URI.equals(uri)
+ && mSystemReady && mAlertSliderObserver != null) {
+ mAlertSliderObserver.update();
+ } else {
+ updateSettings();
+ updateRotation(false);
+ }
}
}
@@ -2019,6 +2036,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mWakeOnDpadKeyPress =
res.getBoolean(com.android.internal.R.bool.config_wakeOnDpadKeyPress);
+ // Init alert slider
+ mHasAlertSlider = mContext.getResources().getBoolean(R.bool.config_hasAlertSlider)
+ && !TextUtils.isEmpty(mContext.getResources().getString(R.string.alert_slider_state_path))
+ && !TextUtils.isEmpty(mContext.getResources().getString(R.string.alert_slider_uevent_match_path));
+
// Init display burn-in protection
boolean burnInProtectionEnabled = context.getResources().getBoolean(
com.android.internal.R.bool.config_enableBurnInProtection);
@@ -5584,6 +5606,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
}
+ if (mHasAlertSlider) {
+ mAlertSliderObserver = new AlertSliderObserver(mContext);
+ mAlertSliderObserver.startObserving(com.android.internal.R.string.alert_slider_uevent_match_path);
+ }
+
mLineageHardware = LineageHardwareManager.getInstance(mContext);
// Ensure observe happens in systemReady() since we need
// LineageHardwareService to be up and running