Merge cherrypicks of [4583929, 4582754, 4582755, 4582756, 4583930, 4583931, 4583932, 4586307, 4586953, 4582585, 4586964, 4586965, 4586984, 4586985, 4586986, 4586987, 4586966, 4582586, 4582885, 4586531, 4586532, 4586533, 4586535, 4586536, 4586537, 4586538, 4586539, 4586540, 4586541, 4586542, 4586890, 4586891, 4586892, 4586893, 4586894, 4586895, 4586896, 4586897, 4586898, 4586899, 4586900, 4586901, 4586902, 4586903, 4587104, 4587105, 4587106, 4586988, 4583933, 4583934, 4583935, 4586989, 4586990, 4587136, 4587138, 4586991, 4586308, 4586967, 4587069, 4587070, 4582886, 4582887, 4587164, 4582888, 4587027, 4587028, 4587029, 4587030, 4582587, 4582588, 4582589, 4582590, 4582591, 4582592, 4582593, 4582594, 4582595, 4582596, 4582597, 4582598, 4582599, 4582600, 4582601, 4582602, 4582603, 4587244, 4587245, 4587246, 4587247, 4587248, 4587249, 4587250, 4587251, 4587252, 4582760, 4583936, 4582761, 4586992, 4587229, 4587230, 4587231, 4587253, 4586968] into sparse-4732991-L37700000192334752

Change-Id: I8a265015723a8b178a911ef2054eed777aee14f5
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 1fdc6e1..5dd2563 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -240,11 +240,12 @@
     Mutex::Autolock autoLock(mLock);
 
     int32_t seqNum = mHeapSeqNum++;
+
     int fd = heap->getHeapID();
     nativeHandle->data[0] = fd;
     auto hidlHandle = hidl_handle(nativeHandle);
     auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
-    mHeapBases.add(seqNum, mNextBufferId);
+    mHeapBases.add(seqNum, HeapBase(mNextBufferId, heap->getSize()));
     Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
     ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
     return seqNum;
@@ -269,10 +270,26 @@
         return UNEXPECTED_NULL;
     }
 
-    // memory must be in the declared heap
-    CHECK(mHeapBases.indexOfKey(seqNum) >= 0);
+    // memory must be in one of the heaps that have been set
+    if (mHeapBases.indexOfKey(seqNum) < 0) {
+        return UNKNOWN_ERROR;
+    }
 
-    buffer->bufferId = mHeapBases.valueFor(seqNum);
+    // heap must be the same size as the one that was set in setHeapBase
+    if (mHeapBases.valueFor(seqNum).getSize() != heap->getSize()) {
+        android_errorWriteLog(0x534e4554, "76221123");
+        return UNKNOWN_ERROR;
+     }
+
+    // memory must be within the address space of the heap
+    if (memory->pointer() != static_cast<uint8_t *>(heap->getBase()) + memory->offset()  ||
+            heap->getSize() < memory->offset() + memory->size() ||
+            SIZE_MAX - memory->offset() < memory->size()) {
+        android_errorWriteLog(0x534e4554, "76221123");
+        return UNKNOWN_ERROR;
+    }
+
+    buffer->bufferId = mHeapBases.valueFor(seqNum).getBufferId();
     buffer->offset = offset >= 0 ? offset : 0;
     buffer->size = size;
     return OK;
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index d838975..f071a02 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -940,7 +940,7 @@
             audio_output_flags_t flags =
                     static_cast <audio_output_flags_t>(data.readInt32());
             bool hasOffloadInfo = data.readInt32() != 0;
-            audio_offload_info_t offloadInfo;
+            audio_offload_info_t offloadInfo = {};
             if (hasOffloadInfo) {
                 data.read(&offloadInfo, sizeof(audio_offload_info_t));
             }
@@ -956,7 +956,7 @@
 
         case GET_OUTPUT_FOR_ATTR: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_attributes_t attr;
+            audio_attributes_t attr = {};
             bool hasAttributes = data.readInt32() != 0;
             if (hasAttributes) {
                 data.read(&attr, sizeof(audio_attributes_t));
@@ -1024,7 +1024,7 @@
 
         case GET_INPUT_FOR_ATTR: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_attributes_t attr;
+            audio_attributes_t attr = {};
             data.read(&attr, sizeof(audio_attributes_t));
             sanetizeAudioAttributes(&attr);
             audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
@@ -1125,8 +1125,11 @@
 
         case GET_OUTPUT_FOR_EFFECT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            effect_descriptor_t desc;
-            data.read(&desc, sizeof(effect_descriptor_t));
+            effect_descriptor_t desc = {};
+            if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
+                android_errorWriteLog(0x534e4554, "73126106");
+            }
+            (void)sanitizeEffectDescriptor(&desc);
             audio_io_handle_t output = getOutputForEffect(&desc);
             reply->writeInt32(static_cast <int>(output));
             return NO_ERROR;
@@ -1134,8 +1137,11 @@
 
         case REGISTER_EFFECT: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            effect_descriptor_t desc;
