diff options
| author | Svet Ganov <svetoslavganov@google.com> | 2015-04-28 12:06:02 -0700 | 
|---|---|---|
| committer | Svetoslav Ganov <svetoslavganov@google.com> | 2015-04-29 19:06:41 +0000 | 
| commit | be71aa29a3c86d2e01cd17839d2a72ab09a1bce5 (patch) | |
| tree | ca29cd10f78ff053761eb809c391019180836742 | |
| parent | f62a067a5b21c840c915d36392679346ac0abfd7 (diff) | |
| download | frameworks_av-be71aa29a3c86d2e01cd17839d2a72ab09a1bce5.zip frameworks_av-be71aa29a3c86d2e01cd17839d2a72ab09a1bce5.tar.gz frameworks_av-be71aa29a3c86d2e01cd17839d2a72ab09a1bce5.tar.bz2  | |
Respect the record audio app op - media
Change-Id: I3a97977b6e9a09355e2008f780d22d480fb7308b
34 files changed, 209 insertions, 75 deletions
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp index 7b0de24..6e9e6ec 100644 --- a/cmds/stagefright/audioloop.cpp +++ b/cmds/stagefright/audioloop.cpp @@ -18,6 +18,8 @@  #include <sys/stat.h>  #include <fcntl.h> +#include <utils/String16.h> +  #include <binder/ProcessState.h>  #include <media/mediarecorder.h>  #include <media/stagefright/foundation/ADebug.h> @@ -34,7 +36,7 @@ using namespace android;  static void usage(const char* name)  { -    fprintf(stderr, "Usage: %s [-d duration] [-m] [-w] [<output-file>]\n", name); +    fprintf(stderr, "Usage: %s [-d du.ration] [-m] [-w] [<output-file>]\n", name);      fprintf(stderr, "Encodes either a sine wave or microphone input to AMR format\n");      fprintf(stderr, "    -d    duration in seconds, default 5 seconds\n");      fprintf(stderr, "    -m    use microphone for input, default sine source\n"); @@ -85,6 +87,7 @@ int main(int argc, char* argv[])          // talk into the appropriate microphone for the duration          source = new AudioSource(                  AUDIO_SOURCE_MIC, +                String16(),                  kSampleRate,                  channels);      } else { diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index 583695d..61da4f2 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -201,8 +201,12 @@ public:       */      /* Simple Constructor. +     * +     * Parameters: +     * +     * opPackageName:      The package name used for app op checks.       */ -    AudioEffect(); +    AudioEffect(const String16& opPackageName);      /* Constructor. @@ -211,6 +215,7 @@ public:       *       * type:  type of effect created: can be null if uuid is specified. This corresponds to       *        the OpenSL ES interface implemented by this effect. +     * opPackageName:  The package name used for app op checks.       * uuid:  Uuid of effect created: can be null if type is specified. This uuid corresponds to       *        a particular implementation of an effect type.       * priority:    requested priority for effect control: the priority level corresponds to the @@ -227,6 +232,7 @@ public:       */      AudioEffect(const effect_uuid_t *type, +                const String16& opPackageName,                  const effect_uuid_t *uuid = NULL,                    int32_t priority = 0,                    effect_callback_t cbf = NULL, @@ -239,6 +245,7 @@ public:       *      Same as above but with type and uuid specified by character strings       */      AudioEffect(const char *typeStr, +                    const String16& opPackageName,                      const char *uuidStr = NULL,                      int32_t priority = 0,                      effect_callback_t cbf = NULL, @@ -406,7 +413,9 @@ protected:       void*                   mUserData;          // client context for callback function       effect_descriptor_t     mDescriptor;        // effect descriptor       int32_t                 mId;                // system wide unique effect engine instance ID -     Mutex                   mLock;               // Mutex for mEnabled access +     Mutex                   mLock;              // Mutex for mEnabled access + +     String16                mOpPackageName;     // The package name used for app op checks.       // IEffectClient       virtual void controlStatusChanged(bool controlGranted); diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index c24a28d..b743c11 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -129,8 +129,12 @@ public:      /* Constructs an uninitialized AudioRecord. No connection with       * AudioFlinger takes place.  Use set() after this. +     * +     * Parameters: +     * +     * opPackageName:      The package name used for app ops.       */ -                        AudioRecord(); +                        AudioRecord(const String16& opPackageName);      /* Creates an AudioRecord object and registers it with AudioFlinger.       * Once created, the track needs to be started before it can be used. @@ -143,6 +147,7 @@ public:       * format:             Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed       *                     16 bits per sample).       * channelMask:        Channel mask, such that audio_is_input_channel(channelMask) is true. +     * opPackageName:      The package name used for app ops.       * frameCount:         Minimum size of track PCM buffer in frames. This defines the       *                     application's contribution to the       *                     latency of the track.  The actual size selected by the AudioRecord could @@ -165,6 +170,7 @@ public:                                      uint32_t sampleRate,                                      audio_format_t format,                                      audio_channel_mask_t channelMask, +                                    const String16& opPackageName,                                      size_t frameCount = 0,                                      callback_t cbf = NULL,                                      void* user = NULL, @@ -483,7 +489,7 @@ private:              // caller must hold lock on mLock for all _l methods -            status_t openRecord_l(size_t epoch); +            status_t openRecord_l(size_t epoch, const String16& opPackageName);              // FIXME enum is faster than strcmp() for parameter 'from'              status_t restoreRecord_l(const char *from); @@ -520,6 +526,8 @@ private:      status_t                mStatus; +    String16                mOpPackageName;         // The package name used for app ops. +      size_t                  mFrameCount;            // corresponds to current IAudioRecord, value is                                                      // reported back by AudioFlinger to the client      size_t                  mReqFrameCount;         // frame count to request the first or next time diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index f927a80..046345c 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -85,6 +85,7 @@ public:                                  uint32_t sampleRate,                                  audio_format_t format,                                  audio_channel_mask_t channelMask, +                                const String16& callingPackage,                                  size_t *pFrameCount,                                  track_flags_t *flags,                                  pid_t tid,  // -1 means unused, otherwise must be valid non-0 @@ -198,6 +199,7 @@ public:                                      // AudioFlinger doesn't take over handle reference from client                                      audio_io_handle_t output,                                      int sessionId, +                                    const String16& callingPackage,                                      status_t *status,                                      int *id,                                      int *enabled) = 0; diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 49a3d61..a316ce2 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -47,7 +47,7 @@ class IMediaPlayerService: public IInterface  public:      DECLARE_META_INTERFACE(MediaPlayerService); -    virtual sp<IMediaRecorder> createMediaRecorder() = 0; +    virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) = 0;      virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0;      virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, int audioSessionId = 0)              = 0; @@ -65,8 +65,8 @@ public:      // display client when display connection, disconnection or errors occur.      // The assumption is that at most one remote display will be connected to the      // provided interface at a time. -    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client, -            const String8& iface) = 0; +    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName, +            const sp<IRemoteDisplayClient>& client, const String8& iface) = 0;      // codecs and audio devices usage tracking for the battery app      enum BatteryDataBits { diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h index f55063e..f9feede 100644 --- a/include/media/MediaRecorderBase.h +++ b/include/media/MediaRecorderBase.h @@ -29,7 +29,8 @@ class Surface;  class IGraphicBufferProducer;  struct MediaRecorderBase { -    MediaRecorderBase() {} +    MediaRecorderBase(const String16 &opPackageName) +        : mOpPackageName(opPackageName) {}      virtual ~MediaRecorderBase() {}      virtual status_t init() = 0; @@ -57,6 +58,10 @@ struct MediaRecorderBase {      virtual status_t dump(int fd, const Vector<String16>& args) const = 0;      virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const = 0; + +protected: +    String16 mOpPackageName; +  private:      MediaRecorderBase(const MediaRecorderBase &);      MediaRecorderBase &operator=(const MediaRecorderBase &); diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h index 6167dd6..b92f816 100644 --- a/include/media/Visualizer.h +++ b/include/media/Visualizer.h @@ -65,7 +65,8 @@ public:      /* Constructor.       * See AudioEffect constructor for details on parameters.       */ -                        Visualizer(int32_t priority = 0, +                        Visualizer(const String16& opPackageName, +                                   int32_t priority = 0,                                     effect_callback_t cbf = NULL,                                     void* user = NULL,                                     int sessionId = 0); diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h index 74a6469..8e40c5d 100644 --- a/include/media/mediarecorder.h +++ b/include/media/mediarecorder.h @@ -209,7 +209,7 @@ class MediaRecorder : public BnMediaRecorderClient,                        public virtual IMediaDeathNotifier  {  public: -    MediaRecorder(); +    MediaRecorder(const String16& opPackageName);      ~MediaRecorder();      void        died(); diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h index 4c9aaad..50cf371 100644 --- a/include/media/stagefright/AudioSource.h +++ b/include/media/stagefright/AudioSource.h @@ -35,6 +35,7 @@ struct AudioSource : public MediaSource, public MediaBufferObserver {      // _not_ a bitmask of audio_channels_t constants.      AudioSource(              audio_source_t inputSource, +            const String16 &opPackageName,              uint32_t sampleRate,              uint32_t channels = 1); diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp index 7d8222f..bbeb854 100644 --- a/media/libmedia/AudioEffect.cpp +++ b/media/libmedia/AudioEffect.cpp @@ -35,13 +35,14 @@ namespace android {  // --------------------------------------------------------------------------- -AudioEffect::AudioEffect() -    : mStatus(NO_INIT) +AudioEffect::AudioEffect(const String16& opPackageName) +    : mStatus(NO_INIT), mOpPackageName(opPackageName)  {  }  AudioEffect::AudioEffect(const effect_uuid_t *type, +                const String16& opPackageName,                  const effect_uuid_t *uuid,                  int32_t priority,                  effect_callback_t cbf, @@ -49,12 +50,13 @@ AudioEffect::AudioEffect(const effect_uuid_t *type,                  int sessionId,                  audio_io_handle_t io                  ) -    : mStatus(NO_INIT) +    : mStatus(NO_INIT), mOpPackageName(opPackageName)  {      mStatus = set(type, uuid, priority, cbf, user, sessionId, io);  }  AudioEffect::AudioEffect(const char *typeStr, +                const String16& opPackageName,                  const char *uuidStr,                  int32_t priority,                  effect_callback_t cbf, @@ -62,7 +64,7 @@ AudioEffect::AudioEffect(const char *typeStr,                  int sessionId,                  audio_io_handle_t io                  ) -    : mStatus(NO_INIT) +    : mStatus(NO_INIT), mOpPackageName(opPackageName)  {      effect_uuid_t type;      effect_uuid_t *pType = NULL; @@ -128,7 +130,7 @@ status_t AudioEffect::set(const effect_uuid_t *type,      mIEffectClient = new EffectClient(this);      iEffect = audioFlinger->createEffect((effect_descriptor_t *)&mDescriptor, -            mIEffectClient, priority, io, mSessionId, &mStatus, &mId, &enabled); +            mIEffectClient, priority, io, mSessionId, mOpPackageName, &mStatus, &mId, &enabled);      if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {          ALOGE("set(): AudioFlinger could not create effect, status: %d", mStatus); diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 9f5c4c5..9a61977 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -65,8 +65,8 @@ status_t AudioRecord::getMinFrameCount(  // --------------------------------------------------------------------------- -AudioRecord::AudioRecord() -    : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), +AudioRecord::AudioRecord(const String16 &opPackageName) +    : mStatus(NO_INIT), mOpPackageName(opPackageName), mSessionId(AUDIO_SESSION_ALLOCATE),        mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),        mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)  { @@ -77,6 +77,7 @@ AudioRecord::AudioRecord(          uint32_t sampleRate,          audio_format_t format,          audio_channel_mask_t channelMask, +        const String16& opPackageName,          size_t frameCount,          callback_t cbf,          void* user, @@ -85,7 +86,9 @@ AudioRecord::AudioRecord(          transfer_type transferType,          audio_input_flags_t flags,          const audio_attributes_t* pAttributes) -    : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), +    : mStatus(NO_INIT), +      mOpPackageName(opPackageName), +      mSessionId(AUDIO_SESSION_ALLOCATE),        mPreviousPriority(ANDROID_PRIORITY_NORMAL),        mPreviousSchedulingGroup(SP_DEFAULT),        mProxy(NULL), @@ -136,9 +139,9 @@ status_t AudioRecord::set(          const audio_attributes_t* pAttributes)  {      ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, " -          "notificationFrames %u, sessionId %d, transferType %d, flags %#x", +          "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s",            inputSource, sampleRate, format, channelMask, frameCount, notificationFrames, -          sessionId, transferType, flags); +          sessionId, transferType, flags, String8(mOpPackageName).string());      switch (transferType) {      case TRANSFER_DEFAULT: @@ -235,7 +238,7 @@ status_t AudioRecord::set(      }      // create the IAudioRecord -    status_t status = openRecord_l(0 /*epoch*/); +    status_t status = openRecord_l(0 /*epoch*/, mOpPackageName);      if (status != NO_ERROR) {          if (mAudioRecordThread != 0) { @@ -435,7 +438,7 @@ audio_port_handle_t AudioRecord::getInputDevice() {  // -------------------------------------------------------------------------  // must be called with mLock held -status_t AudioRecord::openRecord_l(size_t epoch) +status_t AudioRecord::openRecord_l(size_t epoch, const String16& opPackageName)  {      const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();      if (audioFlinger == 0) { @@ -502,8 +505,10 @@ status_t AudioRecord::openRecord_l(size_t epoch)      sp<IMemory> iMem;           // for cblk      sp<IMemory> bufferMem;      sp<IAudioRecord> record = audioFlinger->openRecord(input, -                                                       mSampleRate, mFormat, +                                                       mSampleRate, +                                                       mFormat,                                                         mChannelMask, +                                                       opPackageName,                                                         &temp,                                                         &trackFlags,                                                         tid, @@ -1032,7 +1037,7 @@ status_t AudioRecord::restoreRecord_l(const char *from)      // It will also delete the strong references on previous IAudioRecord and IMemory      size_t position = mProxy->getPosition();      mNewPosition = position + mUpdatePeriod; -    status_t result = openRecord_l(position); +    status_t result = openRecord_l(position, mOpPackageName);      if (result == NO_ERROR) {          if (mActive) {              // callback thread or sync event hasn't changed diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index 38055f9..034a3d9 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -174,6 +174,7 @@ public:                                  uint32_t sampleRate,                                  audio_format_t format,                                  audio_channel_mask_t channelMask, +                                const String16& opPackageName,                                  size_t *pFrameCount,                                  track_flags_t *flags,                                  pid_t tid, @@ -190,6 +191,7 @@ public:          data.writeInt32(sampleRate);          data.writeInt32(format);          data.writeInt32(channelMask); +        data.writeString16(opPackageName)          size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;          data.writeInt64(frameCount);          track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT; @@ -702,6 +704,7 @@ public:                                      int32_t priority,                                      audio_io_handle_t output,                                      int sessionId, +                                    const String16& opPackageName,                                      status_t *status,                                      int *id,                                      int *enabled) @@ -722,6 +725,7 @@ public:          data.writeInt32(priority);          data.writeInt32((int32_t) output);          data.writeInt32(sessionId); +        data.writeString16(opPackageName);          status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply);          if (lStatus != NO_ERROR) { @@ -950,6 +954,7 @@ status_t BnAudioFlinger::onTransact(              uint32_t sampleRate = data.readInt32();              audio_format_t format = (audio_format_t) data.readInt32();              audio_channel_mask_t channelMask = data.readInt32(); +            const String16& opPackageName = data.readString16();              size_t frameCount = data.readInt64();              track_flags_t flags = (track_flags_t) data.readInt32();              pid_t tid = (pid_t) data.readInt32(); @@ -959,9 +964,8 @@ status_t BnAudioFlinger::onTransact(              sp<IMemory> buffers;              status_t status;              sp<IAudioRecord> record = openRecord(input, -                    sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId, -                    ¬ificationFrames, -                    cblk, buffers, &status); +                    sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid, +                    &sessionId, ¬ificationFrames, cblk, buffers, &status);              LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));              reply->writeInt64(frameCount);              reply->writeInt32(flags); @@ -1247,12 +1251,13 @@ status_t BnAudioFlinger::onTransact(              int32_t priority = data.readInt32();              audio_io_handle_t output = (audio_io_handle_t) data.readInt32();              int sessionId = data.readInt32(); +            const String16 opPackageName = data.readString16();              status_t status;              int id;              int enabled;              sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId, -                    &status, &id, &enabled); +                    opPackageName, &status, &id, &enabled);              reply->writeInt32(status);              reply->writeInt32(id);              reply->writeInt32(enabled); diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp index aa7b2e1..05f8670 100644 --- a/media/libmedia/IMediaPlayerService.cpp +++ b/media/libmedia/IMediaPlayerService.cpp @@ -78,10 +78,11 @@ public:          return interface_cast<IMediaPlayer>(reply.readStrongBinder());      } -    virtual sp<IMediaRecorder> createMediaRecorder() +    virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName)      {          Parcel data, reply;          data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); +        data.writeString16(opPackageName);          remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);          return interface_cast<IMediaRecorder>(reply.readStrongBinder());      } @@ -128,11 +129,12 @@ public:          return remote()->transact(PULL_BATTERY_DATA, data, reply);      } -    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client, -            const String8& iface) +    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName, +            const sp<IRemoteDisplayClient>& client, const String8& iface)      {          Parcel data, reply;          data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); +        data.writeString16(opPackageName);          data.writeStrongBinder(IInterface::asBinder(client));          data.writeString8(iface);          remote()->transact(LISTEN_FOR_REMOTE_DISPLAY, data, &reply); @@ -166,7 +168,8 @@ status_t BnMediaPlayerService::onTransact(          } break;          case CREATE_MEDIA_RECORDER: {              CHECK_INTERFACE(IMediaPlayerService, data, reply); -            sp<IMediaRecorder> recorder = createMediaRecorder(); +            const String16 opPackageName = data.readString16(); +            sp<IMediaRecorder> recorder = createMediaRecorder(opPackageName);              reply->writeStrongBinder(IInterface::asBinder(recorder));              return NO_ERROR;          } break; @@ -214,10 +217,11 @@ status_t BnMediaPlayerService::onTransact(          } break;          case LISTEN_FOR_REMOTE_DISPLAY: {              CHECK_INTERFACE(IMediaPlayerService, data, reply); +            const String16 opPackageName = data.readString16();              sp<IRemoteDisplayClient> client(                      interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));              String8 iface(data.readString8()); -            sp<IRemoteDisplay> display(listenForRemoteDisplay(client, iface)); +            sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface));              reply->writeStrongBinder(IInterface::asBinder(display));              return NO_ERROR;          } break; diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp index 9d69b6a..dc46038 100644 --- a/media/libmedia/Visualizer.cpp +++ b/media/libmedia/Visualizer.cpp @@ -34,11 +34,12 @@ namespace android {  // --------------------------------------------------------------------------- -Visualizer::Visualizer (int32_t priority, +Visualizer::Visualizer (const String16& opPackageName, +         int32_t priority,           effect_callback_t cbf,           void* user,           int sessionId) -    :   AudioEffect(SL_IID_VISUALIZATION, NULL, priority, cbf, user, sessionId), +    :   AudioEffect(SL_IID_VISUALIZATION, opPackageName, NULL, priority, cbf, user, sessionId),          mCaptureRate(CAPTURE_RATE_DEF),          mCaptureSize(CAPTURE_SIZE_DEF),          mSampleRate(44100000), diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp index a2d6e53..9470936 100644 --- a/media/libmedia/mediarecorder.cpp +++ b/media/libmedia/mediarecorder.cpp @@ -594,13 +594,13 @@ status_t MediaRecorder::release()      return INVALID_OPERATION;  } -MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL) +MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSource(NULL)  {      ALOGV("constructor");      const sp<IMediaPlayerService>& service(getMediaPlayerService());      if (service != NULL) { -        mMediaRecorder = service->createMediaRecorder(); +        mMediaRecorder = service->createMediaRecorder(opPackageName);      }      if (mMediaRecorder != NULL) {          mCurrentState = MEDIA_RECORDER_IDLE; diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 3bc763f..9567eff 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -307,10 +307,10 @@ MediaPlayerService::~MediaPlayerService()      ALOGV("MediaPlayerService destroyed");  } -sp<IMediaRecorder> MediaPlayerService::createMediaRecorder() +sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(const String16 &opPackageName)  {      pid_t pid = IPCThreadState::self()->getCallingPid(); -    sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid); +    sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid, opPackageName);      wp<MediaRecorderClient> w = recorder;      Mutex::Autolock lock(mLock);      mMediaRecorderClients.add(w); @@ -381,12 +381,13 @@ sp<IHDCP> MediaPlayerService::makeHDCP(bool createEncryptionModule) {  }  sp<IRemoteDisplay> MediaPlayerService::listenForRemoteDisplay( +        const String16 &opPackageName,          const sp<IRemoteDisplayClient>& client, const String8& iface) {      if (!checkPermission("android.permission.CONTROL_WIFI_DISPLAY")) {          return NULL;      } -    return new RemoteDisplay(client, iface.string()); +    return new RemoteDisplay(opPackageName, client, iface.string());  }  status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 6ddfe14..1a3ce92 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -188,7 +188,7 @@ public:      static  void                instantiate();      // IMediaPlayerService interface -    virtual sp<IMediaRecorder>  createMediaRecorder(); +    virtual sp<IMediaRecorder>  createMediaRecorder(const String16 &opPackageName);      void    removeMediaRecorderClient(wp<MediaRecorderClient> client);      virtual sp<IMediaMetadataRetriever> createMetadataRetriever(); @@ -200,8 +200,8 @@ public:      virtual sp<IDrm>            makeDrm();      virtual sp<IHDCP>           makeHDCP(bool createEncryptionModule); -    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client, -            const String8& iface); +    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName, +            const sp<IRemoteDisplayClient>& client, const String8& iface);      virtual status_t            dump(int fd, const Vector<String16>& args);              void                removeClient(wp<Client> client); diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp index 319ebb0..40e9d1c 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.cpp +++ b/media/libmediaplayerservice/MediaRecorderClient.cpp @@ -290,11 +290,12 @@ status_t MediaRecorderClient::release()      return NO_ERROR;  } -MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid) +MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid, +        const String16& opPackageName)  {      ALOGV("Client constructor");      mPid = pid; -    mRecorder = new StagefrightRecorder; +    mRecorder = new StagefrightRecorder(opPackageName);      mMediaPlayerService = service;  } diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h index b45344b..e03ec3f 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.h +++ b/media/libmediaplayerservice/MediaRecorderClient.h @@ -62,7 +62,8 @@ private:                             MediaRecorderClient(                                     const sp<MediaPlayerService>& service, -                                                               pid_t pid); +                                                               pid_t pid, +                                                               const String16& opPackageName);      virtual                ~MediaRecorderClient();      pid_t                  mPid; diff --git a/media/libmediaplayerservice/RemoteDisplay.cpp b/media/libmediaplayerservice/RemoteDisplay.cpp index eb959b4..0eb4b5d 100644 --- a/media/libmediaplayerservice/RemoteDisplay.cpp +++ b/media/libmediaplayerservice/RemoteDisplay.cpp @@ -26,13 +26,14 @@  namespace android {  RemoteDisplay::RemoteDisplay( +        const String16 &opPackageName,          const sp<IRemoteDisplayClient> &client,          const char *iface)      : mLooper(new ALooper),        mNetSession(new ANetworkSession) {      mLooper->setName("wfd_looper"); -    mSource = new WifiDisplaySource(mNetSession, client); +    mSource = new WifiDisplaySource(opPackageName, mNetSession, client);      mLooper->registerHandler(mSource);      mNetSession->start(); diff --git a/media/libmediaplayerservice/RemoteDisplay.h b/media/libmediaplayerservice/RemoteDisplay.h index 1a48981..d4573e9 100644 --- a/media/libmediaplayerservice/RemoteDisplay.h +++ b/media/libmediaplayerservice/RemoteDisplay.h @@ -33,6 +33,7 @@ struct WifiDisplaySource;  struct RemoteDisplay : public BnRemoteDisplay {      RemoteDisplay( +            const String16 &opPackageName,              const sp<IRemoteDisplayClient> &client,              const char *iface); diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 8a0b060..aa19a25 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -69,8 +69,9 @@ static void addBatteryData(uint32_t params) {  } -StagefrightRecorder::StagefrightRecorder() -    : mWriter(NULL), +StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName) +    : MediaRecorderBase(opPackageName), +      mWriter(NULL),        mOutputFd(-1),        mAudioSource(AUDIO_SOURCE_CNT),        mVideoSource(VIDEO_SOURCE_LIST_END), @@ -905,6 +906,7 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() {      sp<AudioSource> audioSource =          new AudioSource(                  mAudioSource, +                mOpPackageName,                  mSampleRate,                  mAudioChannels); diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index 8fa5bfa..1425f59 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -40,7 +40,7 @@ class SurfaceMediaSource;  struct ALooper;  struct StagefrightRecorder : public MediaRecorderBase { -    StagefrightRecorder(); +    StagefrightRecorder(const String16 &opPackageName);      virtual ~StagefrightRecorder();      virtual status_t init(); diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp index 804f131..e5a6a9b 100644 --- a/media/libstagefright/AudioSource.cpp +++ b/media/libstagefright/AudioSource.cpp @@ -50,7 +50,8 @@ static void AudioRecordCallbackFunction(int event, void *user, void *info) {  }  AudioSource::AudioSource( -        audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount) +        audio_source_t inputSource, const String16 &opPackageName, uint32_t sampleRate, +        uint32_t channelCount)      : mStarted(false),        mSampleRate(sampleRate),        mPrevSampleTimeUs(0), @@ -78,6 +79,7 @@ AudioSource::AudioSource(          mRecord = new AudioRecord(                      inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,                      audio_channel_in_mask_from_count(channelCount), +                    opPackageName,                      (size_t) (bufCount * frameCount),                      AudioRecordCallbackFunction,                      this, diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp index fd889f9..3860e9b 100644 --- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp +++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp @@ -19,6 +19,7 @@  #include <gtest/gtest.h>  #include <utils/String8.h> +#include <utils/String16.h>  #include <utils/Errors.h>  #include <fcntl.h>  #include <unistd.h> @@ -466,7 +467,7 @@ void SurfaceMediaSourceGLTest::oneBufferPassGL(int num) {  // Set up the MediaRecorder which runs in the same process as mediaserver  sp<MediaRecorder> SurfaceMediaSourceGLTest::setUpMediaRecorder(int fd, int videoSource,          int outputFormat, int videoEncoder, int width, int height, int fps) { -    sp<MediaRecorder> mr = new MediaRecorder(); +    sp<MediaRecorder> mr = new MediaRecorder(String16());      mr->setVideoSource(videoSource);      mr->setOutputFormat(outputFormat);      mr->setVideoEncoder(videoEncoder); diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index 5e2f0bf..ed5a404 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp +++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp @@ -345,12 +345,14 @@ bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {  ////////////////////////////////////////////////////////////////////////////////  WifiDisplaySource::PlaybackSession::PlaybackSession( +        const String16 &opPackageName,          const sp<ANetworkSession> &netSession,          const sp<AMessage> ¬ify,          const in_addr &interfaceAddr,          const sp<IHDCP> &hdcp,          const char *path) -    : mNetSession(netSession), +    : mOpPackageName(opPackageName), +      mNetSession(netSession),        mNotify(notify),        mInterfaceAddr(interfaceAddr),        mHDCP(hdcp), @@ -1069,6 +1071,7 @@ status_t WifiDisplaySource::PlaybackSession::addVideoSource(  status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {      sp<AudioSource> audioSource = new AudioSource(              AUDIO_SOURCE_REMOTE_SUBMIX, +            mOpPackageName,              48000 /* sampleRate */,              2 /* channelCount */); diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h index 4cd1a75..f6673df 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.h +++ b/media/libstagefright/wifi-display/source/PlaybackSession.h @@ -22,6 +22,8 @@  #include "VideoFormats.h"  #include "WifiDisplaySource.h" +#include <utils/String16.h> +  namespace android {  struct ABuffer; @@ -36,6 +38,7 @@ struct NuMediaExtractor;  // display.  struct WifiDisplaySource::PlaybackSession : public AHandler {      PlaybackSession( +            const String16 &opPackageName,              const sp<ANetworkSession> &netSession,              const sp<AMessage> ¬ify,              const struct in_addr &interfaceAddr, @@ -96,6 +99,8 @@ private:          kWhatPullExtractorSample,      }; +    String16 mOpPackageName; +      sp<ANetworkSession> mNetSession;      sp<AMessage> mNotify;      in_addr mInterfaceAddr; diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp index 332fe16..e26165e 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp @@ -50,10 +50,12 @@ const int64_t WifiDisplaySource::kPlaybackSessionTimeoutUs;  const AString WifiDisplaySource::sUserAgent = MakeUserAgent();  WifiDisplaySource::WifiDisplaySource( +        const String16 &opPackageName,          const sp<ANetworkSession> &netSession,          const sp<IRemoteDisplayClient> &client,          const char *path) -    : mState(INITIALIZED), +    : mOpPackageName(opPackageName), +      mState(INITIALIZED),        mNetSession(netSession),        mClient(client),        mSessionID(0), @@ -1245,7 +1247,7 @@ status_t WifiDisplaySource::onSetupRequest(      sp<PlaybackSession> playbackSession =          new PlaybackSession( -                mNetSession, notify, mInterfaceAddr, mHDCP, mMediaPath.c_str()); +                mOpPackageName, mNetSession, notify, mInterfaceAddr, mHDCP, mMediaPath.c_str());      looper()->registerHandler(playbackSession); diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h index c417cf5..c25a675 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h @@ -25,6 +25,8 @@  #include <netinet/in.h> +#include <utils/String16.h> +  namespace android {  struct AReplyToken; @@ -38,6 +40,7 @@ struct WifiDisplaySource : public AHandler {      static const unsigned kWifiDisplayDefaultPort = 7236;      WifiDisplaySource( +            const String16 &opPackageName,              const sp<ANetworkSession> &netSession,              const sp<IRemoteDisplayClient> &client,              const char *path = NULL); @@ -114,6 +117,8 @@ private:      static const AString sUserAgent; +    String16 mOpPackageName; +      State mState;      VideoFormats mSupportedSourceVideoFormats;      sp<ANetworkSession> mNetSession; diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 5002099..48f7514 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1416,6 +1416,7 @@ sp<IAudioRecord> AudioFlinger::openRecord(          uint32_t sampleRate,          audio_format_t format,          audio_channel_mask_t channelMask, +        const String16& opPackageName,          size_t *frameCount,          IAudioFlinger::track_flags_t *flags,          pid_t tid, @@ -1435,7 +1436,7 @@ sp<IAudioRecord> AudioFlinger::openRecord(      buffers.clear();      // check calling permissions -    if (!recordingAllowed()) { +    if (!recordingAllowed(opPackageName)) {          ALOGE("openRecord() permission denied: recording not allowed");          lStatus = PERMISSION_DENIED;          goto Exit; @@ -2447,6 +2448,7 @@ sp<IEffect> AudioFlinger::createEffect(          int32_t priority,          audio_io_handle_t io,          int sessionId, +        const String16& opPackageName,          status_t *status,          int *id,          int *enabled) @@ -2543,7 +2545,7 @@ sp<IEffect> AudioFlinger::createEffect(          // check recording permission for visualizer          if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) && -            !recordingAllowed()) { +            !recordingAllowed(opPackageName)) {              lStatus = PERMISSION_DENIED;              goto Exit;          } diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index e1ddcbc..3c4517f 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -120,6 +120,7 @@ public:                                  uint32_t sampleRate,                                  audio_format_t format,                                  audio_channel_mask_t channelMask, +                                const String16& opPackageName,                                  size_t *pFrameCount,                                  IAudioFlinger::track_flags_t *flags,                                  pid_t tid, @@ -216,6 +217,7 @@ public:                          int32_t priority,                          audio_io_handle_t io,                          int sessionId, +                        const String16& opPackageName,                          status_t *status /*non-NULL*/,                          int *id,                          int *enabled); diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp index 8246fef..0a718fb 100644 --- a/services/audioflinger/ServiceUtilities.cpp +++ b/services/audioflinger/ServiceUtilities.cpp @@ -14,38 +14,97 @@   * limitations under the License.   */ +#include <binder/AppOpsManager.h>  #include <binder/IPCThreadState.h>  #include <binder/IServiceManager.h>  #include <binder/PermissionCache.h>  #include "ServiceUtilities.h" +/* When performing permission checks we do not use permission cache for + * runtime permissions (protection level dangerous) as they may change at + * runtime. All other permissions (protection level normal and dangerous) + * can be cached as they never change. Of course all permission checked + * here are platform defined. + */ +  namespace android {  // Not valid until initialized by AudioFlinger constructor.  It would have to be  // re-initialized if the process containing AudioFlinger service forks (which it doesn't).  pid_t getpid_cached; -bool recordingAllowed() { +bool recordingAllowed(const String16& opPackageName) { +    // Note: We are getting the UID from the calling IPC thread state because all +    // clients that perform recording create AudioRecord in their own processes +    // and the system does not create AudioRecord objects on behalf of apps. This +    // differs from playback where in some situations the system recreates AudioTrack +    // instances associated with a client's MediaPlayer on behalf of this client. +    // In the latter case we have to store the client UID and pass in along for +    // security checks. +      if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;      static const String16 sRecordAudio("android.permission.RECORD_AUDIO"); -    // don't use PermissionCache; this is not a system permission -    bool ok = checkCallingPermission(sRecordAudio); -    if (!ok) ALOGE("Request requires android.permission.RECORD_AUDIO"); -    return ok; + +    // IMPORTANT: Don't use PermissionCache - a runtime permission and may change. +    const bool ok = checkCallingPermission(sRecordAudio); +    if (!ok) { +        ALOGE("Request requires android.permission.RECORD_AUDIO"); +        return false; +    } + +    const uid_t uid = IPCThreadState::self()->getCallingUid(); +    String16 checkedOpPackageName = opPackageName; + +    // In some cases the calling code has no access to the package it runs under. +    // For example, code using the wilhelm framework's OpenSL-ES APIs. In this +    // case we will get the packages for the calling UID and pick the first one +    // for attributing the app op. This will work correctly for runtime permissions +    // as for legacy apps we will toggle the app op for all packages in the UID. +    // The caveat is that the operation may be attributed to the wrong package and +    // stats based on app ops may be slightly off. +    if (checkedOpPackageName.size() <= 0) { +        sp<IServiceManager> sm = defaultServiceManager(); +        sp<IBinder> binder = sm->getService(String16("permission")); +        if (binder == 0) { +            ALOGE("Cannot get permission service"); +            return false; +        } + +        sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder); +        Vector<String16> packages; + +        permCtrl->getPackagesForUid(uid, packages); + +        if (packages.isEmpty()) { +            ALOGE("No packages for calling UID"); +            return false; +        } +        checkedOpPackageName = packages[0]; +    } + +    AppOpsManager appOps; +    if (appOps.noteOp(AppOpsManager::OP_RECORD_AUDIO, uid, opPackageName) +            != AppOpsManager::MODE_ALLOWED) { +        ALOGE("Request denied by app op OP_RECORD_AUDIO"); +        return false; +    } + +    return true;  }  bool captureAudioOutputAllowed() {      if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;      static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT"); -    // don't use PermissionCache; this is not a system permission -    bool ok = checkCallingPermission(sCaptureAudioOutput); +    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. +    bool ok = PermissionCache::checkCallingPermission(sCaptureAudioOutput);      if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");      return ok;  }  bool captureHotwordAllowed() {      static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD"); -    bool ok = checkCallingPermission(sCaptureHotwordAllowed); +    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. +    bool ok = PermissionCache::checkCallingPermission(sCaptureHotwordAllowed);      if (!ok) ALOGE("android.permission.CAPTURE_AUDIO_HOTWORD");      return ok;  } @@ -53,15 +112,16 @@ bool captureHotwordAllowed() {  bool settingsAllowed() {      if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;      static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS"); -    // don't use PermissionCache; this is not a system permission -    bool ok = checkCallingPermission(sAudioSettings); +    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. +    bool ok = PermissionCache::checkCallingPermission(sAudioSettings);      if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");      return ok;  }  bool modifyAudioRoutingAllowed() {      static const String16 sModifyAudioRoutingAllowed("android.permission.MODIFY_AUDIO_ROUTING"); -    bool ok = checkCallingPermission(sModifyAudioRoutingAllowed); +    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. +    bool ok = PermissionCache::checkCallingPermission(sModifyAudioRoutingAllowed);      if (!ok) ALOGE("android.permission.MODIFY_AUDIO_ROUTING");      return ok;  } @@ -69,7 +129,7 @@ bool modifyAudioRoutingAllowed() {  bool dumpAllowed() {      // don't optimize for same pid, since mediaserver never dumps itself      static const String16 sDump("android.permission.DUMP"); -    // OK to use PermissionCache; this is a system permission +    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.      bool ok = PermissionCache::checkCallingPermission(sDump);      // convention is for caller to dump an error message to fd instead of logging here      //if (!ok) ALOGE("Request requires android.permission.DUMP"); diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h index df6f6f4..fba6dce 100644 --- a/services/audioflinger/ServiceUtilities.h +++ b/services/audioflinger/ServiceUtilities.h @@ -20,11 +20,10 @@ namespace android {  extern pid_t getpid_cached; -bool recordingAllowed(); +bool recordingAllowed(const String16& opPackageName);  bool captureAudioOutputAllowed();  bool captureHotwordAllowed();  bool settingsAllowed();  bool modifyAudioRoutingAllowed();  bool dumpAllowed(); -  } diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index e6ace20..282ddeb 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -109,8 +109,8 @@ status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,          Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;          for (size_t i = 0; i < effects.size(); i++) {              EffectDesc *effect = effects[i]; -            sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, -                                                 audioSession, input); +            sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, -1, 0, +                                                 0, audioSession, input);              status_t status = fx->initCheck();              if (status != NO_ERROR && status != ALREADY_EXISTS) {                  ALOGW("addInputEffects(): failed to create Fx %s on source %d", @@ -254,7 +254,7 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,          Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;          for (size_t i = 0; i < effects.size(); i++) {              EffectDesc *effect = effects[i]; -            sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, 0, 0, 0, +            sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, 0, 0, 0,                                                   audioSession, output);              status_t status = fx->initCheck();              if (status != NO_ERROR && status != ALREADY_EXISTS) {  | 
