diff --git a/api/cm_current.txt b/api/cm_current.txt index 7597153d..b04ab7df 100644 --- a/api/cm_current.txt +++ b/api/cm_current.txt @@ -316,8 +316,8 @@ package cyanogenmod.app { field public static final int PROFILES_STATE_ENABLED = 1; // 0x1 } - public class SettingsManager { - method public static cyanogenmod.app.SettingsManager getInstance(android.content.Context); + public class PartnerInterface { + method public static cyanogenmod.app.PartnerInterface getInstance(android.content.Context); method public void rebootDevice(); method public void setAirplaneModeEnabled(boolean); method public void setMobileDataEnabled(boolean); diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/SettingsManagerService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/PartnerInterfaceService.java similarity index 79% rename from cm/lib/main/java/org/cyanogenmod/platform/internal/SettingsManagerService.java rename to cm/lib/main/java/org/cyanogenmod/platform/internal/PartnerInterfaceService.java index ae50755d..5cad50fa 100644 --- a/cm/lib/main/java/org/cyanogenmod/platform/internal/SettingsManagerService.java +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/PartnerInterfaceService.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.media.IAudioService; import android.os.IBinder; import android.os.IPowerManager; @@ -33,8 +34,9 @@ import android.telephony.TelephonyManager; import android.util.Log; import com.android.server.SystemService; import cyanogenmod.app.CMContextConstants; -import cyanogenmod.app.ISettingsManager; -import cyanogenmod.app.SettingsManager; +import cyanogenmod.app.IPartnerInterface; +import cyanogenmod.app.PartnerInterface; +import cyanogenmod.media.MediaRecorder; import java.io.ByteArrayInputStream; import java.security.PublicKey; @@ -44,18 +46,19 @@ import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; /** {@hide} */ -public class SettingsManagerService extends SystemService { +public class PartnerInterfaceService extends SystemService { private static final String TAG = "CMSettingsService"; private Context mContext; private TelephonyManager mTelephonyManager; private INotificationManager mNotificationManager; + private IAudioService mAudioService; - public SettingsManagerService(Context context) { + public PartnerInterfaceService(Context context) { super(context); mContext = context; - publishBinderService(CMContextConstants.CM_SETTINGS_SERVICE, mService); + publishBinderService(CMContextConstants.CM_PARTNER_INTERFACE, mService); } @Override @@ -64,15 +67,17 @@ public class SettingsManagerService extends SystemService { mContext.getSystemService(Context.TELEPHONY_SERVICE); mNotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); + IBinder b = ServiceManager.getService(android.content.Context.AUDIO_SERVICE); + mAudioService = IAudioService.Stub.asInterface(b); } private void enforceModifyNetworkSettingsPermission() { - mContext.enforceCallingOrSelfPermission(SettingsManager.MODIFY_NETWORK_SETTINGS_PERMISSION, + mContext.enforceCallingOrSelfPermission(PartnerInterface.MODIFY_NETWORK_SETTINGS_PERMISSION, "You do not have permissions to change system network settings."); } private void enforceModifySoundSettingsPermission() { - mContext.enforceCallingOrSelfPermission(SettingsManager.MODIFY_SOUND_SETTINGS_PERMISSION, + mContext.enforceCallingOrSelfPermission(PartnerInterface.MODIFY_SOUND_SETTINGS_PERMISSION, "You do not have permissions to change system sound settings."); } @@ -81,7 +86,12 @@ public class SettingsManagerService extends SystemService { "You do not have permissions to shut down the device."); } - private final IBinder mService = new ISettingsManager.Stub() { + private void enforceCaptureHotwordPermission() { + mContext.enforceCallingOrSelfPermission(MediaRecorder.CAPTURE_AUDIO_HOTWORD_PERMISSION, + "You do not have permission to query the hotword input package name."); + } + + private final IBinder mService = new IPartnerInterface.Stub() { @Override public void setAirplaneModeEnabled(boolean enabled) { @@ -148,6 +158,15 @@ public class SettingsManagerService extends SystemService { restoreCallingIdentity(token); return success; } + + @Override + public String getCurrentHotwordPackageName() { + enforceCaptureHotwordPermission(); + long token = clearCallingIdentity(); + String packageName = getHotwordPackageNameInternal(); + restoreCallingIdentity(token); + return packageName; + } }; private void setAirplaneModeEnabledInternal(boolean enabled) { @@ -183,13 +202,13 @@ public class SettingsManagerService extends SystemService { ContentResolver contentResolver = mContext.getContentResolver(); int zenModeValue = -1; switch(mode) { - case SettingsManager.ZEN_MODE_IMPORTANT_INTERRUPTIONS: + case PartnerInterface.ZEN_MODE_IMPORTANT_INTERRUPTIONS: zenModeValue = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; break; - case SettingsManager.ZEN_MODE_OFF: + case PartnerInterface.ZEN_MODE_OFF: zenModeValue = Settings.Global.ZEN_MODE_OFF; break; - case SettingsManager.ZEN_MODE_NO_INTERRUPTIONS: + case PartnerInterface.ZEN_MODE_NO_INTERRUPTIONS: zenModeValue = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; break; default: @@ -211,5 +230,15 @@ public class SettingsManagerService extends SystemService { } return true; } + + public String getHotwordPackageNameInternal() { + String packageName = null; + try { + packageName = mAudioService.getCurrentHotwordInputPackageName(); + } catch (RemoteException e) { + Log.e(TAG, "getHotwordPackageName() failed."); + } + return packageName; + } } diff --git a/src/java/cyanogenmod/app/CMContextConstants.java b/src/java/cyanogenmod/app/CMContextConstants.java index b79063ac..ab80b4f2 100644 --- a/src/java/cyanogenmod/app/CMContextConstants.java +++ b/src/java/cyanogenmod/app/CMContextConstants.java @@ -53,14 +53,14 @@ public final class CMContextConstants { /** * Use with {@link android.content.Context#getSystemService} to retrieve a - * {@link cyanogenmod.app.SettingsManager} changing system settings. + * {@link cyanogenmod.app.PartnerInterface} interact with system settings. * * @see android.content.Context#getSystemService - * @see cyanogenmod.app.SettingsManager + * @see cyanogenmod.app.PartnerInterface * * @hide */ - public static final String CM_SETTINGS_SERVICE = "cmsettings"; + public static final String CM_PARTNER_INTERFACE = "cmpartnerinterface"; /** * Use with {@link android.content.Context#getSystemService} to retrieve a diff --git a/src/java/cyanogenmod/app/ISettingsManager.aidl b/src/java/cyanogenmod/app/IPartnerInterface.aidl similarity index 92% rename from src/java/cyanogenmod/app/ISettingsManager.aidl rename to src/java/cyanogenmod/app/IPartnerInterface.aidl index 86fa36c3..b7baa4de 100644 --- a/src/java/cyanogenmod/app/ISettingsManager.aidl +++ b/src/java/cyanogenmod/app/IPartnerInterface.aidl @@ -18,11 +18,12 @@ package cyanogenmod.app; /** {@hide} */ -interface ISettingsManager +interface IPartnerInterface { void setAirplaneModeEnabled(boolean enabled); void setMobileDataEnabled(boolean enabled); boolean setZenMode(int mode); void shutdown(); void reboot(); + String getCurrentHotwordPackageName(); } diff --git a/src/java/cyanogenmod/app/SettingsManager.java b/src/java/cyanogenmod/app/PartnerInterface.java similarity index 76% rename from src/java/cyanogenmod/app/SettingsManager.java rename to src/java/cyanogenmod/app/PartnerInterface.java index b8a58024..74f230a0 100644 --- a/src/java/cyanogenmod/app/SettingsManager.java +++ b/src/java/cyanogenmod/app/PartnerInterface.java @@ -24,10 +24,10 @@ import android.util.Log; /** *
- * The SettingsManager allows applications to modify a subset of system settings. + * The PartnerInterface allows applications to interact with a subset of system settings. *
*/ -public class SettingsManager { +public class PartnerInterface { /** * Turn off zen mode. This restores the original ring and interruption * settings that the user had set before zen mode was enabled. @@ -53,7 +53,7 @@ public class SettingsManager { */ public static final int ZEN_MODE_NO_INTERRUPTIONS = 2; - private static ISettingsManager sService; + private static IPartnerInterface sService; private Context mContext; @@ -70,11 +70,11 @@ public class SettingsManager { public static final String MODIFY_SOUND_SETTINGS_PERMISSION = "cyanogenmod.permission.MODIFY_SOUND_SETTINGS"; - private static final String TAG = "SettingsManager"; + private static final String TAG = "PartnerInterface"; - private static SettingsManager sSettingsManagerInstance; + private static PartnerInterface sPartnerInterfaceInstance; - private SettingsManager(Context context) { + private PartnerInterface(Context context) { Context appContext = context.getApplicationContext(); if (appContext != null) { mContext = appContext; @@ -85,25 +85,25 @@ public class SettingsManager { } /** - * Get or create an instance of the {@link cyanogenmod.app.SettingsManager} + * Get or create an instance of the {@link cyanogenmod.app.PartnerInterface} * @param context - * @return {@link SettingsManager} + * @return {@link PartnerInterface} */ - public static SettingsManager getInstance(Context context) { - if (sSettingsManagerInstance == null) { - sSettingsManagerInstance = new SettingsManager(context); + public static PartnerInterface getInstance(Context context) { + if (sPartnerInterfaceInstance == null) { + sPartnerInterfaceInstance = new PartnerInterface(context); } - return sSettingsManagerInstance; + return sPartnerInterfaceInstance; } /** @hide */ - static public ISettingsManager getService() { + static public IPartnerInterface getService() { if (sService != null) { return sService; } - IBinder b = ServiceManager.getService(CMContextConstants.CM_SETTINGS_SERVICE); + IBinder b = ServiceManager.getService(CMContextConstants.CM_PARTNER_INTERFACE); if (b != null) { - sService = ISettingsManager.Stub.asInterface(b); + sService = IPartnerInterface.Stub.asInterface(b); return sService; } else { return null; @@ -122,7 +122,7 @@ public class SettingsManager { return; } try { - getService().setAirplaneModeEnabled(enabled); + sService.setAirplaneModeEnabled(enabled); } catch (RemoteException e) { Log.e(TAG, e.getLocalizedMessage(), e); } @@ -140,7 +140,7 @@ public class SettingsManager { return; } try { - getService().setMobileDataEnabled(enabled); + sService.setMobileDataEnabled(enabled); } catch (RemoteException e) { Log.e(TAG, e.getLocalizedMessage(), e); } @@ -165,7 +165,7 @@ public class SettingsManager { return false; } try { - return getService().setZenMode(mode); + return sService.setZenMode(mode); } catch (RemoteException e) { Log.e(TAG, e.getLocalizedMessage(), e); } @@ -183,7 +183,7 @@ public class SettingsManager { return; } try { - getService().shutdown(); + sService.shutdown(); } catch (RemoteException e) { Log.e(TAG, e.getLocalizedMessage(), e); } @@ -200,9 +200,26 @@ public class SettingsManager { return; } try { - getService().reboot(); + sService.reboot(); } catch (RemoteException e) { Log.e(TAG, e.getLocalizedMessage(), e); } } + + /** + * Retrieves the package name of the application that currently holds the + * {@link cyanogenmod.media.MediaRecorder.AudioSource#HOTWORD} input. + * @return The package name or null if no application currently holds the HOTWORD input. + */ + public String getCurrentHotwordPackageName() { + if (sService == null) { + return null; + } + try { + return sService.getCurrentHotwordPackageName(); + } catch (RemoteException e) { + Log.e(TAG, e.getLocalizedMessage(), e); + } + return null; + } } diff --git a/src/java/cyanogenmod/media/MediaRecorder.java b/src/java/cyanogenmod/media/MediaRecorder.java index 7d56e365..c28cc932 100644 --- a/src/java/cyanogenmod/media/MediaRecorder.java +++ b/src/java/cyanogenmod/media/MediaRecorder.java @@ -26,7 +26,47 @@ public class MediaRecorder { public static final String CAPTURE_AUDIO_HOTWORD_PERMISSION = "android.permission.CAPTURE_AUDIO_HOTWORD"; - public class AudioSource { + /** + *Broadcast Action: The state of the HOTWORD audio input has changed.:
+ *This is a protected intent that can only be sent + * by the system. It can only be received by packages that hold + * {@link android.Manifest.permission#CAPTURE_AUDIO_HOTWORD}. + */ + //@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_HOTWORD_INPUT_CHANGED + = "com.cyanogenmod.intent.action.HOTWORD_INPUT_CHANGED"; + + /** + * Extra for {@link #ACTION_HOTWORD_INPUT_CHANGED} that provides the package name of the + * app in that controlled the HOTWORD input when the state changed. Can be reused for other + * purposes. + */ + public static final String EXTRA_CURRENT_PACKAGE_NAME = + "com.cyanogenmod.intent.extra.CURRENT_PACKAGE_NAME"; + + /** + * Extra for {@link #ACTION_HOTWORD_INPUT_CHANGED} that provides the state of + * the input when the broadcast action was sent. + * @hide + */ + public static final String EXTRA_HOTWORD_INPUT_STATE = + "com.cyanogenmod.intent.extra.HOTWORD_INPUT_STATE"; + + + public static class AudioSource { /** * Audio source for preemptible, low-priority software hotword detection * It presents the same gain and pre processing tuning as diff --git a/src/java/cyanogenmod/os/Build.java b/src/java/cyanogenmod/os/Build.java index 015168b2..2218447a 100644 --- a/src/java/cyanogenmod/os/Build.java +++ b/src/java/cyanogenmod/os/Build.java @@ -99,7 +99,7 @@ public class Build { *