-            data.read(&desc, sizeof(effect_descriptor_t));
+            effect_descriptor_t desc = {};
+            if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
+                android_errorWriteLog(0x534e4554, "73126106");
+            }
+            (void)sanitizeEffectDescriptor(&desc);
             audio_io_handle_t io = data.readInt32();
             uint32_t strategy = data.readInt32();
             audio_session_t session = (audio_session_t) data.readInt32();
@@ -1194,7 +1200,7 @@
                 count = AudioEffect::kMaxPreProcessing;
             }
             uint32_t retCount = count;
-            effect_descriptor_t *descriptors = new effect_descriptor_t[count];
+            effect_descriptor_t *descriptors = new effect_descriptor_t[count]{};
             status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount);
             reply->writeInt32(status);
             if (status != NO_ERROR && status != NO_MEMORY) {
@@ -1213,7 +1219,7 @@
 
         case IS_OFFLOAD_SUPPORTED: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_offload_info_t info;
+            audio_offload_info_t info = {};
             data.read(&info, sizeof(audio_offload_info_t));
             bool isSupported = isOffloadSupported(info);
             reply->writeInt32(isSupported);
@@ -1268,7 +1274,7 @@
 
         case CREATE_AUDIO_PATCH: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            struct audio_patch patch;
+            struct audio_patch patch = {};
             data.read(&patch, sizeof(struct audio_patch));
             audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
             if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
@@ -1284,7 +1290,7 @@
 
         case RELEASE_AUDIO_PATCH: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_patch_handle_t handle;
+            audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
             data.read(&handle, sizeof(audio_patch_handle_t));
             status_t status = releaseAudioPatch(handle);
             reply->writeInt32(status);
@@ -1323,8 +1329,9 @@
 
         case SET_AUDIO_PORT_CONFIG: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            struct audio_port_config config;
+            struct audio_port_config config = {};
             data.read(&config, sizeof(struct audio_port_config));
+            (void)sanitizeAudioPortConfig(&config);
             status_t status = setAudioPortConfig(&config);
             reply->writeInt32(status);
             return NO_ERROR;
@@ -1398,9 +1405,10 @@
 
         case START_AUDIO_SOURCE: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            struct audio_port_config source;
+            struct audio_port_config source = {};
             data.read(&source, sizeof(struct audio_port_config));
-            audio_attributes_t attributes;
+            (void)sanitizeAudioPortConfig(&source);
+            audio_attributes_t attributes = {};
             data.read(&attributes, sizeof(audio_attributes_t));
             sanetizeAudioAttributes(&attributes);
             audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
@@ -1453,6 +1461,14 @@
     }
 }
 
+/** returns true if string overflow was prevented by zero termination */
+template <size_t size>
+static bool preventStringOverflow(char (&s)[size]) {
+    if (strnlen(s, size) < size) return false;
+    s[size - 1] = '\0';
+    return true;
+}
+
 void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
 {
     const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
@@ -1462,6 +1478,27 @@
     attr->tags[tagsMaxSize - 1] = '\0';
 }
 
+/** returns BAD_VALUE if sanitization was required. */
+status_t BnAudioPolicyService::sanitizeEffectDescriptor(effect_descriptor_t* desc)
+{
+    if (preventStringOverflow(desc->name)
+        | /* always */ preventStringOverflow(desc->implementor)) {
+        android_errorWriteLog(0x534e4554, "73126106"); // SafetyNet logging
+        return BAD_VALUE;
+    }
+    return NO_ERROR;
+}
+
+/** returns BAD_VALUE if sanitization was required. */
+status_t BnAudioPolicyService::sanitizeAudioPortConfig(struct audio_port_config* config)
+{
+    if (config->type == AUDIO_PORT_TYPE_DEVICE &&
+        preventStringOverflow(config->ext.device.address)) {
+        return BAD_VALUE;
+    }
+    return NO_ERROR;
+}
+
 // ----------------------------------------------------------------------------
 
 } // namespace android
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 60ba4ba..eec3e88 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -185,6 +185,8 @@
                                     uint32_t flags = 0);
 private:
     void sanetizeAudioAttributes(audio_attributes_t* attr);
+    status_t sanitizeEffectDescriptor(effect_descriptor_t* desc);
+    status_t sanitizeAudioPortConfig(struct audio_port_config* config);
 };
 
 // ----------------------------------------------------------------------------
diff --git a/media/libmedia/include/media/CryptoHal.h b/media/libmedia/include/media/CryptoHal.h
index a5d8b43..80e181e 100644
--- a/media/libmedia/include/media/CryptoHal.h
+++ b/media/libmedia/include/media/CryptoHal.h
@@ -79,7 +79,20 @@
      */
     status_t mInitCheck;
 
-    KeyedVector<int32_t, uint32_t> mHeapBases;
+    struct HeapBase {
+        HeapBase() : mBufferId(0), mSize(0) {}
+        HeapBase(uint32_t bufferId, size_t size) :
+            mBufferId(bufferId), mSize(size) {}
+
+        uint32_t getBufferId() const {return mBufferId;}
+        size_t getSize() const {return mSize;}
+
+    private:
+        uint32_t mBufferId;
+        size_t mSize;
+    };
+
+    KeyedVector<int32_t, HeapBase> mHeapBases;
     uint32_t mNextBufferId;
     int32_t mHeapSeqNum;
 
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index cd0a003..686c059 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -126,8 +126,7 @@
 
 sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
         player_type playerType,
