Merge changes from topic "hotword-battery-saver"

* changes:
  add API for ST clients run in battery saver mode
  add SOUND_TRIGGER_RUN_IN_BATTERY_SAVER permission
  add SoundTrigger service modes in battery saver
This commit is contained in:
Nicholas Ambur
2021-01-23 21:51:13 +00:00
committed by Android (Google) Code Review
17 changed files with 363 additions and 137 deletions

View File

@@ -237,6 +237,7 @@ package android {
field public static final String SET_WALLPAPER_COMPONENT = "android.permission.SET_WALLPAPER_COMPONENT";
field public static final String SHOW_KEYGUARD_MESSAGE = "android.permission.SHOW_KEYGUARD_MESSAGE";
field public static final String SHUTDOWN = "android.permission.SHUTDOWN";
field public static final String SOUND_TRIGGER_RUN_IN_BATTERY_SAVER = "android.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER";
field public static final String START_ACTIVITIES_FROM_BACKGROUND = "android.permission.START_ACTIVITIES_FROM_BACKGROUND";
field public static final String START_FOREGROUND_SERVICES_FROM_BACKGROUND = "android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND";
field public static final String STATUS_BAR_SERVICE = "android.permission.STATUS_BAR_SERVICE";
@@ -5060,6 +5061,7 @@ package android.media.soundtrigger {
field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
field public static final int RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION = 4; // 0x4
field public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 8; // 0x8
field public static final int RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER = 16; // 0x10
}
public abstract static class SoundTriggerDetector.Callback {
@@ -7870,7 +7872,7 @@ package android.os {
method public boolean getDisableAod();
method public boolean getDisableLaunchBoost();
method public boolean getDisableOptionalSensors();
method public boolean getDisableSoundTrigger();
method @Deprecated public boolean getDisableSoundTrigger();
method public boolean getDisableVibration();
method public boolean getEnableAdjustBrightness();
method public boolean getEnableDataSaver();
@@ -7880,6 +7882,7 @@ package android.os {
method public boolean getForceAllAppsStandby();
method public boolean getForceBackgroundCheck();
method public int getLocationMode();
method public int getSoundTriggerMode();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.os.BatterySaverPolicyConfig> CREATOR;
}
@@ -7896,7 +7899,7 @@ package android.os {
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setDisableAod(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setDisableLaunchBoost(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setDisableOptionalSensors(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setDisableSoundTrigger(boolean);
method @Deprecated @NonNull public android.os.BatterySaverPolicyConfig.Builder setDisableSoundTrigger(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setDisableVibration(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableAdjustBrightness(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableDataSaver(boolean);
@@ -7906,6 +7909,7 @@ package android.os {
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setForceAllAppsStandby(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setForceBackgroundCheck(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setLocationMode(int);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setSoundTriggerMode(int);
}
public final class BatteryStatsManager {
@@ -8266,6 +8270,9 @@ package android.os {
field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
field public static final String REBOOT_USERSPACE = "userspace";
field public static final int SOUND_TRIGGER_MODE_ALL_DISABLED = 2; // 0x2
field public static final int SOUND_TRIGGER_MODE_ALL_ENABLED = 0; // 0x0
field public static final int SOUND_TRIGGER_MODE_CRITICAL_ONLY = 1; // 0x1
field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1
field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0
@@ -10198,6 +10205,7 @@ package android.service.voice {
field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
field public static final int RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION = 4; // 0x4
field public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 8; // 0x8
field public static final int RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER = 16; // 0x10
field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2
field public static final int RECOGNITION_MODE_VOICE_TRIGGER = 1; // 0x1
field public static final int STATE_ERROR = 3; // 0x3

View File

@@ -42,7 +42,6 @@ public final class BatterySaverPolicyConfig implements Parcelable {
private final boolean mDisableAod;
private final boolean mDisableLaunchBoost;
private final boolean mDisableOptionalSensors;
private final boolean mDisableSoundTrigger;
private final boolean mDisableVibration;
private final boolean mEnableAdjustBrightness;
private final boolean mEnableDataSaver;
@@ -52,6 +51,7 @@ public final class BatterySaverPolicyConfig implements Parcelable {
private final boolean mForceAllAppsStandby;
private final boolean mForceBackgroundCheck;
private final int mLocationMode;
private final int mSoundTriggerMode;
private BatterySaverPolicyConfig(Builder in) {
mAdjustBrightnessFactor = Math.max(0, Math.min(in.mAdjustBrightnessFactor, 1f));
@@ -64,7 +64,6 @@ public final class BatterySaverPolicyConfig implements Parcelable {
mDisableAod = in.mDisableAod;
mDisableLaunchBoost = in.mDisableLaunchBoost;
mDisableOptionalSensors = in.mDisableOptionalSensors;
mDisableSoundTrigger = in.mDisableSoundTrigger;
mDisableVibration = in.mDisableVibration;
mEnableAdjustBrightness = in.mEnableAdjustBrightness;
mEnableDataSaver = in.mEnableDataSaver;
@@ -75,6 +74,8 @@ public final class BatterySaverPolicyConfig implements Parcelable {
mForceBackgroundCheck = in.mForceBackgroundCheck;
mLocationMode = Math.max(PowerManager.MIN_LOCATION_MODE,
Math.min(in.mLocationMode, PowerManager.MAX_LOCATION_MODE));
mSoundTriggerMode = Math.max(PowerManager.MIN_SOUND_TRIGGER_MODE,
Math.min(in.mSoundTriggerMode, PowerManager.MAX_SOUND_TRIGGER_MODE));
}
private BatterySaverPolicyConfig(Parcel in) {
@@ -99,7 +100,6 @@ public final class BatterySaverPolicyConfig implements Parcelable {
mDisableAod = in.readBoolean();
mDisableLaunchBoost = in.readBoolean();
mDisableOptionalSensors = in.readBoolean();
mDisableSoundTrigger = in.readBoolean();
mDisableVibration = in.readBoolean();
mEnableAdjustBrightness = in.readBoolean();
mEnableDataSaver = in.readBoolean();
@@ -110,6 +110,8 @@ public final class BatterySaverPolicyConfig implements Parcelable {
mForceBackgroundCheck = in.readBoolean();
mLocationMode = Math.max(PowerManager.MIN_LOCATION_MODE,
Math.min(in.readInt(), PowerManager.MAX_LOCATION_MODE));
mSoundTriggerMode = Math.max(PowerManager.MIN_SOUND_TRIGGER_MODE,
Math.min(in.readInt(), PowerManager.MAX_SOUND_TRIGGER_MODE));
}
public static final @android.annotation.NonNull Creator<BatterySaverPolicyConfig> CREATOR =
@@ -149,7 +151,6 @@ public final class BatterySaverPolicyConfig implements Parcelable {
dest.writeBoolean(mDisableAod);
dest.writeBoolean(mDisableLaunchBoost);
dest.writeBoolean(mDisableOptionalSensors);
dest.writeBoolean(mDisableSoundTrigger);
dest.writeBoolean(mDisableVibration);
dest.writeBoolean(mEnableAdjustBrightness);
dest.writeBoolean(mEnableDataSaver);
@@ -159,6 +160,7 @@ public final class BatterySaverPolicyConfig implements Parcelable {
dest.writeBoolean(mForceAllAppsStandby);
dest.writeBoolean(mForceBackgroundCheck);
dest.writeInt(mLocationMode);
dest.writeInt(mSoundTriggerMode);
}
@NonNull
@@ -184,7 +186,7 @@ public final class BatterySaverPolicyConfig implements Parcelable {
+ "launch_boost_disabled=" + mDisableLaunchBoost + ","
+ "optional_sensors_disabled=" + mDisableOptionalSensors + ","
+ "quick_doze_enabled=" + mEnableQuickDoze + ","
+ "soundtrigger_disabled=" + mDisableSoundTrigger + ","
+ "soundtrigger_mode=" + mSoundTriggerMode + ","
+ "vibration_disabled=" + mDisableVibration + ","
+ sb.toString();
}
@@ -242,12 +244,21 @@ public final class BatterySaverPolicyConfig implements Parcelable {
return mDisableOptionalSensors;
}
/**
* Get the SoundTrigger mode while in Battery Saver.
*/
public int getSoundTriggerMode() {
return mSoundTriggerMode;
}
/**
* Whether or not to disable {@link android.hardware.soundtrigger.SoundTrigger}
* while in Battery Saver.
* @deprecated Use {@link #getSoundTriggerMode()} instead.
*/
@Deprecated
public boolean getDisableSoundTrigger() {
return mDisableSoundTrigger;
return mSoundTriggerMode == PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED;
}
/** Whether or not to disable vibration while in Battery Saver. */
@@ -315,7 +326,6 @@ public final class BatterySaverPolicyConfig implements Parcelable {
private boolean mDisableAod = false;
private boolean mDisableLaunchBoost = false;
private boolean mDisableOptionalSensors = false;
private boolean mDisableSoundTrigger = false;
private boolean mDisableVibration = false;
private boolean mEnableAdjustBrightness = false;
private boolean mEnableDataSaver = false;
@@ -325,6 +335,7 @@ public final class BatterySaverPolicyConfig implements Parcelable {
private boolean mForceAllAppsStandby = false;
private boolean mForceBackgroundCheck = false;
private int mLocationMode = PowerManager.LOCATION_MODE_NO_CHANGE;
private int mSoundTriggerMode = PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED;
public Builder() {
}
@@ -416,10 +427,26 @@ public final class BatterySaverPolicyConfig implements Parcelable {
/**
* Set whether or not to disable {@link android.hardware.soundtrigger.SoundTrigger}
* while in Battery Saver.
* @deprecated Use {@link #setSoundTriggerMode(int)} instead.
*/
@Deprecated
@NonNull
public Builder setDisableSoundTrigger(boolean disableSoundTrigger) {
mDisableSoundTrigger = disableSoundTrigger;
if (disableSoundTrigger) {
mSoundTriggerMode = PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED;
} else {
mSoundTriggerMode = PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED;
}
return this;
}
/**
* Set the SoundTrigger mode while in Battery Saver.
*/
@NonNull
public Builder setSoundTriggerMode(
@PowerManager.SoundTriggerPowerSaveMode int soundTriggerMode) {
mSoundTriggerMode = soundTriggerMode;
return this;
}

View File

@@ -885,6 +885,45 @@ public final class PowerManager {
})
public @interface LocationPowerSaveMode {}
/**
* In this mode, all active SoundTrigger recognitions are enabled by the SoundTrigger system
* service.
* @hide
*/
@SystemApi
public static final int SOUND_TRIGGER_MODE_ALL_ENABLED = 0;
/**
* In this mode, only privileged components of the SoundTrigger system service should be
* enabled. This functionality is to be used to limit SoundTrigger recognitions to those only
* deemed necessary by the system.
* @hide
*/
@SystemApi
public static final int SOUND_TRIGGER_MODE_CRITICAL_ONLY = 1;
/**
* In this mode, all active SoundTrigger recognitions should be disabled by the SoundTrigger
* system service.
* @hide
*/
@SystemApi
public static final int SOUND_TRIGGER_MODE_ALL_DISABLED = 2;
/** @hide */
public static final int MIN_SOUND_TRIGGER_MODE = SOUND_TRIGGER_MODE_ALL_ENABLED;
/** @hide */
public static final int MAX_SOUND_TRIGGER_MODE = SOUND_TRIGGER_MODE_ALL_DISABLED;
/**
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"SOUND_TRIGGER_MODE_"}, value = {
SOUND_TRIGGER_MODE_ALL_ENABLED,
SOUND_TRIGGER_MODE_CRITICAL_ONLY,
SOUND_TRIGGER_MODE_ALL_DISABLED,
})
public @interface SoundTriggerPowerSaveMode {}
/** @hide */
public static String locationPowerSaveModeToString(@LocationPowerSaveMode int mode) {
switch (mode) {
@@ -1832,6 +1871,26 @@ public final class PowerManager {
return powerSaveState.locationMode;
}
/**
* Returns how SoundTrigger features should behave when battery saver is on. When battery saver
* is off, this will always return {@link #SOUND_TRIGGER_MODE_ALL_ENABLED}.
*
* <p>This API is normally only useful for components that provide use SoundTrigger features.
*
* @see #isPowerSaveMode()
* @see #ACTION_POWER_SAVE_MODE_CHANGED
*
* @hide
*/
@SoundTriggerPowerSaveMode
public int getSoundTriggerPowerSaveMode() {
final PowerSaveState powerSaveState = getPowerSaveState(ServiceType.SOUND);
if (!powerSaveState.batterySaverEnabled) {
return SOUND_TRIGGER_MODE_ALL_ENABLED;
}
return powerSaveState.soundTriggerMode;
}
/**
* Returns true if the device is currently in idle mode. This happens when a device
* has been sitting unused and unmoving for a sufficiently long period of time, so that

View File

@@ -36,11 +36,13 @@ public class PowerSaveState implements Parcelable {
*/
public final boolean globalBatterySaverEnabled;
public final int locationMode;
public final int soundTriggerMode;
public final float brightnessFactor;
public PowerSaveState(Builder builder) {
batterySaverEnabled = builder.mBatterySaverEnabled;
locationMode = builder.mLocationMode;
soundTriggerMode = builder.mSoundTriggerMode;
brightnessFactor = builder.mBrightnessFactor;
globalBatterySaverEnabled = builder.mGlobalBatterySaverEnabled;
}
@@ -49,6 +51,7 @@ public class PowerSaveState implements Parcelable {
batterySaverEnabled = in.readByte() != 0;
globalBatterySaverEnabled = in.readByte() != 0;
locationMode = in.readInt();
soundTriggerMode = in.readInt();
brightnessFactor = in.readFloat();
}
@@ -62,6 +65,7 @@ public class PowerSaveState implements Parcelable {
dest.writeByte((byte) (batterySaverEnabled ? 1 : 0));
dest.writeByte((byte) (globalBatterySaverEnabled ? 1 : 0));
dest.writeInt(locationMode);
dest.writeInt(soundTriggerMode);
dest.writeFloat(brightnessFactor);
}
@@ -69,6 +73,7 @@ public class PowerSaveState implements Parcelable {
private boolean mBatterySaverEnabled = false;
private boolean mGlobalBatterySaverEnabled = false;
private int mLocationMode = 0;
private int mSoundTriggerMode = PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED;
private float mBrightnessFactor = 0.5f;
public Builder() {}
@@ -83,6 +88,11 @@ public class PowerSaveState implements Parcelable {
return this;
}
public Builder setSoundTriggerMode(int mode) {
mSoundTriggerMode = mode;
return this;
}
public Builder setLocationMode(int mode) {
mLocationMode = mode;
return this;

View File

@@ -125,6 +125,7 @@ public class AlwaysOnHotwordDetector {
RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS,
RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION,
RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION,
RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER,
})
public @interface RecognitionFlags {}
@@ -171,6 +172,14 @@ public class AlwaysOnHotwordDetector {
*/
public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 0x8;
/**
* Recognition flag for {@link #startRecognition(int)} that indicates whether the recognition
* should continue after battery saver mode is enabled.
* When this flag is specified, the caller will be checked for
* {@link android.Manifest.permission#SOUND_TRIGGER_RUN_IN_BATTERY_SAVER} permission granted.
*/
public static final int RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER = 0x10;
//---- Recognition mode flags. Return codes for getSupportedRecognitionModes() ----//
// Must be kept in sync with the related attribute defined as searchKeyphraseRecognitionFlags.
@@ -860,6 +869,7 @@ public class AlwaysOnHotwordDetector {
(recognitionFlags&RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO) != 0;
boolean allowMultipleTriggers =
(recognitionFlags&RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS) != 0;
boolean runInBatterySaver = (recognitionFlags&RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER) != 0;
int audioCapabilities = 0;
if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION) != 0) {
@@ -874,7 +884,8 @@ public class AlwaysOnHotwordDetector {
code = mSoundTriggerSession.startRecognition(
mKeyphraseMetadata.getId(), mLocale.toLanguageTag(), mInternalCallback,
new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
recognitionExtra, null /* additional data */, audioCapabilities));
recognitionExtra, null /* additional data */, audioCapabilities),
runInBatterySaver);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -37,7 +37,7 @@ interface ISoundTriggerSession {
void deleteSoundModel(in ParcelUuid soundModelId);
int startRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback,
in SoundTrigger.RecognitionConfig config);
in SoundTrigger.RecognitionConfig config, boolean runInBatterySaver);
int stopRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);

View File

@@ -41,7 +41,8 @@ interface IVoiceInteractionSoundTriggerSession {
*/
int startRecognition(int keyphraseId, in String bcp47Locale,
in IRecognitionStatusCallback callback,
in SoundTrigger.RecognitionConfig recognitionConfig);
in SoundTrigger.RecognitionConfig recognitionConfig,
boolean runInBatterySaver);
/**
* Stops a recognition for the given keyphrase.
* Caller must be the active voice interaction service via

View File

@@ -5034,6 +5034,13 @@
<permission android:name="android.permission.MANAGE_SOUND_TRIGGER"
android:protectionLevel="signature|privileged" />
<!-- Must be required by system/priv apps to run sound trigger recognition sessions while in
battery saver mode.
@hide
@SystemApi -->
<permission android:name="android.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER"
android:protectionLevel="signature|privileged" />
<!-- Must be required by system/priv apps implementing sound trigger detection services
@hide
@SystemApi -->

View File

@@ -61,7 +61,6 @@ static struct BatterySaverPolicyConfigFieldId {
jfieldID disableAod;
jfieldID disableLaunchBoost;
jfieldID disableOptionalSensors;
jfieldID disableSoundTrigger;
jfieldID disableVibration;
jfieldID enableAdjustBrightness;
jfieldID enableDataSaver;
@@ -71,6 +70,7 @@ static struct BatterySaverPolicyConfigFieldId {
jfieldID forceAllAppsStandby;
jfieldID forceBackgroundCheck;
jfieldID locationMode;
jfieldID soundTriggerMode;
} gBSPCFieldIds;
static jobject nativeObtainParcel(JNIEnv* env) {
@@ -171,10 +171,11 @@ static void nativeUnparcelAndVerifyWorkSource(JNIEnv* env, jobject /* obj */, jo
static jobject nativeObtainPowerSaveStateParcel(JNIEnv* env, jobject /* obj */,
jboolean batterySaverEnabled, jboolean globalBatterySaverEnabled,
jint locationMode, jfloat brightnessFactor) {
jint locationMode, jint soundTriggerMode, jfloat brightnessFactor) {
PowerSaveState ps = PowerSaveState(static_cast<bool>(batterySaverEnabled),
static_cast<bool>(globalBatterySaverEnabled),
static_cast<LocationMode>(locationMode),
static_cast<SoundTriggerMode>(soundTriggerMode),
static_cast<float>(brightnessFactor));
jobject psParcel = nativeObtainParcel(env);
Parcel* parcel = nativeGetParcelData(env, psParcel);
@@ -189,7 +190,7 @@ static jobject nativeObtainPowerSaveStateParcel(JNIEnv* env, jobject /* obj */,
static void nativeUnparcelAndVerifyPowerSaveState(JNIEnv* env, jobject /* obj */, jobject psParcel,
jboolean batterySaverEnabled, jboolean globalBatterySaverEnabled,
jint locationMode, jfloat brightnessFactor) {
jint locationMode, jint soundTriggerMode, jfloat brightnessFactor) {
PowerSaveState ps = {};
Parcel* parcel = nativeGetParcelData(env, psParcel);
status_t err = ps.readFromParcel(parcel);
@@ -200,6 +201,7 @@ static void nativeUnparcelAndVerifyPowerSaveState(JNIEnv* env, jobject /* obj */
PowerSaveState psOrig = PowerSaveState(static_cast<bool>(batterySaverEnabled),
static_cast<bool>(globalBatterySaverEnabled),
static_cast<LocationMode>(locationMode),
static_cast<SoundTriggerMode>(soundTriggerMode),
static_cast<float>(brightnessFactor));
if (ps == psOrig) {
return;
@@ -229,7 +231,6 @@ static jobject nativeObtainBSPConfigParcel(JNIEnv* env, jobject /* obj */,
env->GetBooleanField(bsObj, gBSPCFieldIds.disableAod),
env->GetBooleanField(bsObj, gBSPCFieldIds.disableLaunchBoost),
env->GetBooleanField(bsObj, gBSPCFieldIds.disableOptionalSensors),
env->GetBooleanField(bsObj, gBSPCFieldIds.disableSoundTrigger),
env->GetBooleanField(bsObj, gBSPCFieldIds.disableVibration),
env->GetBooleanField(bsObj, gBSPCFieldIds.enableAdjustBrightness),
env->GetBooleanField(bsObj, gBSPCFieldIds.enableDataSaver),
@@ -238,7 +239,8 @@ static jobject nativeObtainBSPConfigParcel(JNIEnv* env, jobject /* obj */,
env->GetBooleanField(bsObj, gBSPCFieldIds.enableQuickDoze),
env->GetBooleanField(bsObj, gBSPCFieldIds.forceAllAppsStandby),
env->GetBooleanField(bsObj, gBSPCFieldIds.forceBackgroundCheck),
static_cast<LocationMode>(env->GetIntField(bsObj, gBSPCFieldIds.locationMode)));
static_cast<LocationMode>(env->GetIntField(bsObj, gBSPCFieldIds.locationMode)),
static_cast<SoundTriggerMode>(env->GetIntField(bsObj, gBSPCFieldIds.soundTriggerMode)));
jobject bsParcel = nativeObtainParcel(env);
Parcel* parcel = nativeGetParcelData(env, bsParcel);
@@ -279,7 +281,6 @@ static void nativeUnparcelAndVerifyBSPConfig(JNIEnv* env, jobject /* obj */,
env->GetBooleanField(bsObj, gBSPCFieldIds.disableAod),
env->GetBooleanField(bsObj, gBSPCFieldIds.disableLaunchBoost),
env->GetBooleanField(bsObj, gBSPCFieldIds.disableOptionalSensors),
env->GetBooleanField(bsObj, gBSPCFieldIds.disableSoundTrigger),
env->GetBooleanField(bsObj, gBSPCFieldIds.disableVibration),
env->GetBooleanField(bsObj, gBSPCFieldIds.enableAdjustBrightness),
env->GetBooleanField(bsObj, gBSPCFieldIds.enableDataSaver),
@@ -288,7 +289,8 @@ static void nativeUnparcelAndVerifyBSPConfig(JNIEnv* env, jobject /* obj */,
env->GetBooleanField(bsObj, gBSPCFieldIds.enableQuickDoze),
env->GetBooleanField(bsObj, gBSPCFieldIds.forceAllAppsStandby),
env->GetBooleanField(bsObj, gBSPCFieldIds.forceBackgroundCheck),
static_cast<LocationMode>(env->GetIntField(bsObj, gBSPCFieldIds.locationMode)));
static_cast<LocationMode>(env->GetIntField(bsObj, gBSPCFieldIds.locationMode)),
static_cast<SoundTriggerMode>(env->GetIntField(bsObj, gBSPCFieldIds.soundTriggerMode)));
if (bs == bsOrig) {
return;
@@ -307,9 +309,9 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
(void*) nativeObtainWorkSourceParcel },
{ "nativeUnparcelAndVerifyWorkSource", "(Landroid/os/Parcel;[I[Ljava/lang/String;)V",
(void*) nativeUnparcelAndVerifyWorkSource },
{ "nativeObtainPowerSaveStateParcel", "(ZZIF)Landroid/os/Parcel;",
{ "nativeObtainPowerSaveStateParcel", "(ZZIIF)Landroid/os/Parcel;",
(void*) nativeObtainPowerSaveStateParcel },
{ "nativeUnparcelAndVerifyPowerSaveState", "(Landroid/os/Parcel;ZZIF)V",
{ "nativeUnparcelAndVerifyPowerSaveState", "(Landroid/os/Parcel;ZZIIF)V",
(void*) nativeUnparcelAndVerifyPowerSaveState },
{ "nativeObtainBSPConfigParcel",
"(Landroid/os/BatterySaverPolicyConfig;"
@@ -340,7 +342,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
GET_FIELD_ID(gBSPCFieldIds.disableAod, bspcClazz, "mDisableAod", "Z");
GET_FIELD_ID(gBSPCFieldIds.disableLaunchBoost, bspcClazz, "mDisableLaunchBoost", "Z");
GET_FIELD_ID(gBSPCFieldIds.disableOptionalSensors, bspcClazz, "mDisableOptionalSensors", "Z");
GET_FIELD_ID(gBSPCFieldIds.disableSoundTrigger, bspcClazz, "mDisableSoundTrigger", "Z");
GET_FIELD_ID(gBSPCFieldIds.disableVibration, bspcClazz, "mDisableVibration", "Z");
GET_FIELD_ID(gBSPCFieldIds.enableAdjustBrightness, bspcClazz, "mEnableAdjustBrightness", "Z");
GET_FIELD_ID(gBSPCFieldIds.enableDataSaver, bspcClazz, "mEnableDataSaver", "Z");
@@ -350,6 +351,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
GET_FIELD_ID(gBSPCFieldIds.forceAllAppsStandby, bspcClazz, "mForceAllAppsStandby", "Z");
GET_FIELD_ID(gBSPCFieldIds.forceBackgroundCheck, bspcClazz, "mForceBackgroundCheck", "Z");
GET_FIELD_ID(gBSPCFieldIds.locationMode, bspcClazz, "mLocationMode", "I");
GET_FIELD_ID(gBSPCFieldIds.soundTriggerMode, bspcClazz, "mSoundTriggerMode", "I");
jniRegisterNativeMethods(env, "android/os/PowerManagerTest", methodTable,
sizeof(methodTable) / sizeof(JNINativeMethod));

View File

@@ -53,10 +53,11 @@ public class PowerManagerTest extends AndroidTestCase {
private native void nativeUnparcelAndVerifyWorkSource(Parcel parcel, int[] uids,
String[] names);
private native Parcel nativeObtainPowerSaveStateParcel(boolean batterySaverEnabled,
boolean globalBatterySaverEnabled, int locationMode, float brightnessFactor);
boolean globalBatterySaverEnabled, int locationMode, int soundTriggerMode,
float brightnessFactor);
private native void nativeUnparcelAndVerifyPowerSaveState(Parcel parcel,
boolean batterySaverEnabled, boolean globalBatterySaverEnabled,
int locationMode, float brightnessFactor);
int locationMode, int soundTriggerMode, float brightnessFactor);
private native Parcel nativeObtainBSPConfigParcel(BatterySaverPolicyConfig bs,
String[] keys, String[] values);
private native void nativeUnparcelAndVerifyBSPConfig(Parcel parcel, BatterySaverPolicyConfig bs,
@@ -351,15 +352,17 @@ public class PowerManagerTest extends AndroidTestCase {
* specified parameters, and verify the PowerSaveState object created from the parcel.
*/
private void unparcelPowerSaveStateFromNativeAndVerify(boolean batterySaverEnabled,
boolean globalBatterySaverEnabled, int locationMode, float brightnessFactor) {
boolean globalBatterySaverEnabled, int locationMode, int soundTriggerMode,
float brightnessFactor) {
// Obtain PowerSaveState as parcel from native, with parameters.
Parcel psParcel = nativeObtainPowerSaveStateParcel(batterySaverEnabled,
globalBatterySaverEnabled, locationMode, brightnessFactor);
globalBatterySaverEnabled, locationMode, soundTriggerMode, brightnessFactor);
// Verify the parcel.
PowerSaveState ps = PowerSaveState.CREATOR.createFromParcel(psParcel);
assertEquals(ps.batterySaverEnabled, batterySaverEnabled);
assertEquals(ps.globalBatterySaverEnabled, globalBatterySaverEnabled);
assertEquals(ps.locationMode, locationMode);
assertEquals(ps.soundTriggerMode, soundTriggerMode);
assertEquals(ps.brightnessFactor, brightnessFactor, 0.01f);
}
@@ -368,7 +371,8 @@ public class PowerManagerTest extends AndroidTestCase {
* specified parameters. Native will verify the PowerSaveState in native is expected.
*/
private void parcelPowerSaveStateToNativeAndVerify(boolean batterySaverEnabled,
boolean globalBatterySaverEnabled, int locationMode, float brightnessFactor) {
boolean globalBatterySaverEnabled, int locationMode, int soundTriggerMode,
float brightnessFactor) {
Parcel psParcel = Parcel.obtain();
// PowerSaveState API blocks Builder.build(), generate a parcel instead of object.
PowerSaveState ps = new PowerSaveState.Builder()
@@ -380,7 +384,7 @@ public class PowerManagerTest extends AndroidTestCase {
psParcel.setDataPosition(0);
//Set the PowerSaveState as parcel to native and verify in native space.
nativeUnparcelAndVerifyPowerSaveState(psParcel, batterySaverEnabled,
globalBatterySaverEnabled, locationMode, brightnessFactor);
globalBatterySaverEnabled, locationMode, soundTriggerMode, brightnessFactor);
}
/**
@@ -463,10 +467,13 @@ public class PowerManagerTest extends AndroidTestCase {
public void testPowerSaveStateNativeToJava() {
unparcelPowerSaveStateFromNativeAndVerify(false /* batterySaverEnabled */,
false /* globalBatterySaverEnabled */,
PowerManager.LOCATION_MODE_FOREGROUND_ONLY, 0.3f /* brightnessFactor */);
PowerManager.LOCATION_MODE_FOREGROUND_ONLY,
PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY,
0.3f /* brightnessFactor */);
unparcelPowerSaveStateFromNativeAndVerify(true /* batterySaverEnabled */,
true /* globalBatterySaverEnabled */,
PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF,
PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED,
0.5f /* brightnessFactor */);
}
@@ -479,10 +486,13 @@ public class PowerManagerTest extends AndroidTestCase {
public void testSetPowerSaveStateJavaToNative() {
parcelPowerSaveStateToNativeAndVerify(false /* batterySaverEnabled */,
false /* globalBatterySaverEnabled */,
PowerManager.LOCATION_MODE_FOREGROUND_ONLY, 0.3f /* brightnessFactor */);
PowerManager.LOCATION_MODE_FOREGROUND_ONLY,
PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY,
0.3f /* brightnessFactor */);
parcelPowerSaveStateToNativeAndVerify(true /* batterySaverEnabled */,
true /* globalBatterySaverEnabled */,
PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF,
PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED,
0.5f /* brightnessFactor */);
}

View File

@@ -79,7 +79,8 @@ public final class SoundTriggerDetector {
RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO,
RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS,
RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION,
RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION,
RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION,
RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER,
})
public @interface RecognitionFlags {}
@@ -132,6 +133,14 @@ public final class SoundTriggerDetector {
*/
public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 0x8;
/**
* Recognition flag for {@link #startRecognition(int)} that indicates whether the recognition
* should continue after battery saver mode is enabled.
* When this flag is specified, the caller will be checked for
* {@link android.Manifest.permission#SOUND_TRIGGER_RUN_IN_BATTERY_SAVER} permission granted.
*/
public static final int RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER = 0x10;
/**
* Additional payload for {@link Callback#onDetected}.
*/
@@ -296,6 +305,8 @@ public final class SoundTriggerDetector {
boolean allowMultipleTriggers =
(recognitionFlags & RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS) != 0;
boolean runInBatterySaver = (recognitionFlags & RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER) != 0;
int audioCapabilities = 0;
if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION) != 0) {
audioCapabilities |= SoundTrigger.ModuleProperties.AUDIO_CAPABILITY_ECHO_CANCELLATION;
@@ -308,7 +319,8 @@ public final class SoundTriggerDetector {
try {
status = mSoundTriggerSession.startRecognition(new ParcelUuid(mSoundModelId),
mRecognitionCallback, new RecognitionConfig(captureTriggerAudio,
allowMultipleTriggers, null, null, audioCapabilities));
allowMultipleTriggers, null, null, audioCapabilities),
runInBatterySaver);
} catch (RemoteException e) {
return false;
}

View File

@@ -72,7 +72,7 @@ public class BatterySaverPolicy extends ContentObserver implements
@VisibleForTesting
static final String KEY_DISABLE_ANIMATION = "disable_animation";
@VisibleForTesting
static final String KEY_DISABLE_SOUNDTRIGGER = "disable_soundtrigger";
static final String KEY_SOUNDTRIGGER_MODE = "soundtrigger_mode";
/**
* Turn on the network firewall when Battery Saver is turned on.
@@ -144,7 +144,6 @@ public class BatterySaverPolicy extends ContentObserver implements
false, /* disableAod */
false, /* disableLaunchBoost */
false, /* disableOptionalSensors */
false, /* disableSoundTrigger */
false, /* disableVibration */
false, /* enableAdjustBrightness */
false, /* enableDataSaver */
@@ -155,7 +154,8 @@ public class BatterySaverPolicy extends ContentObserver implements
new ArrayMap<>(), /* filesForNoninteractive */
false, /* forceAllAppsStandby */
false, /* forceBackgroundCheck */
PowerManager.LOCATION_MODE_NO_CHANGE /* locationMode */
PowerManager.LOCATION_MODE_NO_CHANGE, /* locationMode */
PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED /* soundTriggerMode */
);
private static final Policy DEFAULT_ADAPTIVE_POLICY = OFF_POLICY;
@@ -169,7 +169,6 @@ public class BatterySaverPolicy extends ContentObserver implements
true, /* disableAod */
true, /* disableLaunchBoost */
true, /* disableOptionalSensors */
true, /* disableSoundTrigger */
true, /* disableVibration */
false, /* enableAdjustBrightness */
false, /* enableDataSaver */
@@ -180,7 +179,8 @@ public class BatterySaverPolicy extends ContentObserver implements
new ArrayMap<>(), /* filesForNoninteractive */
true, /* forceAllAppsStandby */
true, /* forceBackgroundCheck */
PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF /* locationMode */
PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF, /* locationMode */
PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY /* soundTriggerMode */
);
private final Object mLock;
@@ -494,7 +494,6 @@ public class BatterySaverPolicy extends ContentObserver implements
rawPolicy.disableAod,
rawPolicy.disableLaunchBoost,
rawPolicy.disableOptionalSensors,
rawPolicy.disableSoundTrigger,
// Don't disable vibration when accessibility is on.
rawPolicy.disableVibration && !mAccessibilityEnabled.get(),
rawPolicy.enableAdjustBrightness,
@@ -507,7 +506,8 @@ public class BatterySaverPolicy extends ContentObserver implements
rawPolicy.filesForNoninteractive,
rawPolicy.forceAllAppsStandby,
rawPolicy.forceBackgroundCheck,
locationMode
locationMode,
rawPolicy.soundTriggerMode
);
@@ -518,7 +518,9 @@ public class BatterySaverPolicy extends ContentObserver implements
if (mEffectivePolicyRaw.disableVibration) sb.append("v");
if (mEffectivePolicyRaw.disableAnimation) sb.append("a");
if (mEffectivePolicyRaw.disableSoundTrigger) sb.append("s");
sb.append(mEffectivePolicyRaw.soundTriggerMode);
if (mEffectivePolicyRaw.deferFullBackup) sb.append("F");
if (mEffectivePolicyRaw.deferKeyValueBackup) sb.append("K");
if (mEffectivePolicyRaw.enableFirewall) sb.append("f");
@@ -599,9 +601,9 @@ public class BatterySaverPolicy extends ContentObserver implements
* in battery saver mode.
*
* @see Settings.Global#BATTERY_SAVER_CONSTANTS
* @see #KEY_DISABLE_SOUNDTRIGGER
* @see #KEY_SOUNDTRIGGER_MODE
*/
public final boolean disableSoundTrigger;
public final int soundTriggerMode;
/**
* {@code true} if vibration is disabled in battery saver mode.
@@ -692,7 +694,6 @@ public class BatterySaverPolicy extends ContentObserver implements
boolean disableAod,
boolean disableLaunchBoost,
boolean disableOptionalSensors,
boolean disableSoundTrigger,
boolean disableVibration,
boolean enableAdjustBrightness,
boolean enableDataSaver,
@@ -703,7 +704,8 @@ public class BatterySaverPolicy extends ContentObserver implements
ArrayMap<String, String> filesForNoninteractive,
boolean forceAllAppsStandby,
boolean forceBackgroundCheck,
int locationMode) {
int locationMode,
int soundTriggerMode) {
this.adjustBrightnessFactor = Math.min(1, Math.max(0, adjustBrightnessFactor));
this.advertiseIsEnabled = advertiseIsEnabled;
@@ -713,7 +715,6 @@ public class BatterySaverPolicy extends ContentObserver implements
this.disableAod = disableAod;
this.disableLaunchBoost = disableLaunchBoost;
this.disableOptionalSensors = disableOptionalSensors;
this.disableSoundTrigger = disableSoundTrigger;
this.disableVibration = disableVibration;
this.enableAdjustBrightness = enableAdjustBrightness;
this.enableDataSaver = enableDataSaver;
@@ -733,6 +734,14 @@ public class BatterySaverPolicy extends ContentObserver implements
this.locationMode = locationMode;
}
if (soundTriggerMode < PowerManager.MIN_SOUND_TRIGGER_MODE
|| soundTriggerMode > PowerManager.MAX_SOUND_TRIGGER_MODE) {
Slog.e(TAG, "Invalid SoundTrigger mode: " + soundTriggerMode);
this.soundTriggerMode = PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED;
} else {
this.soundTriggerMode = soundTriggerMode;
}
mHashCode = Objects.hash(
adjustBrightnessFactor,
advertiseIsEnabled,
@@ -742,7 +751,6 @@ public class BatterySaverPolicy extends ContentObserver implements
disableAod,
disableLaunchBoost,
disableOptionalSensors,
disableSoundTrigger,
disableVibration,
enableAdjustBrightness,
enableDataSaver,
@@ -753,7 +761,8 @@ public class BatterySaverPolicy extends ContentObserver implements
filesForNoninteractive,
forceAllAppsStandby,
forceBackgroundCheck,
locationMode);
locationMode,
soundTriggerMode);
}
static Policy fromConfig(BatterySaverPolicyConfig config) {
@@ -778,7 +787,6 @@ public class BatterySaverPolicy extends ContentObserver implements
config.getDisableAod(),
config.getDisableLaunchBoost(),
config.getDisableOptionalSensors(),
config.getDisableSoundTrigger(),
config.getDisableVibration(),
config.getEnableAdjustBrightness(),
config.getEnableDataSaver(),
@@ -791,7 +799,8 @@ public class BatterySaverPolicy extends ContentObserver implements
(new CpuFrequencies()).parseString(cpuFreqNoninteractive).toSysFileMap(),
config.getForceAllAppsStandby(),
config.getForceBackgroundCheck(),
config.getLocationMode()
config.getLocationMode(),
config.getSoundTriggerMode()
);
}
@@ -851,9 +860,6 @@ public class BatterySaverPolicy extends ContentObserver implements
final boolean disableOptionalSensors = parser.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS,
properties.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS + configSuffix,
defaultPolicy.disableOptionalSensors));
final boolean disableSoundTrigger = parser.getBoolean(KEY_DISABLE_SOUNDTRIGGER,
properties.getBoolean(KEY_DISABLE_SOUNDTRIGGER + configSuffix,
defaultPolicy.disableSoundTrigger));
final boolean disableVibrationConfig = parser.getBoolean(KEY_DISABLE_VIBRATION,
properties.getBoolean(KEY_DISABLE_VIBRATION + configSuffix,
defaultPolicy.disableVibration));
@@ -882,7 +888,9 @@ public class BatterySaverPolicy extends ContentObserver implements
final int locationMode = parser.getInt(KEY_LOCATION_MODE,
properties.getInt(KEY_LOCATION_MODE + configSuffix,
defaultPolicy.locationMode));
final int soundTriggerMode = parser.getInt(KEY_SOUNDTRIGGER_MODE,
properties.getInt(KEY_SOUNDTRIGGER_MODE + configSuffix,
defaultPolicy.soundTriggerMode));
return new Policy(
adjustBrightnessFactor,
advertiseIsEnabled,
@@ -892,7 +900,6 @@ public class BatterySaverPolicy extends ContentObserver implements
disableAod,
disableLaunchBoost,
disableOptionalSensors,
disableSoundTrigger,
/* disableVibration */
disableVibrationConfig,
enableBrightnessAdjustment,
@@ -906,7 +913,8 @@ public class BatterySaverPolicy extends ContentObserver implements
(new CpuFrequencies()).parseString(cpuFreqNoninteractive).toSysFileMap(),
forceAllAppsStandby,
forceBackgroundCheck,
locationMode
locationMode,
soundTriggerMode
);
}
@@ -923,7 +931,6 @@ public class BatterySaverPolicy extends ContentObserver implements
&& disableAod == other.disableAod
&& disableLaunchBoost == other.disableLaunchBoost
&& disableOptionalSensors == other.disableOptionalSensors
&& disableSoundTrigger == other.disableSoundTrigger
&& disableVibration == other.disableVibration
&& enableAdjustBrightness == other.enableAdjustBrightness
&& enableDataSaver == other.enableDataSaver
@@ -933,6 +940,7 @@ public class BatterySaverPolicy extends ContentObserver implements
&& forceAllAppsStandby == other.forceAllAppsStandby
&& forceBackgroundCheck == other.forceBackgroundCheck
&& locationMode == other.locationMode
&& soundTriggerMode == other.soundTriggerMode
&& filesForInteractive.equals(other.filesForInteractive)
&& filesForNoninteractive.equals(other.filesForNoninteractive);
}
@@ -983,7 +991,11 @@ public class BatterySaverPolicy extends ContentObserver implements
return builder.setBatterySaverEnabled(currPolicy.enableDataSaver)
.build();
case ServiceType.SOUND:
return builder.setBatterySaverEnabled(currPolicy.disableSoundTrigger)
boolean soundTriggerBatterySaverEnabled = currPolicy.advertiseIsEnabled
|| currPolicy.soundTriggerMode
!= PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED;
return builder.setBatterySaverEnabled(soundTriggerBatterySaverEnabled)
.setSoundTriggerMode(currPolicy.soundTriggerMode)
.build();
case ServiceType.VIBRATION:
return builder.setBatterySaverEnabled(currPolicy.disableVibration)
@@ -1172,7 +1184,7 @@ public class BatterySaverPolicy extends ContentObserver implements
pw.println(KEY_FORCE_BACKGROUND_CHECK + "=" + p.forceBackgroundCheck);
pw.println(KEY_DISABLE_OPTIONAL_SENSORS + "=" + p.disableOptionalSensors);
pw.println(KEY_DISABLE_AOD + "=" + p.disableAod);
pw.println(KEY_DISABLE_SOUNDTRIGGER + "=" + p.disableSoundTrigger);
pw.println(KEY_SOUNDTRIGGER_MODE + "=" + p.soundTriggerMode);
pw.println(KEY_ENABLE_QUICK_DOZE + "=" + p.enableQuickDoze);
pw.println(KEY_ENABLE_NIGHT_MODE + "=" + p.enableNightMode);

View File

@@ -48,10 +48,12 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
private static final int GPS_MODE = 0; // LOCATION_MODE_NO_CHANGE
private static final int DEFAULT_GPS_MODE =
PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF;
private static final int SOUND_TRIGGER_MODE = 0; // SOUND_TRIGGER_MODE_ALL_ENABLED
private static final int DEFAULT_SOUND_TRIGGER_MODE =
PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY;
private static final String BATTERY_SAVER_CONSTANTS = "disable_vibration=true,"
+ "advertise_is_enabled=true,"
+ "disable_animation=false,"
+ "disable_soundtrigger=true,"
+ "enable_firewall=true,"
+ "enable_datasaver=true,"
+ "enable_brightness_adjustment=false,"
@@ -59,6 +61,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
+ "defer_full_backup=true,"
+ "defer_keyvalue_backup=false,"
+ "location_mode=0," // LOCATION_MODE_NO_CHANGE
+ "soundtrigger_mode=0," // SOUND_TRIGGER_MODE_ALL_ENABLE
+ "enable_night_mode=false,"
+ "enable_quick_doze=true";
private static final String BATTERY_SAVER_INCORRECT_CONSTANTS = "vi*,!=,,true";
@@ -125,6 +128,11 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
@SmallTest
public void testGetBatterySaverPolicy_PolicySound_DefaultValueCorrect() {
testServiceDefaultValue_On(ServiceType.SOUND);
mBatterySaverPolicy.setPolicyLevel(POLICY_LEVEL_FULL);
PowerSaveState stateOn =
mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.SOUND);
assertThat(stateOn.soundTriggerMode).isEqualTo(DEFAULT_SOUND_TRIGGER_MODE);
}
@SmallTest
@@ -211,6 +219,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
final PowerSaveState soundState =
mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.SOUND);
assertThat(soundState.batterySaverEnabled).isTrue();
assertThat(soundState.soundTriggerMode).isEqualTo(SOUND_TRIGGER_MODE);
final PowerSaveState networkState = mBatterySaverPolicy.getBatterySaverPolicy(
ServiceType.NETWORK_FIREWALL);
@@ -408,7 +417,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
+ "," + BatterySaverPolicy.KEY_DISABLE_AOD + "=true"
+ "," + BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST + "=true"
+ "," + BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS + "=true"
+ "," + BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER + "=true"
+ "," + BatterySaverPolicy.KEY_DISABLE_VIBRATION + "=true"
+ "," + BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + "=true"
+ "," + BatterySaverPolicy.KEY_ENABLE_DATASAVER + "=true"
@@ -418,7 +426,9 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
+ "," + BatterySaverPolicy.KEY_FORCE_ALL_APPS_STANDBY + "=true"
+ "," + BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK + "=true"
+ "," + BatterySaverPolicy.KEY_LOCATION_MODE
+ "=" + PowerManager.LOCATION_MODE_FOREGROUND_ONLY,
+ "=" + PowerManager.LOCATION_MODE_FOREGROUND_ONLY
+ "," + BatterySaverPolicy.KEY_SOUNDTRIGGER_MODE
+ "=" + PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY,
"",
new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_BATTERY_SAVER)
.setFloat(BatterySaverPolicy.KEY_ADJUST_BRIGHTNESS_FACTOR, .5f)
@@ -429,7 +439,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
.setBoolean(BatterySaverPolicy.KEY_DISABLE_AOD, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_VIBRATION, false)
.setBoolean(BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT, false)
.setBoolean(BatterySaverPolicy.KEY_ENABLE_DATASAVER, false)
@@ -440,6 +449,8 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
.setBoolean(BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK, false)
.setInt(BatterySaverPolicy.KEY_LOCATION_MODE,
PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF)
.setInt(BatterySaverPolicy.KEY_SOUNDTRIGGER_MODE,
PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED)
.build(),
null);
assertEquals(.1f, policy.adjustBrightnessFactor);
@@ -450,7 +461,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
assertTrue(policy.disableAod);
assertTrue(policy.disableLaunchBoost);
assertTrue(policy.disableOptionalSensors);
assertTrue(policy.disableSoundTrigger);
assertTrue(policy.disableVibration);
assertTrue(policy.enableAdjustBrightness);
assertTrue(policy.enableDataSaver);
@@ -460,6 +470,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
assertTrue(policy.forceAllAppsStandby);
assertTrue(policy.forceBackgroundCheck);
assertEquals(PowerManager.LOCATION_MODE_FOREGROUND_ONLY, policy.locationMode);
assertEquals(PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY, policy.soundTriggerMode);
}
public void testDeviceConfigOverridesDefaults() {
@@ -474,7 +485,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
.setBoolean(BatterySaverPolicy.KEY_DISABLE_AOD, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_VIBRATION, false)
.setBoolean(BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT, false)
.setBoolean(BatterySaverPolicy.KEY_ENABLE_DATASAVER, false)
@@ -485,6 +495,8 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
.setBoolean(BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK, false)
.setInt(BatterySaverPolicy.KEY_LOCATION_MODE,
PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF)
.setInt(BatterySaverPolicy.KEY_SOUNDTRIGGER_MODE,
PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED)
.build(),
null);
assertEquals(.5f, policy.adjustBrightnessFactor);
@@ -495,7 +507,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
assertFalse(policy.disableAod);
assertFalse(policy.disableLaunchBoost);
assertFalse(policy.disableOptionalSensors);
assertFalse(policy.disableSoundTrigger);
assertFalse(policy.disableVibration);
assertFalse(policy.enableAdjustBrightness);
assertFalse(policy.enableDataSaver);
@@ -506,6 +517,8 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
assertFalse(policy.forceBackgroundCheck);
assertEquals(PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF,
policy.locationMode);
assertEquals(PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED,
policy.soundTriggerMode);
}
public void testDeviceConfig_AdaptiveValues() {
@@ -521,7 +534,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
.setBoolean(BatterySaverPolicy.KEY_DISABLE_AOD, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER, false)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_VIBRATION, false)
.setBoolean(BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT, false)
.setBoolean(BatterySaverPolicy.KEY_ENABLE_DATASAVER, false)
@@ -532,6 +544,8 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
.setBoolean(BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK, false)
.setInt(BatterySaverPolicy.KEY_LOCATION_MODE,
PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF)
.setInt(BatterySaverPolicy.KEY_SOUNDTRIGGER_MODE,
PowerManager.SOUND_TRIGGER_MODE_ALL_DISABLED)
.setFloat(BatterySaverPolicy.KEY_ADJUST_BRIGHTNESS_FACTOR + adaptiveSuffix,
.9f)
.setBoolean(BatterySaverPolicy.KEY_ADVERTISE_IS_ENABLED + adaptiveSuffix,
@@ -546,8 +560,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
.setBoolean(
BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS + adaptiveSuffix,
true)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER + adaptiveSuffix,
true)
.setBoolean(BatterySaverPolicy.KEY_DISABLE_VIBRATION + adaptiveSuffix, true)
.setBoolean(BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT
+ adaptiveSuffix, true)
@@ -561,6 +573,8 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
true)
.setInt(BatterySaverPolicy.KEY_LOCATION_MODE + adaptiveSuffix,
PowerManager.LOCATION_MODE_FOREGROUND_ONLY)
.setInt(BatterySaverPolicy.KEY_SOUNDTRIGGER_MODE + adaptiveSuffix,
PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY)
.build(), adaptiveSuffix);
assertEquals(.9f, policy.adjustBrightnessFactor);
assertTrue(policy.advertiseIsEnabled);
@@ -570,7 +584,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
assertTrue(policy.disableAod);
assertTrue(policy.disableLaunchBoost);
assertTrue(policy.disableOptionalSensors);
assertTrue(policy.disableSoundTrigger);
assertTrue(policy.disableVibration);
assertTrue(policy.enableAdjustBrightness);
assertTrue(policy.enableDataSaver);
@@ -580,5 +593,6 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
assertTrue(policy.forceAllAppsStandby);
assertTrue(policy.forceBackgroundCheck);
assertEquals(PowerManager.LOCATION_MODE_FOREGROUND_ONLY, policy.locationMode);
assertEquals(PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY, policy.soundTriggerMode);
}
}

View File

@@ -44,7 +44,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
import android.os.PowerManager.SoundTriggerPowerSaveMode;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
@@ -107,7 +107,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
private HashMap<Integer, UUID> mKeyphraseUuidMap;
private boolean mCallActive = false;
private boolean mIsPowerSaveMode = false;
private @SoundTriggerPowerSaveMode int mSoundTriggerPowerSaveMode =
PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED;
// Indicates if the native sound trigger service is disabled or not.
// This is an indirect indication of the microphone being open in some other application.
private boolean mServiceDisabled = false;
@@ -205,7 +206,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
*/
int startGenericRecognition(UUID modelId, GenericSoundModel soundModel,
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig) {
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
boolean runInBatterySaverMode) {
MetricsLogger.count(mContext, "sth_start_recognition", 1);
if (modelId == null || soundModel == null || callback == null ||
recognitionConfig == null) {
@@ -220,7 +222,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return STATUS_ERROR;
}
return startRecognition(soundModel, modelData, callback, recognitionConfig,
INVALID_VALUE /* keyphraseId */);
INVALID_VALUE /* keyphraseId */, runInBatterySaverMode);
}
}
@@ -234,7 +236,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
*/
int startKeyphraseRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig) {
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
boolean runInBatterySaverMode) {
synchronized (mLock) {
MetricsLogger.count(mContext, "sth_start_recognition", 1);
if (soundModel == null || callback == null || recognitionConfig == null) {
@@ -244,7 +247,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
if (DBG) {
Slog.d(TAG, "startKeyphraseRecognition for keyphraseId=" + keyphraseId
+ " soundModel=" + soundModel + ", callback=" + callback.asBinder()
+ ", recognitionConfig=" + recognitionConfig);
+ ", recognitionConfig=" + recognitionConfig
+ ", runInBatterySaverMode=" + runInBatterySaverMode);
Slog.d(TAG, "moduleProperties=" + mModuleProperties);
dumpModelStateLocked();
}
@@ -273,7 +277,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
}
return startRecognition(soundModel, model, callback, recognitionConfig,
keyphraseId);
keyphraseId, runInBatterySaverMode);
}
}
@@ -334,7 +338,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
*/
int startRecognition(SoundModel soundModel, ModelData modelData,
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
int keyphraseId) {
int keyphraseId, boolean runInBatterySaverMode) {
synchronized (mLock) {
if (mModuleProperties == null) {
Slog.w(TAG, "Attempting startRecognition without the capability");
@@ -387,10 +391,11 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
modelData.setCallback(callback);
modelData.setRequested(true);
modelData.setRecognitionConfig(recognitionConfig);
modelData.setRunInBatterySaverMode(runInBatterySaverMode);
modelData.setSoundModel(soundModel);
if (!isRecognitionAllowed()) {
initializeTelephonyAndPowerStateListeners();
if (!isRecognitionAllowedByDeviceState(modelData)) {
initializeDeviceStateListeners();
return STATUS_OK;
}
@@ -404,7 +409,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Initialize power save, call active state monitoring logic.
if (status == STATUS_OK) {
initializeTelephonyAndPowerStateListeners();
initializeDeviceStateListeners();
}
return status;
@@ -519,8 +524,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Request stop recognition via the update() method.
modelData.setRequested(false);
int status = updateRecognitionLocked(modelData, isRecognitionAllowed(),
false /* don't notify for synchronous calls */);
int status = updateRecognitionLocked(modelData, false);
if (status != SoundTrigger.STATUS_OK) {
return status;
}
@@ -589,8 +593,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Stop recognition if it's the current one.
modelData.setRequested(false);
int status = updateRecognitionLocked(modelData, isRecognitionAllowed(),
false /* don't notify */);
int status = updateRecognitionLocked(modelData, false);
if (status != SoundTrigger.STATUS_OK) {
Slog.w(TAG, "Stop recognition failed for keyphrase ID:" + status);
}
@@ -854,8 +857,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
model.setRequested(config.allowMultipleTriggers);
// TODO: Remove this block if the lower layer supports multiple triggers.
if (model.isRequested()) {
updateRecognitionLocked(model, isRecognitionAllowed() /* isAllowed */,
true /* notify */);
updateRecognitionLocked(model, true);
}
}
@@ -896,15 +898,16 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return;
}
mCallActive = callActive;
updateAllRecognitionsLocked(true /* notify */);
updateAllRecognitionsLocked();
}
private void onPowerSaveModeChangedLocked(boolean isPowerSaveMode) {
if (mIsPowerSaveMode == isPowerSaveMode) {
private void onPowerSaveModeChangedLocked(
@SoundTriggerPowerSaveMode int soundTriggerPowerSaveMode) {
if (mSoundTriggerPowerSaveMode == soundTriggerPowerSaveMode) {
return;
}
mIsPowerSaveMode = isPowerSaveMode;
updateAllRecognitionsLocked(true /* notify */);
mSoundTriggerPowerSaveMode = soundTriggerPowerSaveMode;
updateAllRecognitionsLocked();
}
private void onSoundModelUpdatedLocked(SoundModelEvent event) {
@@ -916,7 +919,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return;
}
mServiceDisabled = disabled;
updateAllRecognitionsLocked(true /* notify */);
updateAllRecognitionsLocked();
}
private void onRecognitionAbortLocked(RecognitionEvent event) {
@@ -997,34 +1000,32 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
}
// TODO: Remove this block if the lower layer supports multiple triggers.
if (modelData.isRequested()) {
updateRecognitionLocked(modelData, isRecognitionAllowed(), true /* notify */);
updateRecognitionLocked(modelData, true);
}
}
private void updateAllRecognitionsLocked(boolean notify) {
boolean isAllowed = isRecognitionAllowed();
private void updateAllRecognitionsLocked() {
// updateRecognitionLocked can possibly update the list of models
ArrayList<ModelData> modelDatas = new ArrayList<ModelData>(mModelDataMap.values());
for (ModelData modelData : modelDatas) {
updateRecognitionLocked(modelData, isAllowed, notify);
updateRecognitionLocked(modelData, true);
}
}
private int updateRecognitionLocked(ModelData model, boolean isAllowed,
boolean notify) {
boolean start = model.isRequested() && isAllowed;
if (start == model.isModelStarted()) {
private int updateRecognitionLocked(ModelData model, boolean notifyClientOnError) {
boolean shouldStartModel = model.isRequested() && isRecognitionAllowedByDeviceState(model);
if (shouldStartModel == model.isModelStarted()) {
// No-op.
return STATUS_OK;
}
if (start) {
if (shouldStartModel) {
int status = prepareForRecognition(model);
if (status != STATUS_OK) {
return status;
}
return startRecognitionLocked(model, notify);
return startRecognitionLocked(model, notifyClientOnError);
} else {
return stopRecognitionLocked(model, notify);
return stopRecognitionLocked(model, notifyClientOnError);
}
}
@@ -1095,11 +1096,13 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
if (!PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(intent.getAction())) {
return;
}
boolean active = mPowerManager.getPowerSaveState(ServiceType.SOUND)
.batterySaverEnabled;
if (DBG) Slog.d(TAG, "onPowerSaveModeChanged: " + active);
@SoundTriggerPowerSaveMode int soundTriggerPowerSaveMode =
mPowerManager.getSoundTriggerPowerSaveMode();
if (DBG) {
Slog.d(TAG, "onPowerSaveModeChanged: " + soundTriggerPowerSaveMode);
}
synchronized (mLock) {
onPowerSaveModeChangedLocked(active);
onPowerSaveModeChangedLocked(soundTriggerPowerSaveMode);
}
}
}
@@ -1108,14 +1111,15 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
synchronized (mLock) {
pw.print(" module properties=");
pw.println(mModuleProperties == null ? "null" : mModuleProperties);
pw.print(" call active="); pw.println(mCallActive);
pw.print(" power save mode active="); pw.println(mIsPowerSaveMode);
pw.print(" service disabled="); pw.println(mServiceDisabled);
pw.print(" call active=");
pw.println(mCallActive);
pw.println(" SoundTrigger Power State=" + mSoundTriggerPowerSaveMode);
pw.print(" service disabled=");
pw.println(mServiceDisabled);
}
}
private void initializeTelephonyAndPowerStateListeners() {
private void initializeDeviceStateListeners() {
if (mRecognitionRequested) {
return;
}
@@ -1134,8 +1138,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
mContext.registerReceiver(mPowerSaveModeListener,
new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
}
mIsPowerSaveMode = mPowerManager.getPowerSaveState(ServiceType.SOUND)
.batterySaverEnabled;
mSoundTriggerPowerSaveMode = mPowerManager.getSoundTriggerPowerSaveMode();
mRecognitionRequested = true;
} finally {
@@ -1308,23 +1311,44 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return null;
}
// Whether we are allowed to run any recognition at all. The conditions that let us run
// a recognition include: no active phone call or not being in a power save mode. Also,
// the native service should be enabled.
private boolean isRecognitionAllowed() {
/**
* Determines if recognition is allowed at all based on device state
*
* <p>Depending on the state of the SoundTrigger service, whether a call is active, or if
* battery saver mode is enabled, a specific model may or may not be able to run. The result
* of this check is not permanent, and the state of the device can change at any time.
*
* @param modelData Model data to be used for recognition
* @return True if recognition is allowed to run at this time. False if not.
*/
private boolean isRecognitionAllowedByDeviceState(ModelData modelData) {
// if mRecognitionRequested is false, call and power state listeners are not registered so
// we read current state directly from services
if (!mRecognitionRequested) {
mCallActive = mTelephonyManager.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK;
mIsPowerSaveMode =
mPowerManager.getPowerSaveState(ServiceType.SOUND).batterySaverEnabled;
mSoundTriggerPowerSaveMode = mPowerManager.getSoundTriggerPowerSaveMode();
}
return !mCallActive && !mServiceDisabled && !mIsPowerSaveMode;
return !mCallActive && !mServiceDisabled
&& isRecognitionAllowedByPowerState(
modelData);
}
/**
* Helper function to validate if a recognition should run based on the current power state
*
* @param modelData Model data to be used for recognition
* @return True if device state allows recognition to run, false if not.
*/
boolean isRecognitionAllowedByPowerState(ModelData modelData) {
return mSoundTriggerPowerSaveMode == PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED
|| (mSoundTriggerPowerSaveMode == PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY
&& modelData.shouldRunInBatterySaverMode());
}
// A single routine that implements the start recognition logic for both generic and keyphrase
// models.
private int startRecognitionLocked(ModelData modelData, boolean notify) {
private int startRecognitionLocked(ModelData modelData, boolean notifyClientOnError) {
IRecognitionStatusCallback callback = modelData.getCallback();
RecognitionConfig config = modelData.getRecognitionConfig();
if (callback == null || !modelData.isModelLoaded() || config == null) {
@@ -1334,7 +1358,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return STATUS_ERROR;
}
if (!isRecognitionAllowed()) {
if (!isRecognitionAllowedByDeviceState(modelData)) {
// Nothing to do here.
Slog.w(TAG, "startRecognition requested but not allowed.");
MetricsLogger.count(mContext, "sth_start_recognition_not_allowed", 1);
@@ -1349,7 +1373,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
Slog.w(TAG, "startRecognition failed with " + status);
MetricsLogger.count(mContext, "sth_start_recognition_error", 1);
// Notify of error if needed.
if (notify) {
if (notifyClientOnError) {
try {
callback.onError(status);
} catch (DeadObjectException e) {
@@ -1363,7 +1387,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
MetricsLogger.count(mContext, "sth_start_recognition_success", 1);
modelData.setStarted();
// Notify of resume if needed.
if (notify) {
if (notifyClientOnError) {
try {
callback.onRecognitionResumed();
} catch (DeadObjectException e) {
@@ -1487,6 +1511,14 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// models.
private int mModelHandle;
/**
* True if the service should continue listening when battery saver mode is enabled.
* Having this flag set requires the client calling
* {@link SoundTriggerModule#startRecognition(int, RecognitionConfig)} to be granted
* {@link android.Manifest.permission#SOUND_TRIGGER_RUN_IN_BATTERY_SAVER}.
*/
public boolean mRunInBatterySaverMode = false;
// The SoundModel instance, one of KeyphraseSoundModel or GenericSoundModel.
private SoundModel mSoundModel = null;
@@ -1562,6 +1594,14 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
mRecognitionConfig = config;
}
synchronized void setRunInBatterySaverMode(boolean runInBatterySaverMode) {
mRunInBatterySaverMode = runInBatterySaverMode;
}
synchronized boolean shouldRunInBatterySaverMode() {
return mRunInBatterySaverMode;
}
synchronized int getHandle() {
return mModelHandle;
}
@@ -1629,7 +1669,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
"ModelState: " + stateToString() + "\n" +
requestedToString() + "\n" +
callbackToString() + "\n" +
uuidToString() + "\n" + modelTypeToString();
uuidToString() + "\n" +
modelTypeToString() +
"RunInBatterySaverMode=" + mRunInBatterySaverMode;
}
synchronized String modelTypeToString() {

View File

@@ -26,7 +26,6 @@ import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
import android.hardware.soundtrigger.SoundTrigger.ModelParamRange;
import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
import android.media.permission.Identity;
import android.os.IBinder;
import com.android.server.voiceinteraction.VoiceInteractionManagerService;
@@ -63,10 +62,13 @@ public interface SoundTriggerInternal {
* @param soundModel The sound model to use for recognition.
* @param listener The listener for the recognition events related to the given
* keyphrase.
* @param runInBatterySaverMode flag that indicates whether the recognition should continue
* after battery saver mode is enabled.
* @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
*/
int startRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig);
IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig,
boolean runInBatterySaverMode);
/**
* Stops recognition for the given {@link Keyphrase} if a recognition is

View File

@@ -296,8 +296,11 @@ public class SoundTriggerService extends SystemService {
@Override
public int startRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback,
RecognitionConfig config) {
RecognitionConfig config, boolean runInBatterySaverMode) {
enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
if (runInBatterySaverMode) {
enforceCallingPermission(Manifest.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER);
}
if (DEBUG) {
Slog.i(TAG, "startRecognition(): Uuid : " + parcelUuid);
}
@@ -316,7 +319,7 @@ public class SoundTriggerService extends SystemService {
}
int ret = mSoundTriggerHelper.startGenericRecognition(parcelUuid.getUuid(), model,
callback, config);
callback, config, runInBatterySaverMode);
if (ret == STATUS_OK) {
mSoundModelStatTracker.onStart(parcelUuid.getUuid());
}
@@ -514,7 +517,7 @@ public class SoundTriggerService extends SystemService {
switch (soundModel.getType()) {
case SoundModel.TYPE_GENERIC_SOUND:
ret = mSoundTriggerHelper.startGenericRecognition(soundModel.getUuid(),
(GenericSoundModel) soundModel, callback, config);
(GenericSoundModel) soundModel, callback, config, false);
break;
default:
Slog.e(TAG, "Unknown model type");
@@ -1505,10 +1508,10 @@ public class SoundTriggerService extends SystemService {
@Override
public int startRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig) {
IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig,
boolean runInBatterySaverMode) {
return mSoundTriggerHelper.startKeyphraseRecognition(keyphraseId, soundModel,
listener,
recognitionConfig);
listener, recognitionConfig, runInBatterySaverMode);
}
@Override

View File

@@ -1146,7 +1146,8 @@ public class VoiceInteractionManagerService extends SystemService {
@Override
public int startRecognition(int keyphraseId, String bcp47Locale,
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig) {
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
boolean runInBatterySaverMode) {
// Allow the call if this is the current voice interaction service.
synchronized (VoiceInteractionManagerServiceStub.this) {
enforceIsCurrentVoiceInteractionService();
@@ -1154,6 +1155,10 @@ public class VoiceInteractionManagerService extends SystemService {
if (callback == null || recognitionConfig == null || bcp47Locale == null) {
throw new IllegalArgumentException("Illegal argument(s) in startRecognition");
}
if (runInBatterySaverMode) {
enforceCallingPermission(
Manifest.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER);
}
}
final int callingUserId = UserHandle.getCallingUserId();
@@ -1173,7 +1178,8 @@ public class VoiceInteractionManagerService extends SystemService {
mLoadedKeyphraseIds.put(keyphraseId, this);
}
return mSession.startRecognition(
keyphraseId, soundModel, callback, recognitionConfig);
keyphraseId, soundModel, callback, recognitionConfig,
runInBatterySaverMode);
}
} finally {
Binder.restoreCallingIdentity(caller);