Exemplo n.º 1
0
void GPUHardware::binderDied(const wp<IBinder>& who)
{
    Mutex::Autolock _l(mLock);
    pid_t pid = mRegisteredClients.valueFor(who);
    if (pid != 0) {
        ssize_t index = mClients.indexOfKey(pid);
        if (index >= 0) {
            //LOGD("*** removing client at %d", index);
            Client& client(mClients.editValueAt(index));
            client.revokeAllHeaps(); // not really needed in theory
            mClients.removeItemsAt(index);
            if (mClients.size() == 0) {
                //LOGD("*** was last client closing everything");
                mCallback.clear();
                mAllocator.clear();
                mCurrentAllocator.clear();
                mSMIHeap.clear();
                mREGHeap.clear();
                
                // NOTE: we cannot clear the EBI heap because surfaceflinger
                // itself may be using it, since this is where surfaces
                // are allocated. if we're in the middle of compositing 
                // a surface (even if its process just died), we cannot
                // rip the heap under our feet.
                
                mOwner = NO_OWNER;
            }
        }
    }
}
status_t NativeInputEventSender::receiveFinishedSignals(JNIEnv* env) {
    if (kDebugDispatchCycle) {
        ALOGD("channel '%s' ~ Receiving finished signals.", getInputChannelName());
    }

    ScopedLocalRef<jobject> senderObj(env, NULL);
    bool skipCallbacks = false;
    for (;;) {
        uint32_t publishedSeq;
        bool handled;
        status_t status = mInputPublisher.receiveFinishedSignal(&publishedSeq, &handled);
        if (status) {
            if (status == WOULD_BLOCK) {
                return OK;
            }
            ALOGE("channel '%s' ~ Failed to consume finished signals.  status=%d",
                    getInputChannelName(), status);
            return status;
        }

        ssize_t index = mPublishedSeqMap.indexOfKey(publishedSeq);
        if (index >= 0) {
            uint32_t seq = mPublishedSeqMap.valueAt(index);
            mPublishedSeqMap.removeItemsAt(index);

            if (kDebugDispatchCycle) {
                ALOGD("channel '%s' ~ Received finished signal, seq=%u, handled=%s, "
                        "pendingEvents=%zu.",
                        getInputChannelName(), seq, handled ? "true" : "false",
                        mPublishedSeqMap.size());
            }

            if (!skipCallbacks) {
                if (!senderObj.get()) {
                    senderObj.reset(jniGetReferent(env, mSenderWeakGlobal));
                    if (!senderObj.get()) {
                        ALOGW("channel '%s' ~ Sender object was finalized "
                                "without being disposed.", getInputChannelName());
                        return DEAD_OBJECT;
                    }
                }

                env->CallVoidMethod(senderObj.get(),
                        gInputEventSenderClassInfo.dispatchInputEventFinished,
                        jint(seq), jboolean(handled));
                if (env->ExceptionCheck()) {
                    ALOGE("Exception dispatching finished signal.");
                    skipCallbacks = true;
                }
            }
        }
    }
}
status_t MPEG2TSExtractor::feedMore() {
    Mutex::Autolock autoLock(mLock);

    uint8_t packet[kTSPacketSize];
    ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);

    if (n < (ssize_t)kTSPacketSize) {
        if (n >= 0) {
            mParser->signalEOS(ERROR_END_OF_STREAM);
        }
        return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
    }

    ATSParser::SyncEvent event(mOffset);
    mOffset += n;
    status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event);
    if (event.isInit()) {
        for (size_t i = 0; i < mSourceImpls.size(); ++i) {
            if (mSourceImpls[i].get() == event.getMediaSource().get()) {
                KeyedVector<int64_t, off64_t> *syncPoints = &mSyncPoints.editItemAt(i);
                syncPoints->add(event.getTimeUs(), event.getOffset());
                // We're keeping the size of the sync points at most 5mb per a track.
                size_t size = syncPoints->size();
                if (size >= 327680) {
                    int64_t firstTimeUs = syncPoints->keyAt(0);
                    int64_t lastTimeUs = syncPoints->keyAt(size - 1);
                    if (event.getTimeUs() - firstTimeUs > lastTimeUs - event.getTimeUs()) {
                        syncPoints->removeItemsAt(0, 4096);
                    } else {
                        syncPoints->removeItemsAt(size - 4096, 4096);
                    }
                }
                break;
            }
        }
    }
    return err;
}
Exemplo n.º 4
0
void HeapCache::free_heap(const wp<IBinder>& binder)
{
    sp<IMemoryHeap> rel;
    {
        Mutex::Autolock _l(mHeapCacheLock);
        ssize_t i = mHeapCache.indexOfKey(binder);
        if (i>=0) {
            heap_info_t& info(mHeapCache.editValueAt(i));
            int32_t c = android_atomic_dec(&info.count);
            if (c == 1) {
                ALOGD_IF(VERBOSE,
                        "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d",
                        binder.unsafe_get(), info.heap.get(),
                        static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
                        static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
                        info.count);
                rel = mHeapCache.valueAt(i).heap;
                mHeapCache.removeItemsAt(i);
            }
        } else {
            ALOGE("free_heap binder=%p not found!!!", binder.unsafe_get());
        }
    }
}
bool isWVM(const char* url,
           const KeyedVector<String8, String8> *headers) {
    sp<DataSource> dataSource;
    String8 mUri;
    KeyedVector<String8, String8> mUriHeaders;
    sp<HTTPBase> mConnectingDataSource;
    sp<NuCachedSource2> mCachedSource;
    uint32_t mFlags;

    mUri = url;

    void *VendorLibHandle = NULL;
    if (VendorLibHandle == NULL) {
        VendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
    }

    if (!VendorLibHandle) {
        return false;
    }

    if (headers) {
        mUriHeaders = *headers;

        ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
        if (index >= 0) {
            // Browser is in "incognito" mode, suppress logging URLs.

            // This isn't something that should be passed to the server.
            mUriHeaders.removeItemsAt(index);

            mFlags |= INCOGNITO;
        }
    }

    if (!strncasecmp("http://", mUri.string(), 7)
            || !strncasecmp("https://", mUri.string(), 8)) {
        mConnectingDataSource = HTTPBase::Create(
                (mFlags & INCOGNITO)
                    ? HTTPBase::kFlagIncognito
                    : 0);

        String8 cacheConfig;
        bool disconnectAtHighwatermark;
        NuCachedSource2::RemoveCacheSpecificHeaders(
                &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);

        status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);

        if (err != OK) {
            mConnectingDataSource.clear();

            ALOGI("mConnectingDataSource->connect() returned %d", err);
            return false;
        }

        // The widevine extractor does its own caching.
        mCachedSource = new NuCachedSource2(
                mConnectingDataSource,
                cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
                disconnectAtHighwatermark);

        dataSource = mCachedSource;

        mConnectingDataSource.clear();

        // Removed prefill as we can't abort it.
        //
        // We're going to prefill the cache before trying to instantiate
        // the extractor below, as the latter is an operation that otherwise
        // could block on the datasource for a significant amount of time.
        // During that time we'd be unable to abort the preparation phase
        // without this prefill.

    } else {
        dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
    }

    if (dataSource == NULL) {
        return false;
    }

    typedef WVMLoadableExtractor *(*SnifferFunc)(const sp<DataSource>&);
    SnifferFunc snifferFunc =
        (SnifferFunc) dlsym(VendorLibHandle,
                "_ZN7android15IsWidevineMediaERKNS_2spINS_10DataSourceEEE");

    if (snifferFunc) {
        if ((*snifferFunc)(dataSource)) {
            return true;
        }
    }

    return false;
}