-        const wp<IMediaPlayer> &client,
-        notify_callback_f notifyFunc,
+        const sp<MediaPlayerBase::Listener> &listener,
         pid_t pid) {
     sp<MediaPlayerBase> p;
     IFactory* factory;
@@ -152,7 +151,7 @@
 
     init_result = p->initCheck();
     if (init_result == NO_ERROR) {
-        p->setNotifyCallback(client, notifyFunc);
+        p->setNotifyCallback(listener);
     } else {
         ALOGE("Failed to create player object of type %d, initCheck failed"
               " (res = %d)", playerType, init_result);
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.h b/media/libmediaplayerservice/MediaPlayerFactory.h
index 6aedeb2..e88700c 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.h
+++ b/media/libmediaplayerservice/MediaPlayerFactory.h
@@ -65,8 +65,7 @@
                                      const sp<DataSource> &source);
 
     static sp<MediaPlayerBase> createPlayer(player_type playerType,
-                                            const wp<IMediaPlayer> &client,
-                                            notify_callback_f notifyFunc,
+                                            const sp<MediaPlayerBase::Listener> &listener,
                                             pid_t pid);
 
     static void registerBuiltinFactories();
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 6e17b8d..3445469 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -590,10 +590,11 @@
     mUid = uid;
     mRetransmitEndpointValid = false;
     mAudioAttributes = NULL;
+    mListener = new Listener(this);
 
 #if CALLBACK_ANTAGONIZER
     ALOGD("create Antagonizer");
-    mAntagonizer = new Antagonizer(notify, this);
+    mAntagonizer = new Antagonizer(mListener);
 #endif
 }
 
@@ -627,7 +628,7 @@
     // and reset the player. We assume the player will serialize
     // access to itself if necessary.
     if (p != 0) {
-        p->setNotifyCallback(0, 0);
+        p->setNotifyCallback(0);
 #if CALLBACK_ANTAGONIZER
         ALOGD("kill Antagonizer");
         mAntagonizer->kill();
@@ -652,7 +653,7 @@
         p.clear();
     }
     if (p == NULL) {
-        p = MediaPlayerFactory::createPlayer(playerType, this, notify, mPid);
+        p = MediaPlayerFactory::createPlayer(playerType, mListener, mPid);
     }
 
     if (p != NULL) {
@@ -1430,25 +1431,19 @@
 }
 
 void MediaPlayerService::Client::notify(
-        const wp<IMediaPlayer> &listener, int msg, int ext1, int ext2, const Parcel *obj)
+        int msg, int ext1, int ext2, const Parcel *obj)
 {
-    sp<IMediaPlayer> spListener = listener.promote();
-    if (spListener == NULL) {
-        return;
-    }
-    Client* client = static_cast<Client*>(spListener.get());
-
     sp<IMediaPlayerClient> c;
     sp<Client> nextClient;
     status_t errStartNext = NO_ERROR;
     {
-        Mutex::Autolock l(client->mLock);
-        c = client->mClient;
-        if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) {
-            nextClient = client->mNextClient;
+        Mutex::Autolock l(mLock);
+        c = mClient;
+        if (msg == MEDIA_PLAYBACK_COMPLETE && mNextClient != NULL) {
+            nextClient = mNextClient;
 
-            if (client->mAudioOutput != NULL)
-                client->mAudioOutput->switchToNextOutput();
+            if (mAudioOutput != NULL)
+                mAudioOutput->switchToNextOutput();
 
             errStartNext = nextClient->start();
         }
@@ -1474,17 +1469,17 @@
         MEDIA_INFO_METADATA_UPDATE == ext1) {
         const media::Metadata::Type metadata_type = ext2;
 
-        if(client->shouldDropMetadata(metadata_type)) {
+        if(shouldDropMetadata(metadata_type)) {
             return;
         }
 
         // Update the list of metadata that have changed. getMetadata
         // also access mMetadataUpdated and clears it.
-        client->addNewMetadataUpdate(metadata_type);
+        addNewMetadataUpdate(metadata_type);
     }
 
     if (c != NULL) {
-        ALOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, spListener.get(), msg, ext1, ext2);
+        ALOGV("[%d] notify (%d, %d, %d)", mConnId, msg, ext1, ext2);
         c->notify(msg, ext1, ext2, obj);
     }
 }
@@ -1542,8 +1537,8 @@
 #if CALLBACK_ANTAGONIZER
 const int Antagonizer::interval = 10000; // 10 msecs
 
-Antagonizer::Antagonizer(notify_callback_f cb, const wp<IMediaPlayer> &client) :
-    mExit(false), mActive(false), mClient(client), mCb(cb)
+Antagonizer::Antagonizer(const sp<MediaPlayerBase::Listener> &listener) :
+    mExit(false), mActive(false), mListener(listener)
 {
     createThread(callbackThread, this);
 }
@@ -1563,7 +1558,7 @@
     while (!p->mExit) {
         if (p->mActive) {
             ALOGV("send event");
-            p->mCb(p->mClient, 0, 0, 0);
+            p->mListener->notify(0, 0, 0, 0);
         }
         usleep(interval);
     }
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index f043f32..34e5e2a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -51,7 +51,7 @@
 #if CALLBACK_ANTAGONIZER
 class Antagonizer {
 public:
-    Antagonizer(notify_callback_f cb, const wp<IMediaPlayer> &client);
+    Antagonizer(const sp<MediaPlayerBase::Listener> &listener);
     void start() { mActive = true; }
     void stop() { mActive = false; }
     void kill();
@@ -59,12 +59,11 @@
     static const int interval;
     Antagonizer();
     static int callbackThread(void* cookie);
-    Mutex               mLock;
-    Condition           mCondition;
-    bool                mExit;
-    bool                mActive;
-    wp<IMediaPlayer>    mClient;
-    notify_callback_f   mCb;
+    Mutex                         mLock;
+    Condition                     mCondition;
+    bool                          mExit;
+    bool                          mActive;
+    sp<MediaPlayerBase::Listener> mListener;
 };
 #endif
 
@@ -215,7 +214,6 @@
 
     }; // AudioOutput
 
-
 public:
     static  void                instantiate();
 
@@ -365,8 +363,7 @@
         status_t                setDataSource_post(const sp<MediaPlayerBase>& p,
                                                    status_t status);
 
-        static  void            notify(const wp<IMediaPlayer> &cookie, int msg,
-                                       int ext1, int ext2, const Parcel *obj);
+                void            notify(int msg, int ext1, int ext2, const Parcel *obj);
 
                 pid_t           pid() const { return mPid; }
         virtual status_t        dump(int fd, const Vector<String16>& args);
@@ -437,23 +434,38 @@
 
         status_t setAudioAttributes_l(const Parcel &request);
 
-        mutable     Mutex                       mLock;
-                    sp<MediaPlayerBase>         mPlayer;
-                    sp<MediaPlayerService>      mService;
-                    sp<IMediaPlayerClient>      mClient;
-                    sp<AudioOutput>             mAudioOutput;
-                    pid_t                       mPid;
-                    status_t                    mStatus;
-                    bool                        mLoop;
-                    int32_t                     mConnId;
-                    audio_session_t             mAudioSessionId;
-                    audio_attributes_t *        mAudioAttributes;
-                    uid_t                       mUid;
-                    sp<ANativeWindow>           mConnectedWindow;
-                    sp<IBinder>                 mConnectedWindowBinder;
-                    struct sockaddr_in          mRetransmitEndpoint;
-                    bool                        mRetransmitEndpointValid;
-                    sp<Client>                  mNextClient;
+        class Listener : public MediaPlayerBase::Listener {
+        public:
+            Listener(const wp<Client> &client) : mClient(client) {}
+            virtual ~Listener() {}
+            virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
+                sp<Client> client = mClient.promote();
+                if (client != NULL) {
+                    client->notify(msg, ext1, ext2, obj);
+                }
+            }
+        private:
+            wp<Client> mClient;
+        };
+
+        mutable     Mutex                         mLock;
+                    sp<MediaPlayerBase>           mPlayer;
+                    sp<MediaPlayerService>        mService;
+                    sp<IMediaPlayerClient>        mClient;
+                    sp<AudioOutput>               mAudioOutput;
+                    pid_t                         mPid;
+                    status_t                      mStatus;
+                    bool                          mLoop;
+                    int32_t                       mConnId;
+                    audio_session_t               mAudioSessionId;
+                    audio_attributes_t *          mAudioAttributes;
+                    uid_t                         mUid;
+                    sp<ANativeWindow>             mConnectedWindow;
+                    sp<IBinder>                   mConnectedWindowBinder;
+                    struct sockaddr_in            mRetransmitEndpoint;
+                    bool                          mRetransmitEndpointValid;
+                    sp<Client>                    mNextClient;
+                    sp<MediaPlayerBase::Listener> mListener;
 
         // Metadata filters.
         media::Metadata::Filter mMetadataAllow;  // protected by mLock
@@ -468,7 +480,7 @@
         sp<ServiceDeathNotifier> mExtractorDeathListener;
         sp<ServiceDeathNotifier> mCodecDeathListener;
 #if CALLBACK_ANTAGONIZER
-                    Antagonizer*                mAntagonizer;
+                    Antagonizer*                  mAntagonizer;
 #endif
     }; // Client
 
diff --git a/media/libmediaplayerservice/include/MediaPlayerInterface.h b/media/libmediaplayerservice/include/MediaPlayerInterface.h
index 34f1fe4..6d02cce 100644
--- a/media/libmediaplayerservice/include/MediaPlayerInterface.h
+++ b/media/libmediaplayerservice/include/MediaPlayerInterface.h
@@ -66,14 +66,17 @@
 // duration below which we do not allow deep audio buffering
 #define AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US 5000000
 
-// callback mechanism for passing messages to MediaPlayer object
-typedef void (*notify_callback_f)(const wp<IMediaPlayer> &listener,
-        int msg, int ext1, int ext2, const Parcel *obj);
-
 // abstract base class - use MediaPlayerInterface
 class MediaPlayerBase : public RefBase
 {
 public:
+    // callback mechanism for passing messages to MediaPlayer object
+    class Listener : public RefBase {
+    public:
+        virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
+        virtual ~Listener() {}
+    };
+
     // AudioSink: abstraction layer for audio output
     class AudioSink : public RefBase {
     public:
@@ -152,7 +155,7 @@
         virtual sp<VolumeShaper::State> getVolumeShaperState(int id);
     };
 
-                        MediaPlayerBase() : mClient(0), mNotify(0) {}
+                        MediaPlayerBase() {}
     virtual             ~MediaPlayerBase() {}
     virtual status_t    initCheck() = 0;
     virtual bool        hardwareOutput() = 0;
@@ -263,22 +266,22 @@
     };
 
     void        setNotifyCallback(
-            const wp<IMediaPlayer> &client, notify_callback_f notifyFunc) {
+            const sp<Listener> &listener) {
         Mutex::Autolock autoLock(mNotifyLock);
-        mClient = client; mNotify = notifyFunc;
+        mListener = listener;
     }
 
     void        sendEvent(int msg, int ext1=0, int ext2=0,
                           const Parcel *obj=NULL) {
-        notify_callback_f notifyCB;
-        wp<IMediaPlayer> client;
+        sp<Listener> listener;
         {
             Mutex::Autolock autoLock(mNotifyLock);
-            notifyCB = mNotify;
-            client = mClient;
+            listener = mListener;
         }
 
-        if (notifyCB) notifyCB(client, msg, ext1, ext2, obj);
+        if (listener != NULL) {
+            listener->notify(msg, ext1, ext2, obj);
+        }
     }
 
     virtual status_t dump(int /* fd */, const Vector<String16>& /* args */) const {
@@ -297,8 +300,7 @@
     friend class MediaPlayerService;
 
     Mutex               mNotifyLock;
-    wp<IMediaPlayer>    mClient;
-    notify_callback_f   mNotify;
+    sp<Listener>        mListener;
 };
 
 // Implement this class for media players that use the AudioFlinger software mixer
diff --git a/media/libstagefright/ItemTable.cpp b/media/libstagefright/ItemTable.cpp
index f9ee1c4..f589f4f 100644
--- a/media/libstagefright/ItemTable.cpp
+++ b/media/libstagefright/ItemTable.cpp
@@ -1335,7 +1335,8 @@
         ALOGV("adding %s: itemId %d", image.isGrid() ? "grid" : "image", info.itemId);
 
         if (image.isGrid()) {
-            if (size > 12) {
+            // ImageGrid struct is at least 8-byte, at most 12-byte (if flags&1)
+            if (size < 8 || size > 12) {
                 return ERROR_MALFORMED;
             }
             uint8_t buf[12];
diff --git a/media/libstagefright/VideoFrameScheduler.cpp b/media/libstagefright/VideoFrameScheduler.cpp
index 03226c7..6819bba 100644
--- a/media/libstagefright/VideoFrameScheduler.cpp
+++ b/media/libstagefright/VideoFrameScheduler.cpp
@@ -129,6 +129,11 @@
         numSamplesToUse = mNumSamples;
     }
 
+    if ((period >> kPrecision) == 0 ) {
+        ALOGW("Period is 0, or after including precision is 0 - would cause div0, returning");
+        return false;
+    }
+
     int64_t sumX = 0;
     int64_t sumXX = 0;
     int64_t sumXY = 0;
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 58d8b13..a0bfd06 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -328,12 +328,25 @@
 }
 
 void ID3::removeUnsynchronization() {
-    for (size_t i = 0; i + 1 < mSize; ++i) {
-        if (mData[i] == 0xff && mData[i + 1] == 0x00) {
-            memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2);
-            --mSize;
+
+    // This file has "unsynchronization", so we have to replace occurrences
+    // of 0xff 0x00 with just 0xff in order to get the real data.
+
+    size_t writeOffset = 1;
+    for (size_t readOffset = 1; readOffset < mSize; ++readOffset) {
+        if (mData[readOffset - 1] == 0xff && mData[readOffset] == 0x00) {
+            continue;
         }
+        // Only move data if there's actually something to move.
+        // This handles the special case of the data being only [0xff, 0x00]
+        // which should be converted to just 0xff if unsynchronization is on.
+        mData[writeOffset++] = mData[readOffset];
     }
+
+    if (writeOffset < mSize) {
+        mSize = writeOffset;
+    }
+
 }
 
 static void WriteSyncsafeInteger(uint8_t *dst, size_t x) {
@@ -593,6 +606,9 @@
         // UCS-2
         // API wants number of characters, not number of bytes...
         int len = n / 2;
+        if (len == 0) {
+            return;
+        }
         const char16_t *framedata = (const char16_t *) (frameData + 1);
         char16_t *framedatacopy = NULL;
         if (*framedata == 0xfffe) {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 015a148..a9fbd71 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -686,6 +686,7 @@
 
     CLOG_CONFIG(setPortMode, "%s(%d), port %d", asString(mode), mode, portIndex);
 
+    status_t err = OK;
     switch (mode) {
     case IOMX::kPortModeDynamicANWBuffer:
     {
@@ -694,17 +695,19 @@
                 CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
                         "not setting port mode to %s(%d) on output",
                         asString(mode), mode);
-                return StatusFromOMXError(OMX_ErrorUnsupportedIndex);
+                err = StatusFromOMXError(OMX_ErrorUnsupportedIndex);
+                break;
             }
 
-            status_t err = enableNativeBuffers_l(
+            err = enableNativeBuffers_l(
                     portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
             if (err != OK) {
-                return err;
+                break;
             }
         }
         (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
-        return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
+        err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
+        break;
     }
 
     case IOMX::kPortModeDynamicNativeHandle:
@@ -712,13 +715,15 @@
         if (portIndex != kPortIndexInput) {
             CLOG_ERROR(setPortMode, BAD_VALUE,
                     "%s(%d) mode is only supported on input port", asString(mode), mode);
-            return BAD_VALUE;
+            err = BAD_VALUE;
+            break;
         }
         (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
         (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
 
         MetadataBufferType metaType = kMetadataBufferTypeNativeHandleSource;
-        return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
+        err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
+        break;
     }
 
     case IOMX::kPortModePresetSecureBuffer:
@@ -726,7 +731,8 @@
         // Allow on both input and output.
         (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
         (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
-        return enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
+        err = enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
+        break;
     }
 
     case IOMX::kPortModePresetANWBuffer:
@@ -734,7 +740,8 @@
         if (portIndex != kPortIndexOutput) {
             CLOG_ERROR(setPortMode, BAD_VALUE,
                     "%s(%d) mode is only supported on output port", asString(mode), mode);
-            return BAD_VALUE;
+            err = BAD_VALUE;
+            break;
         }
 
         // Check if we're simulating legacy mode with metadata mode,
@@ -743,7 +750,7 @@
             if (storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL) == OK) {
                 CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
                         "metdata mode enabled successfully");
-                return OK;
+                break;
             }
 
             CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
@@ -754,15 +761,15 @@
 
         // Disable secure buffer and enable graphic buffer
         (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
-        status_t err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
+        err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
         if (err != OK) {
-            return err;
+            break;
         }
 
         // Not running experiment, or metadata is not supported.
         // Disable metadata mode and use legacy mode.
         (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
-        return OK;
+        break;
     }
 
     case IOMX::kPortModePresetByteBuffer:
@@ -771,15 +778,19 @@
         (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
         (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
         (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
-        return OK;
-    }
-
-    default:
         break;
     }
 
-    CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
-    return BAD_VALUE;
+    default:
+        CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
+        err = BAD_VALUE;
+        break;
+    }
+
+    if (err == OK) {
+        mPortMode[portIndex] = mode;
+    }
+    return err;
 }
 
 status_t OMXNodeInstance::enableNativeBuffers_l(
@@ -1057,28 +1068,51 @@
     }
 
     switch (omxBuffer.mBufferType) {
-        case OMXBuffer::kBufferTypePreset:
+        case OMXBuffer::kBufferTypePreset: {
+            if (mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer
+                    && mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle) {
+                break;
+            }
             return useBuffer_l(portIndex, NULL, NULL, buffer);
+        }
 
-        case OMXBuffer::kBufferTypeSharedMem:
+        case OMXBuffer::kBufferTypeSharedMem: {
+            if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
+                    && mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer) {
+                break;
+            }
             return useBuffer_l(portIndex, omxBuffer.mMem, NULL, buffer);
+        }
 
-        case OMXBuffer::kBufferTypeANWBuffer:
+        case OMXBuffer::kBufferTypeANWBuffer: {
+            if (mPortMode[portIndex] != IOMX::kPortModePresetANWBuffer) {
+                break;
+            }
             return useGraphicBuffer_l(portIndex, omxBuffer.mGraphicBuffer, buffer);
+        }
 
         case OMXBuffer::kBufferTypeHidlMemory: {
+                if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
+                        && mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer
+                        && mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle) {
+                    break;
+                }
                 sp<IHidlMemory> hidlMemory = mapMemory(omxBuffer.mHidlMemory);
                 if (hidlMemory == nullptr) {
                     ALOGE("OMXNodeInstance useBuffer() failed to map memory");
                     return NO_MEMORY;
                 }
                 return useBuffer_l(portIndex, NULL, hidlMemory, buffer);
-            }
+        }
         default:
+            return BAD_VALUE;
             break;
     }
 
-    return BAD_VALUE;
+    ALOGE("b/77486542 : bufferType = %d vs. portMode = %d",
+          omxBuffer.mBufferType, mPortMode[portIndex]);
+    android_errorWriteLog(0x534e4554, "77486542");
+    return INVALID_OPERATION;
 }
 
 status_t OMXNodeInstance::useBuffer_l(
@@ -1514,6 +1548,11 @@
         android_errorWriteLog(0x534e4554, "35467458");
         return BAD_VALUE;
     }
+    if (mPortMode[portIndex] != IOMX::kPortModePresetSecureBuffer) {
+        ALOGE("b/77486542");
+        android_errorWriteLog(0x534e4554, "77486542");
+        return INVALID_OPERATION;
+    }
     BufferMeta *buffer_meta = new BufferMeta(portIndex);
 
     OMX_BUFFERHEADERTYPE *header;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index fcf9070..cdaffe7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -385,6 +385,7 @@
     mSamplingRate = 0;
     mChannelMask = AUDIO_CHANNEL_NONE;
     mFormat = AUDIO_FORMAT_INVALID;
+    memset(&mGain, 0, sizeof(struct audio_gain_config));
     mGain.index = -1;
 }
 
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 2ef6234..c19cc35 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -49,9 +49,9 @@
 
     virtual aaudio_result_t close() = 0;
 
-    virtual aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
+    aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
 
-    virtual aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
+    aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
 
     virtual aaudio_result_t startStream(android::sp<AAudioServiceStreamBase> stream,
                                         audio_port_handle_t *clientHandle) = 0;
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index ff0b037..d9b8766 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -104,6 +104,9 @@
             goto error;
         }
 
+        // This is not protected by a lock because the stream cannot be
+        // referenced until the service returns a handle to the client.
+        // So only one thread can open a stream.
         mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService,
                                                          request,
                                                          sharingMode);
@@ -112,6 +115,9 @@
             result = AAUDIO_ERROR_UNAVAILABLE;
             goto error;
         }
+        // Save a weak pointer that we will use to access the endpoint.
+        mServiceEndpointWeak = mServiceEndpoint;
+
         mFramesPerBurst = mServiceEndpoint->getFramesPerBurst();
         copyFrom(*mServiceEndpoint);
     }
@@ -130,15 +136,19 @@
 
     stop();
 
-    if (mServiceEndpoint == nullptr) {
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
         result = AAUDIO_ERROR_INVALID_STATE;
     } else {
-        mServiceEndpoint->unregisterStream(this);
-        AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
-        mEndpointManager.closeEndpoint(mServiceEndpoint);
-        mServiceEndpoint.clear();
+        endpoint->unregisterStream(this);
+        AAudioEndpointManager &endpointManager = AAudioEndpointManager::getInstance();
+        endpointManager.closeEndpoint(endpoint);
+
+        // AAudioService::closeStream() prevents two threads from closing at the same time.
+        mServiceEndpoint.clear(); // endpoint will hold the pointer until this method returns.
     }
 
+
     {
         std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
         stopTimestampThread();
@@ -152,7 +162,12 @@
 
 aaudio_result_t AAudioServiceStreamBase::startDevice() {
     mClientHandle = AUDIO_PORT_HANDLE_NONE;
-    return mServiceEndpoint->startStream(this, &mClientHandle);
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
+    return endpoint->startStream(this, &mClientHandle);
 }
 
 /**
@@ -162,16 +177,11 @@
  */
 aaudio_result_t AAudioServiceStreamBase::start() {
     aaudio_result_t result = AAUDIO_OK;
+
     if (isRunning()) {
         return AAUDIO_OK;
     }
 
-    if (mServiceEndpoint == nullptr) {
-        ALOGE("AAudioServiceStreamBase::start() missing endpoint");
-        result = AAUDIO_ERROR_INVALID_STATE;
-        goto error;
-    }
-
     // Start with fresh presentation timestamps.
     mAtomicTimestamp.clear();
 
@@ -198,10 +208,6 @@
     if (!isRunning()) {
         return result;
     }
-    if (mServiceEndpoint == nullptr) {
-        ALOGE("AAudioServiceStreamShared::pause() missing endpoint");
-        return AAUDIO_ERROR_INVALID_STATE;
-    }
 
     // Send it now because the timestamp gets rounded up when stopStream() is called below.
     // Also we don't need the timestamps while we are shutting down.
@@ -213,7 +219,12 @@
         return result;
     }
 
-    result = mServiceEndpoint->stopStream(this, mClientHandle);
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
+    result = endpoint->stopStream(this, mClientHandle);
     if (result != AAUDIO_OK) {
         ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result);
         disconnect(); // TODO should we return or pause Base first?
@@ -230,11 +241,6 @@
         return result;
     }
 
-    if (mServiceEndpoint == nullptr) {
-        ALOGE("AAudioServiceStreamShared::stop() missing endpoint");
-        return AAUDIO_ERROR_INVALID_STATE;
-    }
-
     // Send it now because the timestamp gets rounded up when stopStream() is called below.
     // Also we don't need the timestamps while we are shutting down.
     sendCurrentTimestamp(); // warning - this calls a virtual function
@@ -244,8 +250,13 @@
         return result;
     }
 
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
     // TODO wait for data to be played out
-    result = mServiceEndpoint->stopStream(this, mClientHandle);
+    result = endpoint->stopStream(this, mClientHandle);
     if (result != AAUDIO_OK) {
         ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result);
         disconnect();
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index af435b4..815b1cc 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -233,7 +233,12 @@
     SimpleDoubleBuffer<Timestamp>  mAtomicTimestamp;
 
     android::AAudioService &mAudioService;
+
+    // The mServiceEndpoint variable can be accessed by multiple threads.
+    // So we access it by locally promoting a weak pointer to a smart pointer,
+    // which is thread-safe.
     android::sp<AAudioServiceEndpoint> mServiceEndpoint;
+    android::wp<AAudioServiceEndpoint> mServiceEndpointWeak;
 
 private:
     aaudio_handle_t         mHandle = -1;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 44ba1ca..2e7ff8b 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -70,14 +70,19 @@
         return result;
     }
 
-    result = mServiceEndpoint->registerStream(keep);
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
+
+    result = endpoint->registerStream(keep);
     if (result != AAUDIO_OK) {
-        goto error;
+        return result;
     }
 
     setState(AAUDIO_STREAM_STATE_OPEN);
 
-error:
     return AAUDIO_OK;
 }
 
@@ -122,21 +127,37 @@
 
 aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client,
                                                        audio_port_handle_t *clientHandle) {
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
     // Start the client on behalf of the application. Generate a new porthandle.
-    aaudio_result_t result = mServiceEndpoint->startClient(client, clientHandle);
+    aaudio_result_t result = endpoint->startClient(client, clientHandle);
     return result;
 }
 
 aaudio_result_t AAudioServiceStreamMMAP::stopClient(audio_port_handle_t clientHandle) {
-    aaudio_result_t result = mServiceEndpoint->stopClient(clientHandle);
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
+    aaudio_result_t result = endpoint->stopClient(clientHandle);
     return result;
 }
 
 // Get free-running DSP or DMA hardware position from the HAL.
 aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positionFrames,
                                                                   int64_t *timeNanos) {
-    sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
-            static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
+    sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+            static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
+
     aaudio_result_t result = serviceEndpointMMAP->getFreeRunningPosition(positionFrames, timeNanos);
     if (result == AAUDIO_OK) {
         Timestamp timestamp(*positionFrames, *timeNanos);
@@ -152,8 +173,15 @@
 // Get timestamp that was written by getFreeRunningPosition()
 aaudio_result_t AAudioServiceStreamMMAP::getHardwareTimestamp(int64_t *positionFrames,
                                                                 int64_t *timeNanos) {
-    sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
-            static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
+    sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+            static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
+
     // TODO Get presentation timestamp from the HAL
     if (mAtomicTimestamp.isValid()) {
         Timestamp timestamp = mAtomicTimestamp.read();
@@ -171,7 +199,12 @@
 aaudio_result_t AAudioServiceStreamMMAP::getAudioDataDescription(
         AudioEndpointParcelable &parcelable)
 {
-    sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
-            static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
+    sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+            static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
     return serviceEndpointMMAP->getDownDataDescription(parcelable);
 }
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 084f996..f55c40d 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -128,6 +128,11 @@
 
     const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
 
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        result = AAUDIO_ERROR_INVALID_STATE;
+        goto error;
+    }
 
     // Is the request compatible with the shared endpoint?
     setFormat(configurationInput.getFormat());
@@ -141,20 +146,20 @@
 
     setSampleRate(configurationInput.getSampleRate());
     if (getSampleRate() == AAUDIO_UNSPECIFIED) {
-        setSampleRate(mServiceEndpoint->getSampleRate());
-    } else if (getSampleRate() != mServiceEndpoint->getSampleRate()) {
+        setSampleRate(endpoint->getSampleRate());
+    } else if (getSampleRate() != endpoint->getSampleRate()) {
         ALOGE("AAudioServiceStreamShared::open() mSampleRate = %d, need %d",
-              getSampleRate(), mServiceEndpoint->getSampleRate());
+              getSampleRate(), endpoint->getSampleRate());
         result = AAUDIO_ERROR_INVALID_RATE;
         goto error;
     }
 
     setSamplesPerFrame(configurationInput.getSamplesPerFrame());
     if (getSamplesPerFrame() == AAUDIO_UNSPECIFIED) {
-        setSamplesPerFrame(mServiceEndpoint->getSamplesPerFrame());
-    } else if (getSamplesPerFrame() != mServiceEndpoint->getSamplesPerFrame()) {
+        setSamplesPerFrame(endpoint->getSamplesPerFrame());
+    } else if (getSamplesPerFrame() != endpoint->getSamplesPerFrame()) {
         ALOGE("AAudioServiceStreamShared::open() mSamplesPerFrame = %d, need %d",
-              getSamplesPerFrame(), mServiceEndpoint->getSamplesPerFrame());
+              getSamplesPerFrame(), endpoint->getSamplesPerFrame());
         result = AAUDIO_ERROR_OUT_OF_RANGE;
         goto error;
     }
@@ -181,9 +186,9 @@
     }
 
     ALOGD("AAudioServiceStreamShared::open() actual rate = %d, channels = %d, deviceId = %d",
-          getSampleRate(), getSamplesPerFrame(), mServiceEndpoint->getDeviceId());
+          getSampleRate(), getSamplesPerFrame(), endpoint->getDeviceId());
 
-    result = mServiceEndpoint->registerStream(keep);
+    result = endpoint->registerStream(keep);
     if (result != AAUDIO_OK) {
         goto error;
     }
@@ -250,7 +255,13 @@
                                                                 int64_t *timeNanos) {
 
     int64_t position = 0;
-    aaudio_result_t result = mServiceEndpoint->getTimestamp(&position, timeNanos);
+    sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+    if (endpoint == nullptr) {
+        ALOGE("%s() has no endpoint", __func__);
+        return AAUDIO_ERROR_INVALID_STATE;
+    }
+
+    aaudio_result_t result = endpoint->getTimestamp(&position, timeNanos);
     if (result == AAUDIO_OK) {
         int64_t offset = mTimestampPositionOffset.load();
         // TODO, do not go below starting value