BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
    mAllocator(allocator),
    mMutex(),
    mIsAbandoned(false),
    mConsumerControlledByApp(false),
    mConsumerName(getUniqueName()),
    mConsumerListener(),
    mConsumerUsageBits(0),
    mConnectedApi(NO_CONNECTED_API),
    mLinkedToDeath(),
    mConnectedProducerListener(),
    mSlots(),
    mQueue(),
    mFreeSlots(),
    mFreeBuffers(),
    mUnusedSlots(),
    mActiveBuffers(),
    mDequeueCondition(),
    mDequeueBufferCannotBlock(false),
    mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
    mDefaultWidth(1),
    mDefaultHeight(1),
    mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
    mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS),
    mMaxAcquiredBufferCount(1),
    mMaxDequeuedBufferCount(1),
    mBufferHasBeenQueued(false),
    mFrameCounter(0),
    mTransformHint(0),
    mIsAllocating(false),
    mIsAllocatingCondition(),
    mAllowAllocation(true),
    mBufferAge(0),
    mGenerationNumber(0),
    mAsyncMode(false),
    mSharedBufferMode(false),
    mAutoRefresh(false),
    mSharedBufferSlot(INVALID_BUFFER_SLOT),
    mSharedBufferCache(Rect::INVALID_RECT, 0, NATIVE_WINDOW_SCALING_MODE_FREEZE,
            HAL_DATASPACE_UNKNOWN),
    mUniqueId(getUniqueId())
{
    if (allocator == NULL) {

#ifdef HAVE_NO_SURFACE_FLINGER
        // Without a SurfaceFlinger, allocate in-process.  This only makes
        // sense in systems with static SELinux configurations and no
        // applications (since applications need dynamic SELinux policy).
        mAllocator = new GraphicBufferAlloc();
#else
        // Run time check for headless, where we also allocate in-process.
        char value[PROPERTY_VALUE_MAX];
        property_get("config.headless", value, "0");
        if (atoi(value) == 1) {
            mAllocator = new GraphicBufferAlloc();
        } else {
            sp<ISurfaceComposer> composer(ComposerService::getComposerService());
            mAllocator = composer->createGraphicBufferAlloc();
        }
#endif  // HAVE_NO_SURFACE_FLINGER

        if (mAllocator == NULL) {
            BQ_LOGE("createGraphicBufferAlloc failed");
        }
    }

    int numStartingBuffers = getMaxBufferCountLocked();
    for (int s = 0; s < numStartingBuffers; s++) {
        mFreeSlots.insert(s);
    }
    for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS;
            s++) {
        mUnusedSlots.push_front(s);
    }
}
/*
 * Start the Dalvik Virtual Machine.
 *
 * Various arguments, most determined by system properties, are passed in.
 * The "mOptions" vector is updated.
 *
 * Returns 0 on success.
 */
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
{
    int result = -1;
    JavaVMInitArgs initArgs;
    JavaVMOption opt;
    char propBuf[PROPERTY_VALUE_MAX];
    char stackTraceFileBuf[PROPERTY_VALUE_MAX];
    char dexoptFlagsBuf[PROPERTY_VALUE_MAX];
    char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX];
    char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
    char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
    char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
    char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
    char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
    char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
    char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
    char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX];
    char extraOptsBuf[PROPERTY_VALUE_MAX];
    char* stackTraceFile = NULL;
    bool checkJni = false;
    bool checkDexSum = false;
    bool logStdio = false;
    enum {
      kEMDefault,
      kEMIntPortable,
      kEMIntFast,
      kEMJitCompiler,
    } executionMode = kEMDefault;


    property_get("dalvik.vm.checkjni", propBuf, "");
    if (strcmp(propBuf, "true") == 0) {
        checkJni = true;
    } else if (strcmp(propBuf, "false") != 0) {
        /* property is neither true nor false; fall back on kernel parameter */
        property_get("ro.kernel.android.checkjni", propBuf, "");
        if (propBuf[0] == '1') {
            checkJni = true;
        }
    }

    property_get("dalvik.vm.execution-mode", propBuf, "");
    if (strcmp(propBuf, "int:portable") == 0) {
        executionMode = kEMIntPortable;
    } else if (strcmp(propBuf, "int:fast") == 0) {
        executionMode = kEMIntFast;
    } else if (strcmp(propBuf, "int:jit") == 0) {
        executionMode = kEMJitCompiler;
    }

    property_get("dalvik.vm.stack-trace-file", stackTraceFileBuf, "");

    property_get("dalvik.vm.check-dex-sum", propBuf, "");
    if (strcmp(propBuf, "true") == 0) {
        checkDexSum = true;
    }

    property_get("log.redirect-stdio", propBuf, "");
    if (strcmp(propBuf, "true") == 0) {
        logStdio = true;
    }

    strcpy(enableAssertBuf, "-ea:");
    property_get("dalvik.vm.enableassertions", enableAssertBuf+4, "");

    strcpy(jniOptsBuf, "-Xjniopts:");
    property_get("dalvik.vm.jniopts", jniOptsBuf+10, "");

    /* route exit() to our handler */
    opt.extraInfo = (void*) runtime_exit;
    opt.optionString = "exit";
    mOptions.add(opt);

    /* route fprintf() to our handler */
    opt.extraInfo = (void*) runtime_vfprintf;
    opt.optionString = "vfprintf";
    mOptions.add(opt);

    /* register the framework-specific "is sensitive thread" hook */
    opt.extraInfo = (void*) runtime_isSensitiveThread;
    opt.optionString = "sensitiveThread";
    mOptions.add(opt);

    opt.extraInfo = NULL;

    /* enable verbose; standard options are { jni, gc, class } */
    //options[curOpt++].optionString = "-verbose:jni";
    opt.optionString = "-verbose:gc";
    mOptions.add(opt);
    //options[curOpt++].optionString = "-verbose:class";

    /*
     * The default starting and maximum size of the heap.  Larger
     * values should be specified in a product property override.
     */
    strcpy(heapstartsizeOptsBuf, "-Xms");
    property_get("dalvik.vm.heapstartsize", heapstartsizeOptsBuf+4, "4m");
    opt.optionString = heapstartsizeOptsBuf;
    mOptions.add(opt);
    strcpy(heapsizeOptsBuf, "-Xmx");
    property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
    opt.optionString = heapsizeOptsBuf;
    mOptions.add(opt);

    // Increase the main thread's interpreter stack size for bug 6315322.
    opt.optionString = "-XX:mainThreadStackSize=24K";
    mOptions.add(opt);

    // Set the max jit code cache size.  Note: size of 0 will disable the JIT.
    strcpy(jitcodecachesizeOptsBuf, "-Xjitcodecachesize:");
    property_get("dalvik.vm.jit.codecachesize", jitcodecachesizeOptsBuf+19,  NULL);
    if (jitcodecachesizeOptsBuf[19] != '\0') {
      opt.optionString = jitcodecachesizeOptsBuf;
      mOptions.add(opt);
    }

    strcpy(heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
    property_get("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf+20, "");
    if (heapgrowthlimitOptsBuf[20] != '\0') {
        opt.optionString = heapgrowthlimitOptsBuf;
        mOptions.add(opt);
    }

    strcpy(heapminfreeOptsBuf, "-XX:HeapMinFree=");
    property_get("dalvik.vm.heapminfree", heapminfreeOptsBuf+16, "");
    if (heapminfreeOptsBuf[16] != '\0') {
        opt.optionString = heapminfreeOptsBuf;
        mOptions.add(opt);
    }

    strcpy(heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");
    property_get("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf+16, "");
    if (heapmaxfreeOptsBuf[16] != '\0') {
        opt.optionString = heapmaxfreeOptsBuf;
        mOptions.add(opt);
    }

    strcpy(heaptargetutilizationOptsBuf, "-XX:HeapTargetUtilization=");
    property_get("dalvik.vm.heaptargetutilization", heaptargetutilizationOptsBuf+26, "");
    if (heaptargetutilizationOptsBuf[26] != '\0') {
        opt.optionString = heaptargetutilizationOptsBuf;
        mOptions.add(opt);
    }

    property_get("ro.config.low_ram", propBuf, "");
    if (strcmp(propBuf, "true") == 0) {
      opt.optionString = "-XX:LowMemoryMode";
      mOptions.add(opt);
    }

    /*
     * Enable or disable dexopt features, such as bytecode verification and
     * calculation of register maps for precise GC.
     */
    property_get("dalvik.vm.dexopt-flags", dexoptFlagsBuf, "");
    if (dexoptFlagsBuf[0] != '\0') {
        const char* opc;
        const char* val;

        opc = strstr(dexoptFlagsBuf, "v=");     /* verification */
        if (opc != NULL) {
            switch (*(opc+2)) {
            case 'n':   val = "-Xverify:none";      break;
            case 'r':   val = "-Xverify:remote";    break;
            case 'a':   val = "-Xverify:all";       break;
            default:    val = NULL;                 break;
            }

            if (val != NULL) {
                opt.optionString = val;
                mOptions.add(opt);
            }
        }

        opc = strstr(dexoptFlagsBuf, "o=");     /* optimization */
        if (opc != NULL) {
            switch (*(opc+2)) {
            case 'n':   val = "-Xdexopt:none";      break;
            case 'v':   val = "-Xdexopt:verified";  break;
            case 'a':   val = "-Xdexopt:all";       break;
            case 'f':   val = "-Xdexopt:full";      break;
            default:    val = NULL;                 break;
            }

            if (val != NULL) {
                opt.optionString = val;
                mOptions.add(opt);
            }
        }

        opc = strstr(dexoptFlagsBuf, "m=y");    /* register map */
        if (opc != NULL) {
            opt.optionString = "-Xgenregmap";
            mOptions.add(opt);

            /* turn on precise GC while we're at it */
            opt.optionString = "-Xgc:precise";
            mOptions.add(opt);
        }
    }

    /* enable debugging; set suspend=y to pause during VM init */
    /* use android ADB transport */
    opt.optionString =
        "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
    mOptions.add(opt);

    ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
    if (checkJni) {
        /* extended JNI checking */
        opt.optionString = "-Xcheck:jni";
        mOptions.add(opt);

        /* set a cap on JNI global references */
        opt.optionString = "-Xjnigreflimit:2000";
        mOptions.add(opt);

        /* with -Xcheck:jni, this provides a JNI function call trace */
        //opt.optionString = "-verbose:jni";
        //mOptions.add(opt);
    }

    char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
    property_get("dalvik.vm.lockprof.threshold", propBuf, "");
    if (strlen(propBuf) > 0) {
      strcpy(lockProfThresholdBuf, "-Xlockprofthreshold:");
      strcat(lockProfThresholdBuf, propBuf);
      opt.optionString = lockProfThresholdBuf;
      mOptions.add(opt);
    }

    /* Force interpreter-only mode for selected opcodes. Eg "1-0a,3c,f1-ff" */
    char jitOpBuf[sizeof("-Xjitop:") + PROPERTY_VALUE_MAX];
    property_get("dalvik.vm.jit.op", propBuf, "");
    if (strlen(propBuf) > 0) {
        strcpy(jitOpBuf, "-Xjitop:");
        strcat(jitOpBuf, propBuf);
        opt.optionString = jitOpBuf;
        mOptions.add(opt);
    }

    /* Force interpreter-only mode for selected methods */
    char jitMethodBuf[sizeof("-Xjitmethod:") + PROPERTY_VALUE_MAX];
    property_get("dalvik.vm.jit.method", propBuf, "");
    if (strlen(propBuf) > 0) {
        strcpy(jitMethodBuf, "-Xjitmethod:");
        strcat(jitMethodBuf, propBuf);
        opt.optionString = jitMethodBuf;
        mOptions.add(opt);
    }

    if (executionMode == kEMIntPortable) {
        opt.optionString = "-Xint:portable";
        mOptions.add(opt);
    } else if (executionMode == kEMIntFast) {
        opt.optionString = "-Xint:fast";
        mOptions.add(opt);
    } else if (executionMode == kEMJitCompiler) {
        opt.optionString = "-Xint:jit";
        mOptions.add(opt);
    }

    if (checkDexSum) {
        /* perform additional DEX checksum tests */
        opt.optionString = "-Xcheckdexsum";
        mOptions.add(opt);
    }

    if (logStdio) {
        /* convert stdout/stderr to log messages */
        opt.optionString = "-Xlog-stdio";
        mOptions.add(opt);
    }

    if (enableAssertBuf[4] != '\0') {
        /* accept "all" to mean "all classes and packages" */
        if (strcmp(enableAssertBuf+4, "all") == 0)
            enableAssertBuf[3] = '\0';
        ALOGI("Assertions enabled: '%s'\n", enableAssertBuf);
        opt.optionString = enableAssertBuf;
        mOptions.add(opt);
    } else {
        ALOGV("Assertions disabled\n");
    }

    if (jniOptsBuf[10] != '\0') {
        ALOGI("JNI options: '%s'\n", jniOptsBuf);
        opt.optionString = jniOptsBuf;
        mOptions.add(opt);
    }

    if (stackTraceFileBuf[0] != '\0') {
        static const char* stfOptName = "-Xstacktracefile:";

        stackTraceFile = (char*) malloc(strlen(stfOptName) +
            strlen(stackTraceFileBuf) +1);
        strcpy(stackTraceFile, stfOptName);
        strcat(stackTraceFile, stackTraceFileBuf);
        opt.optionString = stackTraceFile;
        mOptions.add(opt);
    }

    /* extra options; parse this late so it overrides others */
    property_get("dalvik.vm.extra-opts", extraOptsBuf, "");
    parseExtraOpts(extraOptsBuf);

    /* Set the properties for locale */
    {
        char langOption[sizeof("-Duser.language=") + 3];
        char regionOption[sizeof("-Duser.region=") + 3];
        strcpy(langOption, "-Duser.language=");
        strcpy(regionOption, "-Duser.region=");
        readLocale(langOption, regionOption);
        opt.extraInfo = NULL;
        opt.optionString = langOption;
        mOptions.add(opt);
        opt.optionString = regionOption;
        mOptions.add(opt);
    }

    /*
     * We don't have /tmp on the device, but we often have an SD card.  Apps
     * shouldn't use this, but some test suites might want to exercise it.
     */
    opt.optionString = "-Djava.io.tmpdir=/sdcard";
    mOptions.add(opt);

    initArgs.version = JNI_VERSION_1_4;
    initArgs.options = mOptions.editArray();
    initArgs.nOptions = mOptions.size();
    initArgs.ignoreUnrecognized = JNI_FALSE;

    /*
     * Initialize the VM.
     *
     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     * If this call succeeds, the VM is ready, and we can start issuing
     * JNI calls.
     */
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        goto bail;
    }

    result = 0;

bail:
    free(stackTraceFile);
    return result;
}
static void *vsync_loop(void *param)
{
    hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);

    char thread_name[64] = HWC_VSYNC_THREAD_NAME;
    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY +
                android::PRIORITY_MORE_FAVORABLE);

    const int MAX_DATA = 64;
    char vdata[MAX_DATA];
    bool logvsync = false;

    struct pollfd pfd[2];
    int fb_fd[2];
    uint64_t timestamp[2] = {0,0};
    int num_displays;

    char property[PROPERTY_VALUE_MAX];
    if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
        if(atoi(property) == 1)
            ctx->vstate.fakevsync = true;
    }

    if(property_get("debug.hwc.logvsync", property, 0) > 0) {
        if(atoi(property) == 1)
            logvsync = true;
    }

    if (ctx->mExtDisplay->isConnected())
        num_displays = 2;
    else
        num_displays = 1;

    char vsync_node_path[MAX_SYSFS_FILE_PATH];
    for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
        snprintf(vsync_node_path, sizeof(vsync_node_path),
                 "/sys/class/graphics/fb%d/vsync_event",
                 dpy == HWC_DISPLAY_PRIMARY ? 0 :
                 overlay::Overlay::getInstance()->
                 getFbForDpy(HWC_DISPLAY_EXTERNAL));
        ALOGI("%s: Reading vsync for dpy=%d from %s", __FUNCTION__, dpy,
              vsync_node_path);
        fb_fd[dpy] = open(vsync_node_path, O_RDONLY);

        if (fb_fd[dpy] < 0) {
            // Make sure fb device is opened before starting this thread so this
            // never happens.
            ALOGE ("%s:not able to open vsync node for dpy=%d, %s",
                   __FUNCTION__, dpy, strerror(errno));
            if (dpy == HWC_DISPLAY_PRIMARY) {
                ctx->vstate.fakevsync = true;
                break;
            }
        }
        // Read once from the fds to clear the first notify
        pread(fb_fd[dpy], vdata , MAX_DATA, 0);

        pfd[dpy].fd = fb_fd[dpy];
        if (pfd[dpy].fd >= 0)
            pfd[dpy].events = POLLPRI | POLLERR;
    }

    if (LIKELY(!ctx->vstate.fakevsync)) {
        do {
            int err = poll(pfd, num_displays, -1);
            if(err > 0) {
                for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
                    if (pfd[dpy].revents & POLLPRI) {
                        int len = pread(pfd[dpy].fd, vdata, MAX_DATA, 0);
                        if (UNLIKELY(len < 0)) {
                            // If the read was just interrupted - it is not a
                            // fatal error. Just continue in this case
                            ALOGE ("%s: Unable to read vsync for dpy=%d : %s",
                                   __FUNCTION__, dpy, strerror(errno));
                            continue;
                        }
                        // extract timestamp
                        if (!strncmp(vdata, "VSYNC=", strlen("VSYNC="))) {
                            timestamp[dpy] = strtoull(vdata + strlen("VSYNC="),
                                                      NULL, 0);
                        }
                        // send timestamp to SurfaceFlinger
                        ALOGD_IF (logvsync,
                                  "%s: timestamp %llu sent to SF for dpy=%d",
                                  __FUNCTION__, timestamp[dpy], dpy);
                        ctx->proc->vsync(ctx->proc, dpy, timestamp[dpy]);
                    }
                }

            } else {
                ALOGE("%s: vsync poll failed errno: %s", __FUNCTION__,
                      strerror(errno));
                continue;
            }
        } while (true);

    } else {

        //Fake vsync is used only when set explicitly through a property or when
        //the vsync timestamp node cannot be opened at bootup. There is no
        //fallback to fake vsync from the true vsync loop, ever, as the
        //condition can easily escape detection.
        //Also, fake vsync is delivered only for the primary display.
        do {
            usleep(16666);
            timestamp[HWC_DISPLAY_PRIMARY] = systemTime();
            ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY,
                             timestamp[HWC_DISPLAY_PRIMARY]);

        } while (true);
    }

    for (int dpy = HWC_DISPLAY_PRIMARY; dpy <= HWC_DISPLAY_EXTERNAL; dpy++ ) {
        if(fb_fd[dpy] >= 0)
            close (fb_fd[dpy]);
    }

    return NULL;
}
status_t WifiDisplaySource::onReceiveM3Response(
        int32_t sessionID, const sp<ParsedMessage> &msg) {
    int32_t statusCode;
    if (!msg->getStatusCode(&statusCode)) {
        return ERROR_MALFORMED;
    }

    if (statusCode != 200) {
        return ERROR_UNSUPPORTED;
    }

    sp<Parameters> params =
        Parameters::Parse(msg->getContent(), strlen(msg->getContent()));

    if (params == NULL) {
        return ERROR_MALFORMED;
    }

    AString value;
    if (!params->findParameter("wfd_client_rtp_ports", &value)) {
        ALOGE("Sink doesn't report its choice of wfd_client_rtp_ports.");
        return ERROR_MALFORMED;
    }

    unsigned port0, port1;
    if (sscanf(value.c_str(),
               "RTP/AVP/UDP;unicast %u %u mode=play",
               &port0,
               &port1) != 2
        || port0 == 0 || port0 > 65535 || port1 != 0) {
        ALOGE("Sink chose its wfd_client_rtp_ports poorly (%s)",
              value.c_str());

        ALOGE("onReceiveM3Response() SKIP!! port check.");
        port0 = 19000;
        port1 = 0;
        //return ERROR_MALFORMED;
    }

    mChosenRTPPort = port0;

    if (!params->findParameter("wfd_audio_codecs", &value)) {
        ALOGE("Sink doesn't report its choice of wfd_audio_codecs.");
        return ERROR_MALFORMED;
    }

    if  (value == "none") {
        ALOGE("Sink doesn't support audio at all.");
        return ERROR_UNSUPPORTED;
    }

    if (value == "xxx") {
        ALOGE("onReceiveM3Response() Force Apply wfd_audio_codecs to AAC");
        value.clear();
        value.append("LPCM 00000003 00, AAC 0000000F 00");
    }

    uint32_t modes;
    GetAudioModes(value.c_str(), "AAC", &modes);

    bool supportsAAC = (modes & 1) != 0;  // AAC 2ch 48kHz

    GetAudioModes(value.c_str(), "LPCM", &modes);

    bool supportsPCM = (modes & 2) != 0;  // LPCM 2ch 48kHz

    char val[PROPERTY_VALUE_MAX];
    if (supportsPCM
            && property_get("media.wfd.use-pcm-audio", val, NULL)
            && (!strcasecmp("true", val) || !strcmp("1", val))) {
        ALOGI("Using PCM audio.");
        mUsingPCMAudio = true;
    } else if (supportsAAC) {
        ALOGI("Using AAC audio.");
        mUsingPCMAudio = false;
    } else if (supportsPCM) {
        ALOGI("Using PCM audio.");
        mUsingPCMAudio = true;
    } else {
        ALOGI("Sink doesn't support an audio format we do.");
        return ERROR_UNSUPPORTED;
    }

    mUsingHDCP = false;
    if (!params->findParameter("wfd_content_protection", &value)) {
        ALOGI("Sink doesn't appear to support content protection.");
    } else if (value == "none") {
        ALOGI("Sink does not support content protection.");
    } else {
        mUsingHDCP = true;

        bool isHDCP2_0 = false;
        if (value.startsWith("HDCP2.0 ")) {
            isHDCP2_0 = true;
        } else if (!value.startsWith("HDCP2.1 ")) {
            ALOGE("malformed wfd_content_protection: '%s'", value.c_str());

            return ERROR_MALFORMED;
        }

        int32_t hdcpPort;
        if (!ParsedMessage::GetInt32Attribute(
                    value.c_str() + 8, "port", &hdcpPort)
                || hdcpPort < 1 || hdcpPort > 65535) {
            return ERROR_MALFORMED;
        }

        mIsHDCP2_0 = isHDCP2_0;
        mHDCPPort = hdcpPort;

        status_t err = makeHDCP();
        if (err != OK) {
            ALOGE("Unable to instantiate HDCP component. "
                  "Not using HDCP after all.");

            mUsingHDCP = false;
        }
    }

    return sendM4(sessionID);
}
Example #5
0
int nandroid_backup(const char* backup_path)
{
    nandroid_backup_bitfield = 0;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    refresh_default_backup_handler();

    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("Can't mount backup path.\n");
    }

    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume)
        return print_and_error("Unable to find volume for backup path.\n");
    if (is_data_media_volume_path(volume->mount_point))
        volume = volume_for_path("/data");
    int ret;
    struct statfs sfs;
    struct stat s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &sfs)))
            return print_and_error("Unable to stat backup path.\n");
        uint64_t bavail = sfs.f_bavail;
        uint64_t bsize = sfs.f_bsize;
        uint64_t sdcard_free = bavail * bsize;
        uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
        ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
        if (sdcard_free_mb < 150)
            ui_print("There may not be enough free space to complete backup... continuing...\n");
    }
    char tmp[PATH_MAX];
    ensure_directory(backup_path);

    if (0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) {
            ui_print("Failed to backup /preload!\n");
            return ret;
        }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) {
        ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n");
    }
    else {
        if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n");
        else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
            return ret;
    }

    ui_print("Generating md5 sum...\n");
    sprintf(tmp, "nandroid-md5.sh %s", backup_path);
    if (0 != (ret = __system(tmp))) {
        ui_print("Error while generating md5 sum!\n");
        return ret;
    }

    sprintf(tmp, "cp /tmp/recovery.log %s/recovery.log", backup_path);
    __system(tmp);

    sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path);
    __system(tmp);
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
Example #6
0
static void read_property() {
    char value[PROPERTY_VALUE_MAX];
    property_get("debug.nfc.UART_ERROR_RATE", value, "0");
    property_error_rate = atoi(value);
}
void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatStart:
        {
            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            AString iface;
            CHECK(msg->findString("iface", &iface));

            status_t err = OK;

            ssize_t colonPos = iface.find(":");

            unsigned long port;

            if (colonPos >= 0) {
                const char *s = iface.c_str() + colonPos + 1;

                char *end;
                port = strtoul(s, &end, 10);

                if (end == s || *end != '\0' || port > 65535) {
                    err = -EINVAL;
                } else {
                    iface.erase(colonPos, iface.size() - colonPos);
                }
            } else {
                port = kWifiDisplayDefaultPort;
            }

            if (err == OK) {
                if (inet_aton(iface.c_str(), &mInterfaceAddr) != 0) {
                    sp<AMessage> notify = new AMessage(kWhatRTSPNotify, id());

                    err = mNetSession->createRTSPServer(
                            mInterfaceAddr, port, notify, &mSessionID);
                } else {
                    err = -EINVAL;
                }
            }

            if (err == OK) {
                mState = AWAITING_CLIENT_CONNECTION;
            }

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatRTSPNotify:
        {
            int32_t reason;
            CHECK(msg->findInt32("reason", &reason));

            switch (reason) {
                case ANetworkSession::kWhatError:
                {
                    int32_t sessionID;
                    CHECK(msg->findInt32("sessionID", &sessionID));

                    int32_t err;
                    CHECK(msg->findInt32("err", &err));

                    AString detail;
                    CHECK(msg->findString("detail", &detail));

                    ALOGE("An error occurred in session %d (%d, '%s/%s').",
                          sessionID,
                          err,
                          detail.c_str(),
                          strerror(-err));

                    mNetSession->destroySession(sessionID);

                    if (sessionID == mClientSessionID) {
                        mClientSessionID = 0;

                        mClient->onDisplayError(
                                IRemoteDisplayClient::kDisplayErrorUnknown);
                    }
                    break;
                }

                case ANetworkSession::kWhatClientConnected:
                {
                    int32_t sessionID;
                    CHECK(msg->findInt32("sessionID", &sessionID));

                    if (mClientSessionID > 0) {
                        ALOGW("A client tried to connect, but we already "
                              "have one.");

                        mNetSession->destroySession(sessionID);
                        break;
                    }

                    CHECK_EQ(mState, AWAITING_CLIENT_CONNECTION);

                    CHECK(msg->findString("client-ip", &mClientInfo.mRemoteIP));
                    CHECK(msg->findString("server-ip", &mClientInfo.mLocalIP));

                    if (mClientInfo.mRemoteIP == mClientInfo.mLocalIP) {
                        // Disallow connections from the local interface
                        // for security reasons.
                        mNetSession->destroySession(sessionID);
                        break;
                    }

                    CHECK(msg->findInt32(
                                "server-port", &mClientInfo.mLocalPort));
                    mClientInfo.mPlaybackSessionID = -1;

                    mClientSessionID = sessionID;

                    ALOGI("We now have a client (%d) connected.", sessionID);

                    mState = AWAITING_CLIENT_SETUP;

                    status_t err = sendM1(sessionID);
                    CHECK_EQ(err, (status_t)OK);
                    break;
                }

                case ANetworkSession::kWhatData:
                {
                    status_t err = onReceiveClientData(msg);

                    if (err != OK) {
                        mClient->onDisplayError(
                                IRemoteDisplayClient::kDisplayErrorUnknown);
                    }

#if 0
                    // testing only.
                    char val[PROPERTY_VALUE_MAX];
                    if (property_get("media.wfd.trigger", val, NULL)) {
                        if (!strcasecmp(val, "pause") && mState == PLAYING) {
                            mState = PLAYING_TO_PAUSED;
                            sendTrigger(mClientSessionID, TRIGGER_PAUSE);
                        } else if (!strcasecmp(val, "play") && mState == PAUSED) {
                            mState = PAUSED_TO_PLAYING;
                            sendTrigger(mClientSessionID, TRIGGER_PLAY);
                        }
                    }
#endif
                    break;
                }

                default:
                    TRESPASS();
            }
            break;
        }

        case kWhatStop:
        {
            CHECK(msg->senderAwaitsResponse(&mStopReplyID));

            CHECK_LT(mState, AWAITING_CLIENT_TEARDOWN);

            if (mState >= AWAITING_CLIENT_PLAY) {
                // We have a session, i.e. a previous SETUP succeeded.

                status_t err = sendTrigger(
                        mClientSessionID, TRIGGER_TEARDOWN);

                if (err == OK) {
                    mState = AWAITING_CLIENT_TEARDOWN;

                    (new AMessage(kWhatTeardownTriggerTimedOut, id()))->post(
                            kTeardownTriggerTimeouSecs * 1000000ll);

                    break;
                }

                // fall through.
            }

            finishStop();
            break;
        }

        case kWhatPause:
        {
            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            status_t err = OK;

            if (mState != PLAYING) {
                err = INVALID_OPERATION;
            } else {
                mState = PLAYING_TO_PAUSED;
                sendTrigger(mClientSessionID, TRIGGER_PAUSE);
            }

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatResume:
        {
            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            status_t err = OK;

            if (mState != PAUSED) {
                err = INVALID_OPERATION;
            } else {
                mState = PAUSED_TO_PLAYING;
                sendTrigger(mClientSessionID, TRIGGER_PLAY);
            }

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatReapDeadClients:
        {
            mReaperPending = false;

            if (mClientSessionID == 0
                    || mClientInfo.mPlaybackSession == NULL) {
                break;
            }

            if (mClientInfo.mPlaybackSession->getLastLifesignUs()
                    + kPlaybackSessionTimeoutUs < ALooper::GetNowUs()) {
                ALOGI("playback session timed out, reaping.");

                mNetSession->destroySession(mClientSessionID);
                mClientSessionID = 0;

                mClient->onDisplayError(
                        IRemoteDisplayClient::kDisplayErrorUnknown);
            } else {
                scheduleReaper();
            }
            break;
        }

        case kWhatPlaybackSessionNotify:
        {
            int32_t playbackSessionID;
            CHECK(msg->findInt32("playbackSessionID", &playbackSessionID));

            int32_t what;
            CHECK(msg->findInt32("what", &what));

            if (what == PlaybackSession::kWhatSessionDead) {
                ALOGI("playback session wants to quit.");

                mClient->onDisplayError(
                        IRemoteDisplayClient::kDisplayErrorUnknown);
            } else if (what == PlaybackSession::kWhatSessionEstablished) {
                if (mClient != NULL) {
                    mClient->onDisplayConnected(
                            mClientInfo.mPlaybackSession->getSurfaceTexture(),
                            mClientInfo.mPlaybackSession->width(),
                            mClientInfo.mPlaybackSession->height(),
                            mUsingHDCP
                                ? IRemoteDisplayClient::kDisplayFlagSecure
                                : 0);
                }

                if (0 != property_set("wfd.enable", "1")) {
                    ALOGE("DisplayConnected set wfd.enable property fail.");
                }
                ALOGI("DisplayConnected set wfd.enable property to 1.");

                if (mState == ABOUT_TO_PLAY) {
                    mState = PLAYING;
                }
            } else if (what == PlaybackSession::kWhatSessionDestroyed) {
                disconnectClient2();
            } else {
                CHECK_EQ(what, PlaybackSession::kWhatBinaryData);

                int32_t channel;
                CHECK(msg->findInt32("channel", &channel));

                sp<ABuffer> data;
                CHECK(msg->findBuffer("data", &data));

                CHECK_LE(channel, 0xffu);
                CHECK_LE(data->size(), 0xffffu);

                int32_t sessionID;
                CHECK(msg->findInt32("sessionID", &sessionID));

                char header[4];
                header[0] = '$';
                header[1] = channel;
                header[2] = data->size() >> 8;
                header[3] = data->size() & 0xff;

                mNetSession->sendRequest(
                        sessionID, header, sizeof(header));

                mNetSession->sendRequest(
                        sessionID, data->data(), data->size());
            }
            break;
        }

        case kWhatKeepAlive:
        {
            int32_t sessionID;
            CHECK(msg->findInt32("sessionID", &sessionID));

            if (mClientSessionID != sessionID) {
                // Obsolete event, client is already gone.
                break;
            }

            sendM16(sessionID);
            break;
        }

        case kWhatTeardownTriggerTimedOut:
        {
            if (mState == AWAITING_CLIENT_TEARDOWN) {
                ALOGI("TEARDOWN trigger timed out, forcing disconnection.");

                CHECK_NE(mStopReplyID, 0);
                finishStop();
                break;
            }
            break;
        }

        case kWhatHDCPNotify:
        {
            int32_t msgCode, ext1, ext2;
            CHECK(msg->findInt32("msg", &msgCode));
            CHECK(msg->findInt32("ext1", &ext1));
            CHECK(msg->findInt32("ext2", &ext2));

            ALOGI("Saw HDCP notification code %d, ext1 %d, ext2 %d",
                    msgCode, ext1, ext2);

            switch (msgCode) {
                case HDCPModule::HDCP_INITIALIZATION_COMPLETE:
                {
                    mHDCPInitializationComplete = true;

                    if (mSetupTriggerDeferred) {
                        mSetupTriggerDeferred = false;

                        sendTrigger(mClientSessionID, TRIGGER_SETUP);
                    }
                    break;
                }

                case HDCPModule::HDCP_SHUTDOWN_COMPLETE:
                case HDCPModule::HDCP_SHUTDOWN_FAILED:
                {
                    // Ugly hack to make sure that the call to
                    // HDCPObserver::notify is completely handled before
                    // we clear the HDCP instance and unload the shared
                    // library :(
                    (new AMessage(kWhatFinishStop2, id()))->post(300000ll);
                    break;
                }

                default:
                {
                    ALOGE("HDCP failure, shutting down.");

                    mClient->onDisplayError(
                            IRemoteDisplayClient::kDisplayErrorUnknown);
                    break;
                }
            }
            break;
        }

        case kWhatFinishStop2:
        {
            finishStop2();
            break;
        }

        default:
            TRESPASS();
    }
}
Example #8
0
bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
	char full_line[MAX_FSTAB_LINE_LENGTH], item[MAX_FSTAB_LINE_LENGTH];
	int line_len = Line.size(), index = 0, item_index = 0;
	char* ptr;
	string Flags;

	strncpy(full_line, Line.c_str(), line_len);

	for (index = 0; index < line_len; index++) {
		if (full_line[index] <= 32)
			full_line[index] = '\0';
	}
	Mount_Point = full_line;
	LOGI("Processing '%s'\n", Mount_Point.c_str());
	Backup_Path = Mount_Point;
	index = Mount_Point.size();
	while (index < line_len) {
		while (index < line_len && full_line[index] == '\0')
			index++;
		if (index >= line_len)
			continue;
		ptr = full_line + index;
		if (item_index == 0) {
			// File System
			Fstab_File_System = ptr;
			Current_File_System = ptr;
			item_index++;
		} else if (item_index == 1) {
			// Primary Block Device
			if (Fstab_File_System == "mtd" || Fstab_File_System == "yaffs2") {
				MTD_Name = ptr;
				Find_MTD_Block_Device(MTD_Name);
			} else if (Fstab_File_System == "bml") {
				if (Mount_Point == "/boot")
					MTD_Name = "boot";
				else if (Mount_Point == "/recovery")
					MTD_Name = "recovery";
				Primary_Block_Device = ptr;
				if (*ptr != '/')
					LOGE("Until we get better BML support, you will have to find and provide the full block device path to the BML devices e.g. /dev/block/bml9 instead of the partition name\n");
			} else if (*ptr != '/') {
				if (Display_Error)
					LOGE("Invalid block device on '%s', '%s', %i\n", Line.c_str(), ptr, index);
				else
					LOGI("Invalid block device on '%s', '%s', %i\n", Line.c_str(), ptr, index);
				return 0;
			} else {
				Primary_Block_Device = ptr;
				Find_Real_Block_Device(Primary_Block_Device, Display_Error);
			}
			item_index++;
		} else if (item_index > 1) {
			if (*ptr == '/') {
				// Alternate Block Device
				Alternate_Block_Device = ptr;
				Find_Real_Block_Device(Alternate_Block_Device, Display_Error);
			} else if (strlen(ptr) > 7 && strncmp(ptr, "length=", 7) == 0) {
				// Partition length
				ptr += 7;
				Length = atoi(ptr);
			} else if (strlen(ptr) > 6 && strncmp(ptr, "flags=", 6) == 0) {
				// Custom flags, save for later so that new values aren't overwritten by defaults
				ptr += 6;
				Flags = ptr;
			} else if (strlen(ptr) == 4 && (strncmp(ptr, "NULL", 4) == 0 || strncmp(ptr, "null", 4) == 0 || strncmp(ptr, "null", 4) == 0)) {
				// Do nothing
			} else {
				// Unhandled data
				LOGI("Unhandled fstab information: '%s', %i, line: '%s'\n", ptr, index, Line.c_str());
			}
		}
		while (index < line_len && full_line[index] != '\0')
			index++;
	}

	if (!Is_File_System(Fstab_File_System) && !Is_Image(Fstab_File_System)) {
		if (Display_Error)
			LOGE("Unknown File System: '%s'\n", Fstab_File_System.c_str());
		else
			LOGI("Unknown File System: '%s'\n", Fstab_File_System.c_str());
		return 0;
	} else if (Is_File_System(Fstab_File_System)) {
		Find_Actual_Block_Device();
		Setup_File_System(Display_Error);
		if (Mount_Point == "/system") {
			Display_Name = "System";
			Wipe_Available_in_GUI = true;
		} else if (Mount_Point == "/data") {
			Display_Name = "Data";
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
#ifdef RECOVERY_SDCARD_ON_DATA
			Has_Data_Media = true;
			Is_Storage = true;
			Storage_Path = "/data/media";
			if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
				Make_Dir("/emmc", Display_Error);
				Symlink_Path = "/data/media";
				Symlink_Mount_Point = "/emmc";
			} else {
				Make_Dir("/sdcard", Display_Error);
				Symlink_Path = "/data/media";
				Symlink_Mount_Point = "/sdcard";
			}
#endif
#ifdef TW_INCLUDE_CRYPTO
			Can_Be_Encrypted = true;
			char crypto_blkdev[255];
			property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
			if (strcmp(crypto_blkdev, "error") != 0) {
				DataManager::SetValue(TW_DATA_BLK_DEVICE, Primary_Block_Device);
				DataManager::SetValue(TW_IS_DECRYPTED, 1);
				Is_Encrypted = true;
				Is_Decrypted = true;
				Decrypted_Block_Device = crypto_blkdev;
				LOGI("Data already decrypted, new block device: '%s'\n", crypto_blkdev);
			} else if (!Mount(false)) {
				Is_Encrypted = true;
				Is_Decrypted = false;
				DataManager::SetValue(TW_IS_ENCRYPTED, 1);
				DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
				DataManager::SetValue("tw_crypto_display", "");
			}
	#ifdef RECOVERY_SDCARD_ON_DATA
			if (!Is_Encrypted || (Is_Encrypted && Is_Decrypted))
				Recreate_Media_Folder();
	#endif
#else
	#ifdef RECOVERY_SDCARD_ON_DATA
			Recreate_Media_Folder();
	#endif
#endif
		} else if (Mount_Point == "/cache") {
			Display_Name = "Cache";
			Wipe_Available_in_GUI = true;
			Wipe_During_Factory_Reset = true;
			if (Mount(false) && !TWFunc::Path_Exists("/cache/recovery/.")) {
				string Recreate_Command = "cd /cache && mkdir recovery";
				LOGI("Recreating /cache/recovery folder.\n");
				system(Recreate_Command.c_str());
			}
		} else if (Mount_Point == "/datadata") {
			Wipe_During_Factory_Reset = true;
			Display_Name = "DataData";
			Is_SubPartition = true;
			SubPartition_Of = "/data";
			DataManager::SetValue(TW_HAS_DATADATA, 1);
		} else if (Mount_Point == "/sd-ext") {
			Wipe_During_Factory_Reset = true;
			Display_Name = "SD-Ext";
			Wipe_Available_in_GUI = true;
			Removable = true;
		} else if (Mount_Point == "/boot") {
			Display_Name = "Boot";
			DataManager::SetValue("tw_boot_is_mountable", 1);
		}
#ifdef TW_EXTERNAL_STORAGE_PATH
		if (Mount_Point == EXPAND(TW_EXTERNAL_STORAGE_PATH)) {
			Is_Storage = true;
			Storage_Path = EXPAND(TW_EXTERNAL_STORAGE_PATH);
			Removable = true;
		}
#else
		if (Mount_Point == "/sdcard") {
			Is_Storage = true;
			Storage_Path = "/sdcard";
			Removable = true;
#ifndef RECOVERY_SDCARD_ON_DATA
			Setup_AndSec();
			Mount_Storage_Retry();
#endif
		}
#endif
#ifdef TW_INTERNAL_STORAGE_PATH
		if (Mount_Point == EXPAND(TW_INTERNAL_STORAGE_PATH)) {
			Is_Storage = true;
			Storage_Path = EXPAND(TW_INTERNAL_STORAGE_PATH);
#ifndef RECOVERY_SDCARD_ON_DATA
			Setup_AndSec();
			Mount_Storage_Retry();
#endif
		}
#else
		if (Mount_Point == "/emmc") {
			Is_Storage = true;
			Storage_Path = "/emmc";
#ifndef RECOVERY_SDCARD_ON_DATA
			Setup_AndSec();
			Mount_Storage_Retry();
#endif
		}
#endif
	} else if (Is_Image(Fstab_File_System)) {
		Find_Actual_Block_Device();
		Setup_Image(Display_Error);
	}

	// Process any custom flags
	if (Flags.size() > 0)
		Process_Flags(Flags, Display_Error);

	return true;
}
status_t WifiDisplaySource::onReceiveM3Response(
        int32_t sessionID, const sp<ParsedMessage> &msg) {
    int32_t statusCode;
    if (!msg->getStatusCode(&statusCode)) {
        return ERROR_MALFORMED;
    }

    if (statusCode != 200) {
        return ERROR_UNSUPPORTED;
    }

    sp<Parameters> params =
        Parameters::Parse(msg->getContent(), strlen(msg->getContent()));

    if (params == NULL) {
        return ERROR_MALFORMED;
    }

    AString value;
    if (!params->findParameter("wfd_client_rtp_ports", &value)) {
        ALOGE("Sink doesn't report its choice of wfd_client_rtp_ports.");
        return ERROR_MALFORMED;
    }

    unsigned port0 = 0, port1 = 0;
    if (sscanf(value.c_str(),
               "RTP/AVP/UDP;unicast %u %u mode=play",
               &port0,
               &port1) == 2
        || sscanf(value.c_str(),
               "RTP/AVP/TCP;unicast %u %u mode=play",
               &port0,
               &port1) == 2) {
            if (port0 == 0 || port0 > 65535 || port1 != 0) {
                ALOGE("Sink chose its wfd_client_rtp_ports poorly (%s)",
                      value.c_str());

                return ERROR_MALFORMED;
            }
    } else if (strcmp(value.c_str(), "RTP/AVP/TCP;interleaved mode=play")) {
        ALOGE("Unsupported value for wfd_client_rtp_ports (%s)",
              value.c_str());

        return ERROR_UNSUPPORTED;
    }

    mWfdClientRtpPorts = value;
    mChosenRTPPort = port0;

    if (!params->findParameter("wfd_video_formats", &value)) {
        ALOGE("Sink doesn't report its choice of wfd_video_formats.");
        return ERROR_MALFORMED;
    }

    mSinkSupportsVideo = false;

    if  (!(value == "none")) {
        mSinkSupportsVideo = true;
        if (!mSupportedSinkVideoFormats.parseFormatSpec(value.c_str())) {
            ALOGE("Failed to parse sink provided wfd_video_formats (%s)",
                  value.c_str());

            return ERROR_MALFORMED;
        }

        if (!VideoFormats::PickBestFormat(
                    mSupportedSinkVideoFormats,
                    mSupportedSourceVideoFormats,
                    &mChosenVideoResolutionType,
                    &mChosenVideoResolutionIndex,
                    &mChosenVideoProfile,
                    &mChosenVideoLevel)) {
            ALOGE("Sink and source share no commonly supported video "
                  "formats.");

            return ERROR_UNSUPPORTED;
        }

        size_t width, height, framesPerSecond;
        bool interlaced;
        CHECK(VideoFormats::GetConfiguration(
                    mChosenVideoResolutionType,
                    mChosenVideoResolutionIndex,
                    &width,
                    &height,
                    &framesPerSecond,
                    &interlaced));

        ALOGI("Picked video resolution %u x %u %c%u",
              width, height, interlaced ? 'i' : 'p', framesPerSecond);

        ALOGI("Picked AVC profile %d, level %d",
              mChosenVideoProfile, mChosenVideoLevel);
    } else {
        ALOGI("Sink doesn't support video at all.");
    }

    if (!params->findParameter("wfd_audio_codecs", &value)) {
        ALOGE("Sink doesn't report its choice of wfd_audio_codecs.");
        return ERROR_MALFORMED;
    }

    mSinkSupportsAudio = false;

    if  (!(value == "none")) {
        mSinkSupportsAudio = true;

        uint32_t modes;
        GetAudioModes(value.c_str(), "AAC", &modes);

        bool supportsAAC = (modes & 1) != 0;  // AAC 2ch 48kHz

        GetAudioModes(value.c_str(), "LPCM", &modes);

        bool supportsPCM = (modes & 2) != 0;  // LPCM 2ch 48kHz

        char val[PROPERTY_VALUE_MAX];
        if (supportsPCM
                && property_get("media.wfd.use-pcm-audio", val, NULL)
                && (!strcasecmp("true", val) || !strcmp("1", val))) {
            ALOGI("Using PCM audio.");
            mUsingPCMAudio = true;
        } else if (supportsAAC) {
            ALOGI("Using AAC audio.");
            mUsingPCMAudio = false;
        } else if (supportsPCM) {
            ALOGI("Using PCM audio.");
            mUsingPCMAudio = true;
        } else {
            ALOGI("Sink doesn't support an audio format we do.");
            return ERROR_UNSUPPORTED;
        }
    } else {
        ALOGI("Sink doesn't support audio at all.");
    }

    if (!mSinkSupportsVideo && !mSinkSupportsAudio) {
        ALOGE("Sink supports neither video nor audio...");
        return ERROR_UNSUPPORTED;
    }

    mUsingHDCP = false;
    if (!params->findParameter("wfd_content_protection", &value)) {
        ALOGI("Sink doesn't appear to support content protection.");
    } else if (value == "none") {
        ALOGI("Sink does not support content protection.");
    } else {
        mUsingHDCP = true;

        bool isHDCP2_0 = false;
        if (value.startsWith("HDCP2.0 ")) {
            isHDCP2_0 = true;
        } else if (!value.startsWith("HDCP2.1 ")) {
            ALOGE("malformed wfd_content_protection: '%s'", value.c_str());

            return ERROR_MALFORMED;
        }

        int32_t hdcpPort;
        if (!ParsedMessage::GetInt32Attribute(
                    value.c_str() + 8, "port", &hdcpPort)
                || hdcpPort < 1 || hdcpPort > 65535) {
            return ERROR_MALFORMED;
        }

        mIsHDCP2_0 = isHDCP2_0;
        mHDCPPort = hdcpPort;

        status_t err = makeHDCP();
        if (err != OK) {
            ALOGE("Unable to instantiate HDCP component. "
                  "Not using HDCP after all.");

            mUsingHDCP = false;
        }
    }

    return sendM4(sessionID);
}
int update_ctrl_interface(const char *config_file) {

    int srcfd, destfd;
    int nread;
    char ifc[PROPERTY_VALUE_MAX];
    char *pbuf;
    char *sptr;
    struct stat sb;
    int ret;

    if (stat(config_file, &sb) != 0)
        return -1;

    pbuf = malloc(sb.st_size + PROPERTY_VALUE_MAX);
    if (!pbuf)
        return 0;
    srcfd = TEMP_FAILURE_RETRY(open(config_file, O_RDONLY));
    if (srcfd < 0) {
        ALOGE("Cannot open \"%s\": %s", config_file, strerror(errno));
        free(pbuf);
        return 0;
    }
    nread = TEMP_FAILURE_RETRY(read(srcfd, pbuf, sb.st_size));
    close(srcfd);
    if (nread < 0) {
        ALOGE("Cannot read \"%s\": %s", config_file, strerror(errno));
        free(pbuf);
        return 0;
    }

    if (!strcmp(config_file, SUPP_CONFIG_FILE)) {
        property_get("wifi.interface", ifc, WIFI_TEST_INTERFACE);
    } else {
        strcpy(ifc, CONTROL_IFACE_PATH);
    }
    /* Assume file is invalid to begin with */
    ret = -1;
    /*
     * if there is a "ctrl_interface=<value>" entry, re-write it ONLY if it is
     * NOT a directory.  The non-directory value option is an Android add-on
     * that allows the control interface to be exchanged through an environment
     * variable (initialized by the "init" program when it starts a service
     * with a "socket" option).
     *
     * The <value> is deemed to be a directory if the "DIR=" form is used or
     * the value begins with "/".
     */
    if ((sptr = strstr(pbuf, "ctrl_interface="))) {
        ret = 0;
        if ((!strstr(pbuf, "ctrl_interface=DIR=")) &&
                (!strstr(pbuf, "ctrl_interface=/"))) {
            char *iptr = sptr + strlen("ctrl_interface=");
            int ilen = 0;
            int mlen = strlen(ifc);
            int nwrite;
            if (strncmp(ifc, iptr, mlen) != 0) {
                ALOGE("ctrl_interface != %s", ifc);
                while (((ilen + (iptr - pbuf)) < nread) && (iptr[ilen] != '\n'))
                    ilen++;
                mlen = ((ilen >= mlen) ? ilen : mlen) + 1;
                memmove(iptr + mlen, iptr + ilen + 1, nread - (iptr + ilen + 1 - pbuf));
                memset(iptr, '\n', mlen);
                memcpy(iptr, ifc, strlen(ifc));
                destfd = TEMP_FAILURE_RETRY(open(config_file, O_RDWR, 0660));
                if (destfd < 0) {
                    ALOGE("Cannot update \"%s\": %s", config_file, strerror(errno));
                    free(pbuf);
                    return -1;
                }
                TEMP_FAILURE_RETRY(write(destfd, pbuf, nread + mlen - ilen -1));
                close(destfd);
            }
        }
    }
    free(pbuf);
    return ret;
}
int wifi_start_supplicant(int p2p_supported)
{
    char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
    int count = 200; /* wait at most 20 seconds for completion */
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    const prop_info *pi;
    unsigned serial = 0, i;
#endif

    if (p2p_supported) {
        strcpy(supplicant_name, P2P_SUPPLICANT_NAME);
        strcpy(supplicant_prop_name, P2P_PROP_NAME);

        /* Ensure p2p config file is created */
        if (ensure_config_file_exists(P2P_CONFIG_FILE) < 0) {
            ALOGE("Failed to create a p2p config file");
            return -1;
        }

    } else {
        strcpy(supplicant_name, SUPPLICANT_NAME);
        strcpy(supplicant_prop_name, SUPP_PROP_NAME);
    }

    /* Check whether already running */
    if (property_get(supplicant_prop_name, supp_status, NULL)
            && strcmp(supp_status, "running") == 0) {
        return 0;
    }

    /* Before starting the daemon, make sure its config file exists */
    if (ensure_config_file_exists(SUPP_CONFIG_FILE) < 0) {
        ALOGE("Wi-Fi will not be enabled");
        return -1;
    }

    if (ensure_entropy_file_exists() < 0) {
        ALOGE("Wi-Fi entropy file was not created");
    }

    /* Clear out any stale socket files that might be left over. */
    wpa_ctrl_cleanup();

    /* Reset sockets used for exiting from hung state */
    exit_sockets[0] = exit_sockets[1] = -1;

#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    /*
     * Get a reference to the status property, so we can distinguish
     * the case where it goes stopped => running => stopped (i.e.,
     * it start up, but fails right away) from the case in which
     * it starts in the stopped state and never manages to start
     * running at all.
     */
    pi = __system_property_find(supplicant_prop_name);
    if (pi != NULL) {
        serial = __system_property_serial(pi);
    }
#endif
    property_get("wifi.interface", primary_iface, WIFI_TEST_INTERFACE);

    property_set("ctl.start", supplicant_name);
    sched_yield();

    while (count-- > 0) {
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
        if (pi == NULL) {
            pi = __system_property_find(supplicant_prop_name);
        }
        if (pi != NULL) {
            __system_property_read(pi, NULL, supp_status);
            if (strcmp(supp_status, "running") == 0) {
                return 0;
            } else if (__system_property_serial(pi) != serial &&
                    strcmp(supp_status, "stopped") == 0) {
                return -1;
            }
        }
#else
        if (property_get(supplicant_prop_name, supp_status, NULL)) {
            if (strcmp(supp_status, "running") == 0)
                return 0;
        }
#endif
        usleep(100000);
    }
    return -1;
}
int adb_main(int is_daemon)
{
#if !ADB_HOST
    int secure = 0;
    char value[PROPERTY_VALUE_MAX];

    // prevent the OOM killer from killing us
    char text[64];
    snprintf(text, sizeof text, "/proc/%d/oom_adj", (int)getpid());
    int fd = adb_open(text, O_WRONLY);
    if (fd >= 0) {
        // -17 should make us immune to OOM
        snprintf(text, sizeof text, "%d", -17);
        adb_write(fd, text, strlen(text));
        adb_close(fd);
    } else {
        D("adb: unable to open %s\n", text);
    }
#endif

    atexit(adb_cleanup);
#ifdef HAVE_WIN32_PROC
    SetConsoleCtrlHandler( ctrlc_handler, TRUE );
#elif defined(HAVE_FORKEXEC)
    signal(SIGCHLD, sigchld_handler);
    signal(SIGPIPE, SIG_IGN);
#endif

    init_transport_registration();


#if ADB_HOST
    HOST = 1;
    usb_init();
    local_init();

    if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
        exit(1);
    }
#else
    /* run adbd in secure mode if ro.secure is set and
    ** we are not in the emulator
    */
    property_get("ro.kernel.qemu", value, "");
    if (strcmp(value, "1") != 0) {
        property_get("ro.secure", value, "");
        if (strcmp(value, "1") == 0) {
            // don't run as root if ro.secure is set...
            secure = 1;

            // ... except we allow running as root in userdebug builds if the
            // service.adb.root property has been set by the "adb root" command
            property_get("ro.debuggable", value, "");
            if (strcmp(value, "1") == 0) {
                property_get("service.adb.root", value, "");
                if (strcmp(value, "1") == 0) {
                    secure = 0;
                }
            }
        }
    }

    /* don't listen on port 5037 if we are running in secure mode */
    /* don't run as root if we are running in secure mode */
    if (secure) {
        /* add extra groups:
        ** AID_ADB to access the USB driver
        ** AID_LOG to read system logs (adb logcat)
        ** AID_INPUT to diagnose input issues (getevent)
        ** AID_INET to diagnose network issues (netcfg, ping)
        ** AID_GRAPHICS to access the frame buffer
        ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
        */
        gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
                           AID_NET_BT, AID_NET_BT_ADMIN
                         };
        setgroups(sizeof(groups)/sizeof(groups[0]), groups);

        /* then switch user and group to "shell" */
        setgid(AID_SHELL);
        setuid(AID_SHELL);

        D("Local port 5037 disabled\n");
    } else {
        if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
            exit(1);
        }
    }

    /* for the device, start the usb transport if the
    ** android usb device exists, otherwise start the
    ** network transport.
    */
    if(access("/dev/android_adb", F_OK) == 0 ||
            access("/dev/android", F_OK) == 0) {
        usb_init();
    } else {
        local_init();
    }
    init_jdwp();
#endif

    if (is_daemon)
    {
        // inform our parent that we are up and running.
#ifdef HAVE_WIN32_PROC
        DWORD  count;
        WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );
#elif defined(HAVE_FORKEXEC)
        fprintf(stderr, "OK\n");
#endif
        start_logging();
    }

    fdevent_loop();

    usb_cleanup();

    return 0;
}
Example #13
0
int main(int argc, char *argv[])
{
    struct stat st;
    static int socket_serv_fd = -1;
    char buf[64], shell[PATH_MAX], *result, debuggable[PROPERTY_VALUE_MAX];
    char enabled[PROPERTY_VALUE_MAX], build_type[PROPERTY_VALUE_MAX];
    char root_settings[PROPERTY_VALUE_MAX];
    int i, dballow;
    mode_t orig_umask;

    for (i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--command")) {
            if (++i < argc) {
                su_to.command = argv[i];
            } else {
                usage();
            }
        } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--shell")) {
            if (++i < argc) {
                strncpy(shell, argv[i], sizeof(shell));
                shell[sizeof(shell) - 1] = 0;
            } else {
                usage();
            }
        } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
            printf("%s\n", VERSION);
            exit(EXIT_SUCCESS);
        } else if (!strcmp(argv[i], "-V")) {
            printf("%d\n", VERSION_CODE);
            exit(EXIT_SUCCESS);
        } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
            usage();
        } else if (!strcmp(argv[i], "-") || !strcmp(argv[i], "-l") ||
                !strcmp(argv[i], "--login")) {
            ++i;
            break;
        } else {
            break;
        }
    }
    if (i < argc-1) {
        usage();
    }
    if (i == argc-1) {
        struct passwd *pw;
        pw = getpwnam(argv[i]);
        if (!pw) {
            su_to.uid = atoi(argv[i]);
        } else {
            su_to.uid = pw->pw_uid;
        }
    }

    if (from_init(&su_from) < 0) {
        deny();
    }

    property_get("ro.debuggable", debuggable, "0");
    property_get(ROOT_ACCESS_PROPERTY, enabled, ROOT_ACCESS_DEFAULT);
    property_get("ro.build.type", build_type, "");
    property_get(ROOT_SETTINGS_PROPERTY, root_settings, "");

    orig_umask = umask(027);

    // Root Settings-specific behavior
    if (strcmp("1", root_settings) == 0) {
        // only allow su on debuggable builds
        if (strcmp("1", debuggable) != 0) {
            LOGE("Root access is disabled on non-debug builds");
            deny();
        }

        // enforce persist.sys.root_access on non-eng builds
        if (strcmp("eng", build_type) != 0 &&
               (atoi(enabled) & 1) != 1 ) {
            LOGE("Root access is disabled by system setting - enable it under settings -> developer options");
            deny();
        }

        // disallow su in a shell if appropriate
        if (su_from.uid == AID_SHELL && (atoi(enabled) == 1)) {
            LOGE("Root access is disabled by a system setting - enable it under settings -> developer options");
            deny();
        }
    }

    if (su_from.uid == AID_ROOT || su_from.uid == AID_SHELL)
        allow(shell, orig_umask);

    if (stat(REQUESTOR_DATA_PATH, &st) < 0) {
        PLOGE("stat");
        deny();
    }

    if (st.st_gid != st.st_uid)
    {
        LOGE("Bad uid/gid %d/%d for Superuser Requestor application",
                (int)st.st_uid, (int)st.st_gid);
        deny();
    }

    if (mkdir(REQUESTOR_CACHE_PATH, 0770) >= 0) {
        chown(REQUESTOR_CACHE_PATH, st.st_uid, st.st_gid);
    }

    setgroups(0, NULL);
    setegid(st.st_gid);
    seteuid(st.st_uid);

    LOGE("sudb - Opening database");
    db = database_init();
    if (!db) {
        LOGE("sudb - Could not open database, prompt user");
        // if the database could not be opened, we can assume we need to
        // prompt the user
        dballow = DB_INTERACTIVE;
    } else {
        LOGE("sudb - Database opened");
        dballow = database_check(db, &su_from, &su_to);
        // Close the database, we're done with it. If it stays open,
        // it will cause problems
        sqlite3_close(db);
        db = NULL;
        LOGE("sudb - Database closed");
    }

    switch (dballow) {
        case DB_DENY: deny();
        case DB_ALLOW: allow(shell, orig_umask);
        case DB_INTERACTIVE: break;
        default: deny();
    }
    
    socket_serv_fd = socket_create_temp();
    if (socket_serv_fd < 0) {
        deny();
    }

    signal(SIGHUP, cleanup_signal);
    signal(SIGPIPE, cleanup_signal);
    signal(SIGTERM, cleanup_signal);
    signal(SIGABRT, cleanup_signal);
    atexit(cleanup);

    if (send_intent(&su_from, &su_to, socket_path, -1, 0) < 0) {
        deny();
    }

    if (socket_receive_result(socket_serv_fd, buf, sizeof(buf)) < 0) {
        deny();
    }

    close(socket_serv_fd);
    socket_cleanup();

    result = buf;

    if (!strcmp(result, "DENY")) {
        deny();
    } else if (!strcmp(result, "ALLOW")) {
        allow(shell, orig_umask);
    } else {
        LOGE("unknown response from Superuser Requestor: %s", result);
        deny();
    }

    deny();
    return -1;
}
Example #14
0
// Foreground waits for exit of the three main persistent threads that
// are started here.  The three threads are created to manage UNIX
// domain client sockets for writing, reading and controlling the user
// space logger.  Additional transitory per-client threads are created
// for each reader once they register.
int main() {
    int fdDmesg = -1;
    char dmesg[PROPERTY_VALUE_MAX];
    property_get("logd.auditd.dmesg", dmesg, "1");
    if (atol(dmesg)) {
        fdDmesg = open("/dev/kmsg", O_WRONLY);
    }

    if (drop_privs() != 0) {
        return -1;
    }

    // Serves the purpose of managing the last logs times read on a
    // socket connection, and as a reader lock on a range of log
    // entries.

    LastLogTimes *times = new LastLogTimes();

    // LogBuffer is the object which is responsible for holding all
    // log entries.

    LogBuffer *logBuf = new LogBuffer(times);

    char dgram_qlen_statistics[PROPERTY_VALUE_MAX];
    property_get("logd.dgram_qlen.statistics", dgram_qlen_statistics, "");
    if (atol(dgram_qlen_statistics)) {
        logBuf->enableDgramQlenStatistics();
    }

    // LogReader listens on /dev/socket/logdr. When a client
    // connects, log entries in the LogBuffer are written to the client.

    LogReader *reader = new LogReader(logBuf);
    if (reader->startListener()) {
        exit(1);
    }

    // LogListener listens on /dev/socket/logdw for client
    // initiated log messages. New log entries are added to LogBuffer
    // and LogReader is notified to send updates to connected clients.

    LogListener *swl = new LogListener(logBuf, reader);
    // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
    if (swl->startListener(300)) {
        exit(1);
    }

    // Command listener listens on /dev/socket/logd for incoming logd
    // administrative commands.

    CommandListener *cl = new CommandListener(logBuf, reader, swl);
    if (cl->startListener()) {
        exit(1);
    }

    // LogAudit listens on NETLINK_AUDIT socket for selinux
    // initiated log messages. New log entries are added to LogBuffer
    // and LogReader is notified to send updates to connected clients.

    // failure is an option ... messages are in dmesg (required by standard)
    LogAudit *al = new LogAudit(logBuf, reader, fdDmesg);
    if (al->startListener()) {
        delete al;
        close(fdDmesg);
    }

    pause();
    exit(0);
}
Example #15
0
ALSAMixer::ALSAMixer()
{
    int err;

    initMixer (&mMixer[SND_PCM_STREAM_PLAYBACK], "AndroidOut");
    initMixer (&mMixer[SND_PCM_STREAM_CAPTURE], "AndroidIn");

    snd_mixer_selem_id_t *sid;
    snd_mixer_selem_id_alloca(&sid);

    for (int i = 0; i <= SND_PCM_STREAM_LAST; i++) {

        if (!mMixer[i]) continue;

        mixer_info_t *info = mixerMasterProp[i].mInfo = new mixer_info_t;

        property_get (mixerMasterProp[i].propName,
                      info->name,
                      mixerMasterProp[i].propDefault);
        ZJFLOGD("mixerMasterProp[%d].propName is %s, info->name is %s, mixerMasterProp[%d].propDefault is %s", i, mixerMasterProp[i].propName, info->name, i, mixerMasterProp[i].propDefault);
        for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]);
             elem;
             elem = snd_mixer_elem_next(elem)) {
            ZJFLOGD("set mixer elem for mixer:%d", i);

            if (!snd_mixer_selem_is_active(elem))
                continue;

            snd_mixer_selem_get_id(elem, sid);

            // Find PCM playback volume control element.
            const char *elementName = snd_mixer_selem_id_get_name(sid);

            ZJFLOGD("set mixer elem for mixer:%d, ele name is %s", i, elementName);
            if (info->elem == NULL &&
                strcmp(elementName, info->name) == 0 &&
                hasVolume[i] (elem)) {

                info->elem = elem;
                getVolumeRange[i] (elem, &info->min, &info->max);
                info->volume = info->max;
                setVol[i] (elem, info->volume);
                if (i == SND_PCM_STREAM_PLAYBACK &&
                    snd_mixer_selem_has_playback_switch (elem))
                    snd_mixer_selem_set_playback_switch_all (elem, 1);
                break;
            }
        }

        ZJFLOGD("Mixer:%d master '%s' %s.", i, info->name, info->elem ? "found" : "not found");

        for (int j = 0; mixerProp[j][i].device; j++) {

            mixer_info_t *info = mixerProp[j][i].mInfo = new mixer_info_t;

            property_get (mixerProp[j][i].propName,
                          info->name,
                          mixerProp[j][i].propDefault);
            ZJFLOGD("mixerProp[%d][%d].propName is %s, info->name is %s, mixerProp[%d][%d].propDefault is %s", j, i, mixerProp[j][i].propName, info->name, j, i, mixerProp[j][i].propDefault);

            for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]);
                 elem;
                 elem = snd_mixer_elem_next(elem)) {

                ZJFLOGD("set mixer elem for mixer:%d", i);
                if (!snd_mixer_selem_is_active(elem))
                    continue;

                snd_mixer_selem_get_id(elem, sid);

                // Find PCM playback volume control element.
                const char *elementName = snd_mixer_selem_id_get_name(sid);

                ZJFLOGD("set mixer elem for mixer:%d, ele name is %s", i, elementName);
               if (info->elem == NULL &&
                    strcmp(elementName, info->name) == 0 &&
                    hasVolume[i] (elem)) {

                    info->elem = elem;
                    getVolumeRange[i] (elem, &info->min, &info->max);
                    info->volume = info->max;
                    setVol[i] (elem, info->volume);
                    if (i == SND_PCM_STREAM_PLAYBACK &&
                        snd_mixer_selem_has_playback_switch (elem))
                        snd_mixer_selem_set_playback_switch_all (elem, 1);
                    break;
                }
            }
            ZJFLOGD("mixer:%d route '%s' %s.", i, info->name, info->elem ? "found" : "not found");
        }
    }
    LOGV("mixer initialized.");
}
int main(void)
{
	char key_loc[PROPERTY_VALUE_MAX];
	char blk_dev[PROPERTY_VALUE_MAX];
	char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
	struct stat st;
	struct crypt_mnt_ftr crypt_ftr;
	int fdout;

	printf("This tool comes with no warranties whatsoever.\n");
	printf("http://teamw.in\n\n");
	strcpy(fstab_filename, FSTAB_PREFIX);
	property_get("ro.hardware", fstab_filename + sizeof(FSTAB_PREFIX) - 1, "");

	if (stat(fstab_filename, &st) != 0) {
		printf("Cannot locate fstab file '%s'\n", fstab_filename);
		return -1;
	}

	fstab = fs_mgr_read_fstab(fstab_filename);
	if (!fstab) {
		printf("failed to open %s\n", fstab_filename);
		return -1;
	}

	fs_mgr_get_crypt_info(fstab, key_loc, blk_dev, sizeof(blk_dev));

	if (get_crypt_ftr_and_key(&crypt_ftr)) {
		printf("Error getting crypt footer and key\n");
		return -1;
	}

	if ( (fdout = open("/footerfile", O_WRONLY | O_CREAT, 0644)) < 0) {
		printf("Cannot open output file /footerfile\n");
		return -1;
	}
	if (write(fdout, (void*) &crypt_ftr, sizeof(struct crypt_mnt_ftr)) != sizeof(struct crypt_mnt_ftr)) {
		printf("Failed to write footer.\n");
	}
	close(fdout);

	if (!strcmp(key_loc, KEY_IN_FOOTER)) {
		unsigned int nr_sec, cnt;
		off64_t off = 0;
		char buffer[CRYPT_FOOTER_OFFSET];
		int fd;

		printf("\n\nDumping footer from '%s'...\n", blk_dev);
		if ( (fd = open(blk_dev, O_RDONLY)) < 0) {
			printf("Cannot open real block device %s\n", blk_dev);
			return -1;
		}

		if ((nr_sec = get_blkdev_size(fd))) {
			off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
		} else {
			printf("Cannot get size of block device %s\n", blk_dev);
			close(fd);
			return -1;
		}
		printf("Size is %llu, offset is %llu\n", ((off64_t)nr_sec * 512), off);
		if (lseek64(fd, off, SEEK_SET) == -1) {
			printf("Cannot seek to real block device footer\n");
			close(fd);
			return -1;
		}

		if ( (cnt = read(fd, buffer, sizeof(buffer))) != sizeof(buffer)) {
			printf("Cannot read real block device footer\n");
			close(fd);
			return -1;
		}
		close(fd);
		if ( (fdout = open("/footerdump", O_WRONLY | O_CREAT, 0644)) < 0) {
			printf("Cannot open output file /footerdump\n");
			return -1;
		}
		if (write(fdout, buffer, sizeof(buffer)) != sizeof(buffer)) {
			printf("Failed to write footer.\n");
		}
		close(fdout);
	}

	return 0;
}
Example #17
0
void ui_init(void)
{
    ui_has_initialized = 1;
    gr_init();
    ev_init(input_callback, NULL);
#ifdef BOARD_TOUCH_RECOVERY
    touch_init();
#endif

    text_col = text_row = 0;
    text_rows = gr_fb_height() / CHAR_HEIGHT;
    max_menu_rows = text_rows - MIN_LOG_ROWS;
#ifdef BOARD_TOUCH_RECOVERY
    max_menu_rows = get_max_menu_rows(max_menu_rows);
#endif
    if (max_menu_rows > MENU_MAX_ROWS)
        max_menu_rows = MENU_MAX_ROWS;
    if (text_rows > MAX_ROWS) text_rows = MAX_ROWS;
    text_top = 1;

    text_cols = gr_fb_width() / CHAR_WIDTH;
    if (text_cols > MAX_COLS - 1) text_cols = MAX_COLS - 1;

    int i;
    for (i = 0; BITMAPS[i].name != NULL; ++i) {
        int result = res_create_surface(BITMAPS[i].name, BITMAPS[i].surface);
        if (result < 0) {
            LOGE("Missing bitmap %s\n(Code %d)\n", BITMAPS[i].name, result);
        }
    }

    gProgressBarIndeterminate = malloc(ui_parameters.indeterminate_frames *
                                       sizeof(gr_surface));
    for (i = 0; i < ui_parameters.indeterminate_frames; ++i) {
        char filename[40];
        // "indeterminate01.png", "indeterminate02.png", ...
        sprintf(filename, "indeterminate%02d", i+1);
        int result = res_create_surface(filename, gProgressBarIndeterminate+i);
        if (result < 0) {
            LOGE("Missing bitmap %s\n(Code %d)\n", filename, result);
        }
    }

    if (ui_parameters.installing_frames > 0) {
        gInstallationOverlay = malloc(ui_parameters.installing_frames *
                                      sizeof(gr_surface));
        for (i = 0; i < ui_parameters.installing_frames; ++i) {
            char filename[40];
            // "icon_installing_overlay01.png",
            // "icon_installing_overlay02.png", ...
            sprintf(filename, "icon_installing_overlay%02d", i+1);
            int result = res_create_surface(filename, gInstallationOverlay+i);
            if (result < 0) {
                LOGE("Missing bitmap %s\n(Code %d)\n", filename, result);
            }
        }

        // Adjust the offset to account for the positioning of the
        // base image on the screen.
        if (gBackgroundIcon[BACKGROUND_ICON_INSTALLING] != NULL) {
            gr_surface bg = gBackgroundIcon[BACKGROUND_ICON_INSTALLING];
            ui_parameters.install_overlay_offset_x +=
                (gr_fb_width() - gr_get_width(bg)) / 2;
            ui_parameters.install_overlay_offset_y +=
                (gr_fb_height() - gr_get_height(bg)) / 2;
        }
    } else {
        gInstallationOverlay = NULL;
    }

    char enable_key_repeat[PROPERTY_VALUE_MAX];
    property_get("ro.cwm.enable_key_repeat", enable_key_repeat, "");
    if (!strcmp(enable_key_repeat, "true") || !strcmp(enable_key_repeat, "1")) {
        boardEnableKeyRepeat = 1;

        char key_list[PROPERTY_VALUE_MAX];
        property_get("ro.cwm.repeatable_keys", key_list, "");
        if (strlen(key_list) == 0) {
            boardRepeatableKeys[boardNumRepeatableKeys++] = KEY_UP;
            boardRepeatableKeys[boardNumRepeatableKeys++] = KEY_DOWN;
            boardRepeatableKeys[boardNumRepeatableKeys++] = KEY_VOLUMEUP;
            boardRepeatableKeys[boardNumRepeatableKeys++] = KEY_VOLUMEDOWN;
        } else {
            char *pch = strtok(key_list, ",");
            while (pch != NULL) {
                boardRepeatableKeys[boardNumRepeatableKeys++] = atoi(pch);
                pch = strtok(NULL, ",");
            }
        }
    }

    pthread_t t;
    pthread_create(&t, NULL, progress_thread, NULL);
    pthread_create(&t, NULL, input_thread, NULL);
}
int dexopt(const char *apk_path, uid_t uid, int is_public)
{
    struct utimbuf ut;
    struct stat apk_stat, dex_stat;
    char dex_path[PKG_PATH_MAX];
    char dexopt_flags[PROPERTY_VALUE_MAX];
    char *end;
    int res, zip_fd=-1, odex_fd=-1;

        /* Before anything else: is there a .odex file?  If so, we have
         * pre-optimized the apk and there is nothing to do here.
         */
    if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
        return -1;
    }

    /* platform-specific flags affecting optimization and verification */
    property_get("dalvik.vm.dexopt-flags", dexopt_flags, "");

    strcpy(dex_path, apk_path);
    end = strrchr(dex_path, '.');
    if (end != NULL) {
        strcpy(end, ".odex");
        if (stat(dex_path, &dex_stat) == 0) {
            return 0;
        }
    }

    if (create_cache_path(dex_path, apk_path)) {
        return -1;
    }

    memset(&apk_stat, 0, sizeof(apk_stat));
    stat(apk_path, &apk_stat);

    zip_fd = open(apk_path, O_RDONLY, 0);
    if (zip_fd < 0) {
        LOGE("dexopt cannot open '%s' for input\n", apk_path);
        return -1;
    }

    unlink(dex_path);
    odex_fd = open(dex_path, O_RDWR | O_CREAT | O_EXCL, 0644);
    if (odex_fd < 0) {
        LOGE("dexopt cannot open '%s' for output\n", dex_path);
        goto fail;
    }
    if (fchown(odex_fd, AID_SYSTEM, uid) < 0) {
        LOGE("dexopt cannot chown '%s'\n", dex_path);
        goto fail;
    }
    if (fchmod(odex_fd,
               S_IRUSR|S_IWUSR|S_IRGRP |
               (is_public ? S_IROTH : 0)) < 0) {
        LOGE("dexopt cannot chmod '%s'\n", dex_path);
        goto fail;
    }

    LOGD("DexInv: --- BEGIN '%s' ---\n", apk_path);

    pid_t pid;
    pid = fork();
    if (pid == 0) {
        /* child -- drop privileges before continuing */
        if (setgid(uid) != 0) {
            LOGE("setgid(%d) failed during dexopt\n", uid);
            exit(64);
        }
        if (setuid(uid) != 0) {
            LOGE("setuid(%d) during dexopt\n", uid);
            exit(65);
        }
        if (flock(odex_fd, LOCK_EX | LOCK_NB) != 0) {
            LOGE("flock(%s) failed: %s\n", dex_path, strerror(errno));
            exit(66);
        }

        run_dexopt(zip_fd, odex_fd, apk_path, dexopt_flags);
        exit(67);   /* only get here on exec failure */
    } else {
        res = wait_dexopt(pid, apk_path);
        if (res != 0) {
            LOGE("dexopt failed on '%s' res = %d\n", dex_path, res);
            goto fail;
        }
    }

    ut.actime = apk_stat.st_atime;
    ut.modtime = apk_stat.st_mtime;
    utime(dex_path, &ut);
    
    close(odex_fd);
    close(zip_fd);
    return 0;

fail:
    if (odex_fd >= 0) {
        close(odex_fd);
        unlink(dex_path);
    }
    if (zip_fd >= 0) {
        close(zip_fd);
    }
    return -1;
}
Example #19
0
bool expand_props(const std::string& src, std::string* dst) {
    const char* src_ptr = src.c_str();

    if (!dst) {
        return false;
    }

    /* - variables can either be $x.y or ${x.y}, in case they are only part
     *   of the string.
     * - will accept $$ as a literal $.
     * - no nested property expansion, i.e. ${foo.${bar}} is not supported,
     *   bad things will happen
     * - ${x.y:-default} will return default value if property empty.
     */
    while (*src_ptr) {
        const char* c;

        c = strchr(src_ptr, '$');
        if (!c) {
            dst->append(src_ptr);
            return true;
        }

        dst->append(src_ptr, c);
        c++;

        if (*c == '$') {
            dst->push_back(*(c++));
            src_ptr = c;
            continue;
        } else if (*c == '\0') {
            return true;
        }

        std::string prop_name;
        std::string def_val;
        if (*c == '{') {
            c++;
            const char* end = strchr(c, '}');
            if (!end) {
                // failed to find closing brace, abort.
                LOG(ERROR) << "unexpected end of string in '" << src << "', looking for }";
                return false;
            }
            prop_name = std::string(c, end);
            c = end + 1;
            size_t def = prop_name.find(":-");
            if (def < prop_name.size()) {
                def_val = prop_name.substr(def + 2);
                prop_name = prop_name.substr(0, def);
            }
        } else {
            prop_name = c;
            LOG(ERROR) << "using deprecated syntax for specifying property '" << c << "', use ${name} instead";
            c += prop_name.size();
        }

        if (prop_name.empty()) {
            LOG(ERROR) << "invalid zero-length property name in '" << src << "'";
            return false;
        }

        std::string prop_val = property_get(prop_name.c_str());
        if (prop_val.empty()) {
            if (def_val.empty()) {
                LOG(ERROR) << "property '" << prop_name << "' doesn't exist while expanding '" << src << "'";
                return false;
            }
            prop_val = def_val;
        }

        dst->append(prop_val);
        src_ptr = c;
    }

    return true;
}
Example #20
0
int nandroid_backup(const char* backup_path)
{
    nandroid_backup_bitfield = 0;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    refresh_default_backup_handler();
    
    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("Can't mount backup path.\n");
    }
    
    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume)
        return print_and_error("Unable to find volume for backup path.\n");
    if (is_data_media_volume_path(volume->mount_point))
        volume = volume_for_path("/data");
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("Unable to stat backup path.\n");
        uint64_t bavail = s.f_bavail;
        uint64_t bsize = s.f_bsize;
        uint64_t sdcard_free = bavail * bsize;
        uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
        ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
        if (sdcard_free_mb < 150)
            ui_print("There may not be enough free space to complete backup... continuing...\n");
    }
    char tmp[PATH_MAX];
    ensure_directory(backup_path);

    if (backup_boot && 0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (backup_recovery && 0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (backup_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    //2 copies of efs are made: tarball and raw backup
    if (backup_efs) {
        //first backup in raw format, returns 0 on success (or if skipped), else 1
        if (0 != custom_backup_raw_handler(backup_path, "/efs")) {
            ui_print("EFS raw image backup failed! Trying tar backup...\n");
        }
        //second backup in tar format
        sprintf(tmp, "%s/efs_tar", backup_path);
        ensure_directory(tmp);
        if (0 != (ret = nandroid_backup_partition(tmp, "/efs")))
            return ret;
    }
    
    if (backup_modem) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/modem")))
            return ret;
    }

    if (backup_system && 0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;


    if (backup_preload) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) {
            ui_print("Failed to backup /preload!\n");
            return ret;
        }
    } else
#ifdef PHILZ_TOUCH_RECOVERY
            if (quick_toggle_chk(ENABLE_PRELOAD_FILE, 0))
#endif
    {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) {
            ui_print("Failed to backup preload! Try to disable it.\n");
            ui_print("Skipping /preload...\n");
            //return ret;
        }
    }

    if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) {
        ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n");
    }
    else {
        if (backup_data && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (backup_cache && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    if (backup_sdext) {
        vol = volume_for_path("/sd-ext");
        if (vol == NULL || 0 != stat(vol->device, &s))
        {
            ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
        }
        else
        {
            if (0 != ensure_path_mounted("/sd-ext"))
                ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n");
            else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
                return ret;
        }
    }

#ifdef PHILZ_TOUCH_RECOVERY
    if (!quick_toggle_chk(DISABLE_NANDROID_MD5_FILE, 0))
#endif
    {
        ui_print("Generating md5 sum...\n");
        sprintf(tmp, "nandroid-md5.sh %s", backup_path);
        if (0 != (ret = __system(tmp))) {
            ui_print("Error while generating md5 sum!\n");
            return ret;
        }
    }

    sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path);
    __system(tmp);
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
status_t WifiDisplaySource::sendM4(int32_t sessionID) {
    // wfd_video_formats:
    // 1 byte "native"
    // 1 byte "preferred-display-mode-supported" 0 or 1
    // one or more avc codec structures
    //   1 byte profile
    //   1 byte level
    //   4 byte CEA mask
    //   4 byte VESA mask
    //   4 byte HH mask
    //   1 byte latency
    //   2 byte min-slice-slice
    //   2 byte slice-enc-params
    //   1 byte framerate-control-support
    //   max-hres (none or 2 byte)
    //   max-vres (none or 2 byte)

    CHECK_EQ(sessionID, mClientSessionID);

    AString transportString = "UDP";

    char val[PROPERTY_VALUE_MAX];
    if (property_get("media.wfd.enable-tcp", val, NULL)
            && (!strcasecmp("true", val) || !strcmp("1", val))) {
        ALOGI("Using TCP transport.");
        transportString = "TCP";
    }

    // For 720p60:
    //   use "30 00 02 02 00000040 00000000 00000000 00 0000 0000 00 none none\r\n"
    // For 720p30:
    //   use "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n"
    // For 720p24:
    //   use "78 00 02 02 00008000 00000000 00000000 00 0000 0000 00 none none\r\n"
    // For 1080p30:
    //   use "38 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none none\r\n"
    AString body = StringPrintf(
        "wfd_video_formats: "
#if defined(USE_1080P)
        "38 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none none\r\n"
#elif defined(USE_480P)
        "08 00 02 02 00000010 00000000 00000000 00 0000 0000 00 none none\r\n"
#else //if defined(USE_720P) default
        "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n"
#endif
        "wfd_audio_codecs: %s\r\n"
        "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n"
        "wfd_client_rtp_ports: RTP/AVP/%s;unicast %d 0 mode=play\r\n",
        (mUsingPCMAudio
            ? "LPCM 00000002 00" // 2 ch PCM 48kHz
            : "AAC 00000001 00"),  // 2 ch AAC 48kHz
        mClientInfo.mLocalIP.c_str(), transportString.c_str(), mChosenRTPPort);

    AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
    AppendCommonResponse(&request, mNextCSeq);

    request.append("Content-Type: text/parameters\r\n");
    request.append(StringPrintf("Content-Length: %d\r\n", body.size()));
    request.append("\r\n");
    request.append(body);

    status_t err =
        mNetSession->sendRequest(sessionID, request.c_str(), request.size());

    if (err != OK) {
        return err;
    }

    registerResponseHandler(
            sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM4Response);

    ++mNextCSeq;

    return OK;
}
Example #22
0
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    nandroid_files_total = 0;

    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path\n");
    
    char tmp[PATH_MAX];

#ifdef PHILZ_TOUCH_RECOVERY
    if (!quick_toggle_chk(DISABLE_NANDROID_MD5_FILE, 0))
#endif
    {
        ui_print("Checking MD5 sums...\n");
        sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path);
        if (0 != __system(tmp))
            return print_and_error("MD5 mismatch!\n");
    }

    int ret;

    if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot")))
        return ret;

    if (backup_recovery && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery")))
        return ret;

    struct stat s;
    Volume *vol = volume_for_path("/wimax");
    if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);

        struct stat st;
        if (0 != stat(tmp, &st))
        {
            ui_print("WARNING: WiMAX partition exists, but nandroid\n");
            ui_print("         backup does not contain WiMAX image.\n");
            ui_print("         You should create a new backup to\n");
            ui_print("         protect your WiMAX keys.\n");
        }
        else
        {
            ui_print("Erasing WiMAX before restore...\n");
            if (0 != (ret = format_volume("/wimax")))
                return print_and_error("Error while formatting wimax!\n");
            ui_print("Restoring WiMAX image...\n");
            if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp)))
                return ret;
        }
    }

    // restore of raw efs image files (efs_time-stamp.img) is done elsewhere
    // as it needs to pass in a filename (instead of a folder) as backup_path
    // this could be done here since efs is processed alone, but must be done before md5 checksum!
    if (backup_efs == RESTORE_EFS_TAR && 0 != (ret = nandroid_restore_partition(backup_path, "/efs")))
        return ret;
        
    if (backup_modem == RAW_IMG_FILE && 0 != (ret = nandroid_restore_partition(backup_path, "/modem")))
        return ret;
    else if (backup_modem == RAW_BIN_FILE) {
        sprintf(tmp, "%s/modem.bin", backup_path);
        custom_restore_raw_handler(tmp, "/modem");
    }

    if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system")))
        return ret;

    if (backup_preload) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) {
            ui_print("Failed to restore /preload!\n");
            return ret;
        }
    } else
#ifdef PHILZ_TOUCH_RECOVERY
           if (quick_toggle_chk(ENABLE_PRELOAD_FILE, 0))
#endif
    {
        if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) {
            ui_print("Failed to restore preload! Try to disable it.\n");
            ui_print("Skipping /preload...\n");
            //return ret;
        }
    }

    if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data")))
        return ret;
        
    if (has_datadata()) {
        if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata")))
            return ret;
    }

    if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
        return ret;

    if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0)))
        return ret;

    if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext")))
        return ret;

    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
static unsigned int memsizealloc = 0;
static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int usage, buffer_handle_t *pHandle, int *pStride)
{
	if (!pHandle || !pStride)
	{
		return -EINVAL;
	}

	size_t size;
	size_t stride;
	size_t bpr = 0;
	int reserve = true;
	int fmt_bak = format;
	bool fmt_chg = false;

    #ifdef USE_X86	

	if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED  )
	{
	    if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER )
	    {
	        //ALOGD("(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER treat as NV12");
	        format = HAL_PIXEL_FORMAT_YCrCb_NV12;
	    }
	    else
	    {
	        //ALOGD("treat as NV12 888");
	        format = HAL_PIXEL_FORMAT_RGBX_8888;
	        fmt_chg = true;	        
	    }
	}
	#endif
	if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP
                        || format == HAL_PIXEL_FORMAT_YV12
						|| format == HAL_PIXEL_FORMAT_YCrCb_NV12
						|| format == HAL_PIXEL_FORMAT_YCrCb_NV12_VIDEO
						|| format == HAL_PIXEL_FORMAT_YCbCr_420_888) 	
	{
        int align = 8;
        int bpp = 0;
        char property[PROPERTY_VALUE_MAX];
		int gpuformat = HAL_PIXEL_FORMAT_RGB_565;
		switch (format)
		{
			case HAL_PIXEL_FORMAT_YCrCb_420_SP:
			case HAL_PIXEL_FORMAT_YV12:
			case HAL_PIXEL_FORMAT_YCbCr_420_888:
				stride = GRALLOC_ALIGN(w, 16);
				size = h * (stride + GRALLOC_ALIGN(stride / 2, 16));
				break;
			case HAL_PIXEL_FORMAT_YCrCb_NV12:
				//stride = GRALLOC_ALIGN(w, 16);
				//size = h * (stride + GRALLOC_ALIGN(stride/2,16));
				bpp = 2;
	            bpr = (w*bpp + (align-1)) & ~(align-1);
				size = bpr * h;
				stride = bpr / bpp;				

				break;
			case HAL_PIXEL_FORMAT_YCrCb_NV12_VIDEO:
                property_set("sys.gmali.performance","video");
				bpp = 2;

				if (property_get("sys.yuv.rgb.format", property, NULL) > 0) {
					gpuformat = atoi(property);
				}
				if(gpuformat == HAL_PIXEL_FORMAT_RGBA_8888 || gpuformat == HAL_PIXEL_FORMAT_RGBX_8888)
					bpp = 4;
				else if(gpuformat == HAL_PIXEL_FORMAT_RGB_565)
					bpp = 2;
				
				bpr = (w*bpp + (align-1)) & ~(align-1);
#if GET_VPU_INTO_FROM_HEAD
				size = bpr * h;
#else
                //zxl:add tVPU_FRAME at the end of allocated buffer
                size = bpr * h + sizeof(tVPU_FRAME);
#endif
				stride = bpr / bpp;

				break;
			default:
				return -EINVAL;
		}
	}
	else
	{
		int align = 8;
		int bpp = 0;

		switch (format)
		{
			case HAL_PIXEL_FORMAT_RGBA_8888:
			case HAL_PIXEL_FORMAT_RGBX_8888:
			case HAL_PIXEL_FORMAT_BGRA_8888:
			case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
				bpp = 4;
				break;

			case HAL_PIXEL_FORMAT_RGB_888:
				bpp = 3;
				break;

			case HAL_PIXEL_FORMAT_RGB_565:
			case HAL_PIXEL_FORMAT_YCbCr_422_I:
			case HAL_PIXEL_FORMAT_YCbCr_422_SP:
			case HAL_PIXEL_FORMAT_RAW_SENSOR:
#if PLATFORM_SDK_VERSION < 18
			case HAL_PIXEL_FORMAT_RGBA_5551:
			case HAL_PIXEL_FORMAT_RGBA_4444:
#endif
				bpp = 2;
				break;
			case HAL_PIXEL_FORMAT_BLOB:
				bpp = 1;
				break;
			default:
				return -EINVAL;
		}

	int w_e = w, h_e = h;

#ifdef USE_LCDC_COMPOSER

        if (!(usage & GRALLOC_USAGE_HW_FB)) {
        #ifndef LCDC_COMPOSER_LANDSCAPE_ONLY
            private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
            uint32_t rot = (usage & GRALLOC_USAGE_ROT_MASK) >> 24;
            int bar = 0;    
           
            if(rot & 0x08) {
                rot &= ~0x08;
                switch(rot) {
                case 0:
                case HAL_TRANSFORM_ROT_180:
                    bar = m->info.yres - h;            
                    //ALOGD("bar=%d",bar);
           
                    if((w == m->info.xres) && (bar > 0) && (bar < 100)) {
                        if(0 == rot)
                            h_e += bar;
                        else
                            reserve = true;
                    }

                    //ALOGI("rot=%d [0/180]bar=%d,w=%d,h=%d,w_e=%d,h_e=%d",rot,bar,w,h,w_e,h_e);
                    break;
                case HAL_TRANSFORM_ROT_90:
                case HAL_TRANSFORM_ROT_270:
                    bar = m->info.xres - w;
                    if((h == m->info.yres) && (bar > 0) && (bar < 100)) {
                        w_e += bar;
                    }
                    if (rot == HAL_TRANSFORM_ROT_270)
                    {
						 reserve = true;
                    }

                   // ALOGI("rot=%d  [90/270]bar=%d,w=%d,h=%d,w_e=%d,h_e=%d",rot,bar,w,h,w_e,h_e);

                    break;
                default:
                    break;
                }
            }
            else
            {
                int bar_h;
                int bar_w;
                bar_h = m->info.yres - h;   
                bar_w = m->info.xres - w;
                    //ALOGD("bar=%d",bar);           
                if((w == m->info.xres) && (bar_h > 0) && (bar_h < 100)) 
                {
                     h_e += bar_h;
                }
                else if((h == m->info.yres) && (bar_w > 0) && (bar_w < 100))
                {
                     w_e += bar_w;
                }
                reserve = true;

               // ALOGI("[other rot=%x]bar_w=%d,bar_h=%d,w=%d,h=%d,w_e=%d,h_e=%d",rot,bar_w,bar_h,w,h,w_e,h_e);                            
            }
            //ALOGD("rot[%d]: %d x %d => %d x %d, reserve=%d", rot, w, h, w_e, h_e, (int)reserve);
        #else
            h_e += 100;
        #endif
        }
        if(w_e % 16) {
            //ALOGD("alloc_device_alloc, w[%d] not align, aligned to %d", w_e, (w + 31) & (~31));
            w_e = (w + 15) & (~15);
        }
#endif
		if (!(usage & GRALLOC_USAGE_HW_FB))
		{
			//zxl:fix failed of cts DecodeEditEncodeTest
			if(usage == 0x10702)
			{
				if(w_e % 32) {
					w_e=GRALLOC_ALIGN(w_e,32);
				}
			}
			else
			{
				if(w_e % 16) {
					w_e=GRALLOC_ALIGN(w_e,16);
				}
			}
		}
		else
		{
		    if(w_e % 32) 
		    {
				w_e=GRALLOC_ALIGN(w_e,32);
			}
		}

	//	bpr = (w_e*bpp + (align-1)) & ~(align-1);
	 	bpr = GRALLOC_ALIGN(w_e * bpp, 64);
		size = bpr * h_e;
		stride = bpr / bpp;

		if (format == HAL_PIXEL_FORMAT_BLOB) {
			bpp = 1;
			size = w*h;
			stride = w;
			if (GRALLOC_USAGE_HW_CAMERA_WRITE & usage) {
				/* take count from private usage flags */
				int count = (usage & GRALLOC_USAGE_PRIVATE_MASK ) >> 28;
				size += count * GRALLOC_EXTRA_ALLOCATION_UNIT_SIZE;
MatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source)
    : mDataSource(source),
      mReader(new DataSourceReader(mDataSource)),
      mSegment(NULL),
      mExtractedThumbnails(false),
      mIsWebm(false) {
    off64_t size;
    mIsLiveStreaming =
        (mDataSource->flags()
            & (DataSource::kWantsPrefetching
                | DataSource::kIsCachingDataSource))
        && mDataSource->getSize(&size) != OK;

    mkvparser::EBMLHeader ebmlHeader;
    long long pos;
    if (ebmlHeader.Parse(mReader, pos) < 0) {
        return;
    }

    if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) {
        mIsWebm = true;
    }

    long long ret =
        mkvparser::Segment::CreateInstance(mReader, pos, mSegment);

    if (ret) {
        CHECK(mSegment == NULL);
        return;
    }

    ret = mSegment->ParseHeaders();
    CHECK_EQ(ret, 0);

    const mkvparser::SegmentInfo *info = mSegment->GetInfo();

    const char* muxingAppInfo = info->GetMuxingAppAsUTF8();
    const char* writingApp    = info->GetWritingAppAsUTF8();

    char property_value[PROPERTY_VALUE_MAX] = {0};
    int parser_flags = 0;
    property_get("mm.enable.qcom_parser", property_value, "0");
    parser_flags = atoi(property_value);

    //if divx parsing is disabled and clip has divx hint, bailout
    //flag 0x00100000 is for DivX and 0x00200000 is for DivxHD
    if(!(0x00300000 & parser_flags) &&
       ((!strncasecmp(muxingAppInfo, "libDivX", 7)) ||
       (!strncasecmp(writingApp, "DivX", 4)))) {
        ALOGW("format found is not supported -- Bailing out --");
        delete mSegment;
        mSegment = NULL;
        return;
    }

    long len;
    ret = mSegment->LoadCluster(pos, len);
    CHECK_EQ(ret, 0);

    if (ret < 0) {
        delete mSegment;
        mSegment = NULL;
        return;
    }

#if 0
    const mkvparser::SegmentInfo *info = mSegment->GetInfo();
    ALOGI("muxing app: %s, writing app: %s",
         info->GetMuxingAppAsUTF8(),
         info->GetWritingAppAsUTF8());
#endif

    addTracks();
}
Example #25
0
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    nandroid_files_total = 0;

    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path\n");

    char tmp[PATH_MAX];

    ui_print("Checking MD5 sums...\n");
    sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path);
    if (0 != __system(tmp))
        return print_and_error("MD5 mismatch!\n");

    int ret;

    if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot")))
        return ret;

    struct stat s;
    Volume *vol = volume_for_path("/wimax");
    if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];

        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);

        struct stat st;
        if (0 != stat(tmp, &st))
        {
            ui_print("WARNING: WiMAX partition exists, but nandroid\n");
            ui_print("         backup does not contain WiMAX image.\n");
            ui_print("         You should create a new backup to\n");
            ui_print("         protect your WiMAX keys.\n");
        }
        else
        {
            ui_print("Erasing WiMAX before restore...\n");
            if (0 != (ret = format_volume("/wimax")))
                return print_and_error("Error while formatting wimax!\n");
            ui_print("Restoring WiMAX image...\n");
            if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp)))
                return ret;
        }
    }

    if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) {
            ui_print("Failed to restore /preload!\n");
            return ret;
        }

    if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata")))
            return ret;
    }

    if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
        return ret;

    if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0)))
        return ret;

    if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext")))
        return ret;

    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
Example #26
0
int main(int argc, char **argv)
{
	struct fb_fix_screeninfo finfo;
    struct stat s;
    int i;
    int do_calib = 1;
    char runme[PROPERTY_VALUE_MAX];
    char name[MAX_LEN] = "";
    char dev[MAX_LEN] = "";
    int found,ret;
	int fd_carstatus = 0;

    /* open log */
    log_fd = open(log, O_WRONLY | O_CREAT | O_TRUNC);

	fd_carstatus = open("/dev/carstatus", O_RDWR);
	if(fd_carstatus == -1){
	    log_write("Failed to open /dev/carstatus\n");
	} else {
        ret = ioctl(fd_carstatus, CARSTATUS_GET_TOUCHPANEL_TYPE, &touch_type);
        log_write("Calibration Touch Panel Type : 0x%x\n", touch_type);        
		if(ret >= 0) {
            if(touch_type == TOUCH_PANEL_TYPE_CAPACITIVE_GOODIX) {
                log_write("No need to do calibration for goodix capacitive\n");
				close(fd_carstatus);
				return 0;
			}
		}
		
		close(fd_carstatus);
	}
    property_get("ro.calibration", runme, "");
    if (runme[0] != '1')
	    return 0;
    
	if (check_conf()){	// if we have the calibration file, skip any following step to save time
		goto err_log;
    }
	umask(0);
	mkdir("/data/system/calibrator",0777);

    /* read framebuffer for resolution */
    fb_fd = open(fb_dev, O_RDWR);
    if (fb_fd <= 0) {
	    log_write("Failed to open %s\n", fb_dev);
	    goto err_log;
    }
    if (-1 == ioctl(fb_fd, FBIOGET_VSCREENINFO, &info)) {
	    log_write("Failed to get screen info\n");
	    goto err_fb;
    }
    log_write("Screen resolution: %dx%d\n", info.xres, info.yres);
    /* map buffer */
    if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
	    log_write("Failed to get screen info: %d\n", errno);
        goto err_fb;
    }
    scrbuf = (__u16*) mmap(0, finfo.smem_len,
			    PROT_READ | PROT_WRITE,
			    MAP_SHARED,
			    fb_fd, 0);
    if (scrbuf== MAP_FAILED) {
	    log_write("Failed to map screen\n");
	    goto err_fb;
    }
    
    /* Clear screen */
    memset(scrbuf, 0xFF, finfo.smem_len);

    /* Find touchscreen device */
    found = find_ts_device(name, dev);
    if (!found) {
        log_write("can not find ts device\n");
        goto err_map;
    }
    
	log_write("dev:%s\n", dev);
    ts_fd = open(dev, O_RDWR);
    if (ts_fd < 0) {
        log_write("Failed to open %s\n", dev);
        goto err_map;
    }
    if(touch_type == TOUCH_PANEL_TYPE_RESISTIVE_MULTIPOINT_ULTRACHIP) {
		do{
			memset(scrbuf, 0xFF, finfo.smem_len);
		}while(ret = do_calibration_uc6811());
	} else {
	    /* Special calibration function for the DA905x PMIC */
	    if (strcmp(name, DA9052_DEV_NAME) == 0) {
	        log_write("do_calibration_da9052\n");
	        do_calibration_da9052(do_calib);
	    } else {
	        log_write("do_calibration\n");
	        if (do_calib) {
				do{
	    			memset(scrbuf, 0xFF, finfo.smem_len);
				}while(ret = do_calibration());
	        }
	    }
	}

    log_write("Calibration done!!\n");
    /* Clear screen */
    memset(scrbuf, 0, finfo.smem_len);
    //test_calibration();

    close(ts_fd);
err_map:
    munmap(scrbuf, finfo.smem_len);
err_fb:
    close(fb_fd);
err_log:
    close(log_fd);

    return 0;
}
Example #27
0
/* Runs on the radio thread */
static void
initMsmFMRadio(hal::FMRadioSettings &aInfo)
{
  mozilla::ScopedClose fd(sRadioFD);
  char version[64];
  int rc;
  snprintf(version, sizeof(version), "%d", sMsmFMVersion);
  property_set("hw.fm.version", version);

  /* Set the mode for soc downloader */
  property_set("hw.fm.mode", "normal");
  /* start fm_dl service */
  property_set("ctl.start", "fm_dl");

  /*
   * Fix bug 800263. Wait until the FM radio chips initialization is done
   * then set other properties, or the system will hang and reboot. This
   * work around is from codeaurora
   * (git://codeaurora.org/platform/frameworks/base.git).
   */
  for (int i = 0; i < 4; ++i) {
    sleep(1);
    char value[PROPERTY_VALUE_MAX];
    property_get("hw.fm.init", value, "0");
    if (!strcmp(value, "1")) {
      break;
    }
  }

  rc = setControl(V4L2_CID_PRIVATE_TAVARUA_STATE, FM_RECV);
  if (rc < 0) {
    HAL_LOG("Unable to turn on radio |%s|", strerror(errno));
    return;
  }

  int preEmphasis = aInfo.preEmphasis() <= 50;
  rc = setControl(V4L2_CID_PRIVATE_TAVARUA_EMPHASIS, preEmphasis);
  if (rc) {
    HAL_LOG("Unable to configure preemphasis");
    return;
  }

  rc = setControl(V4L2_CID_PRIVATE_TAVARUA_RDS_STD, 0);
  if (rc) {
    HAL_LOG("Unable to configure RDS");
    return;
  }

  int spacing;
  switch (aInfo.spaceType()) {
  case 50:
    spacing = FM_CH_SPACE_50KHZ;
    break;
  case 100:
    spacing = FM_CH_SPACE_100KHZ;
    break;
  case 200:
    spacing = FM_CH_SPACE_200KHZ;
    break;
  default:
    HAL_LOG("Unsupported space value - %d", aInfo.spaceType());
    return;
  }

  rc = setControl(V4L2_CID_PRIVATE_TAVARUA_SPACING, spacing);
  if (rc) {
    HAL_LOG("Unable to configure spacing");
    return;
  }

  /*
   * Frequency conversions
   *
   * HAL uses units of 1k for frequencies
   * V4L2 uses units of 62.5kHz
   * Multiplying by (10000 / 625) converts from HAL units to V4L2.
   */

  struct v4l2_tuner tuner = {0};
  tuner.rangelow = (aInfo.lowerLimit() * 10000) / 625;
  tuner.rangehigh = (aInfo.upperLimit() * 10000) / 625;
  tuner.audmode = V4L2_TUNER_MODE_STEREO;
  rc = ioctl(fd, VIDIOC_S_TUNER, &tuner);
  if (rc < 0) {
    HAL_LOG("Unable to adjust band limits");
    return;
  }

  rc = setControl(V4L2_CID_PRIVATE_TAVARUA_REGION, TAVARUA_REGION_OTHER);
  if (rc < 0) {
    HAL_LOG("Unable to configure region");
    return;
  }

  // Some devices do not support analog audio routing. This should be
  // indicated by the 'ro.moz.fm.noAnalog' property at build time.
  char propval[PROPERTY_VALUE_MAX];
  property_get("ro.moz.fm.noAnalog", propval, "");
  bool noAnalog = !strcmp(propval, "true");

  rc = setControl(V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH,
                  noAnalog ? FM_DIGITAL_PATH : FM_ANALOG_PATH);
  if (rc < 0) {
    HAL_LOG("Unable to set audio path");
    return;
  }

  if (!noAnalog) {
    /* Set the mode for soc downloader */
    property_set("hw.fm.mode", "config_dac");
    /* Use analog mode FM */
    property_set("hw.fm.isAnalog", "true");
    /* start fm_dl service */
    property_set("ctl.start", "fm_dl");

    for (int i = 0; i < 4; ++i) {
      sleep(1);
      char value[PROPERTY_VALUE_MAX];
      property_get("hw.fm.init", value, "0");
      if (!strcmp(value, "1")) {
        break;
      }
    }
  }

  fd.forget();
  sRadioEnabled = true;
}
Example #28
0
static void *vsync_loop(void *param)
{
    const char* vsync_timestamp_fb0 = "/sys/class/graphics/fb0/vsync_event";
    const char* vsync_timestamp_fb1 = "/sys/class/graphics/fb1/vsync_event";
    int dpy = HWC_DISPLAY_PRIMARY;

    hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);

    char thread_name[64] = HWC_VSYNC_THREAD_NAME;
    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY +
                android::PRIORITY_MORE_FAVORABLE);

    const int MAX_DATA = 64;
    static char vdata[MAX_DATA];

    uint64_t cur_timestamp=0;
    ssize_t len = -1;
    int fd_timestamp = -1;
    bool fb1_vsync = false;
    bool logvsync = false;

    char property[PROPERTY_VALUE_MAX];
    if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
        if(atoi(property) == 1)
            ctx->vstate.fakevsync = true;
    }

    if(property_get("debug.hwc.logvsync", property, 0) > 0) {
        if(atoi(property) == 1)
            logvsync = true;
    }

    /* Currently read vsync timestamp from drivers
       e.g. VSYNC=41800875994
       */
    fd_timestamp = open(vsync_timestamp_fb0, O_RDONLY);
    if (fd_timestamp < 0) {
        // Make sure fb device is opened before starting this thread so this
        // never happens.
        ALOGE ("FATAL:%s:not able to open file:%s, %s",  __FUNCTION__,
               (fb1_vsync) ? vsync_timestamp_fb1 : vsync_timestamp_fb0,
               strerror(errno));
        ctx->vstate.fakevsync = true;
    }

    do {
        if (LIKELY(!ctx->vstate.fakevsync)) {
            len = pread(fd_timestamp, vdata, MAX_DATA, 0);
            if (len < 0) {
                // If the read was just interrupted - it is not a fatal error
                // In either case, just continue.
                if (errno != EAGAIN &&
                    errno != EINTR  &&
                    errno != EBUSY) {
                    ALOGE ("FATAL:%s:not able to read file:%s, %s",
                           __FUNCTION__,
                           vsync_timestamp_fb0, strerror(errno));
                }
                continue;
            }
            // extract timestamp
            const char *str = vdata;
            if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) {
                cur_timestamp = strtoull(str + strlen("VSYNC="), NULL, 0);
            }
        } else {
            usleep(16666);
            cur_timestamp = systemTime();
        }
        // send timestamp to HAL
        if(ctx->vstate.enable) {
            ALOGD_IF (logvsync, "%s: timestamp %llu sent to HWC for %s",
                      __FUNCTION__, cur_timestamp, "fb0");
            ctx->proc->vsync(ctx->proc, dpy, cur_timestamp);
        }

    } while (true);
    if(fd_timestamp >= 0)
        close (fd_timestamp);

    return NULL;
}
/**
 * @brief OMX SwVdec diagnostics class constructor.
 */
omx_swvdec_diag::omx_swvdec_diag():
    m_dump_ip(0),
    m_dump_op(0),
    m_filename_ip(NULL),
    m_filename_op(NULL),
    m_file_ip(NULL),
    m_file_op(NULL)
{
    time_t time_raw;

    struct tm *time_info;

    char time_string[16];

    char filename_ip[PROPERTY_VALUE_MAX];
    char filename_op[PROPERTY_VALUE_MAX];

    char property_value[PROPERTY_VALUE_MAX] = {0};

    time_raw = time(NULL);

    time_info = localtime(&time_raw);

    if (time_info != NULL)
    {
        // time string: "YYYYmmddTHHMMSS"
        strftime(time_string, sizeof(time_string), "%Y%m%dT%H%M%S", time_info);
    }
    else
    {
        // time string: "19700101T000000"
        snprintf(time_string, sizeof(time_string), "19700101T000000");
    }

    // default ip filename: "/data/misc/media/omx_swvdec_YYYYmmddTHHMMSS_ip.bin"
    snprintf(filename_ip,
             sizeof(filename_ip),
             "%s/omx_swvdec_%s_ip.bin",
             DIAG_FILE_PATH,
             time_string);

    // default op filename: "/data/misc/media/omx_swvdec_YYYYmmddTHHMMSS_op.yuv"
    snprintf(filename_op,
             sizeof(filename_op),
             "%s/omx_swvdec_%s_op.yuv",
             DIAG_FILE_PATH,
             time_string);

    if (property_get("vendor.omx_swvdec.dump.ip", property_value, NULL))
    {
        m_dump_ip = atoi(property_value);

        OMX_SWVDEC_LOG_HIGH("vendor.omx_swvdec.dump.ip: %d", m_dump_ip);
    }

    if (property_get("vendor.omx_swvdec.dump.op", property_value, NULL))
    {
        m_dump_op = atoi(property_value);

        OMX_SWVDEC_LOG_HIGH("vendor.omx_swvdec.dump.op: %d", m_dump_op);
    }

    if (m_dump_ip && property_get("vendor.omx_swvdec.filename.ip",
                                  property_value,
                                  filename_ip) && (strlen(property_value) > 0 ) )
    {
        size_t m_filename_ip_size = (strlen(property_value) + 1)*sizeof(char);
        m_filename_ip =
            (char *) malloc(m_filename_ip_size);
        if (m_filename_ip == NULL)
        {
            OMX_SWVDEC_LOG_ERROR("failed to allocate %zu bytes for "
                                 "input filename string",
                                 m_filename_ip_size);
        }
        else
        {
            strlcpy(m_filename_ip, property_value,m_filename_ip_size);
            OMX_SWVDEC_LOG_HIGH("vendor.omx_swvdec.filename.ip: %s", m_filename_ip);
            if ((m_file_ip = fopen(m_filename_ip, "wb")) == NULL)
            {
                OMX_SWVDEC_LOG_ERROR("cannot open input file '%s' logging erro is : %d",
                                     m_filename_ip,errno);
            }
        }
    }

    if (m_dump_op && property_get("vendor.omx_swvdec.filename.op",
                                  property_value,
                                  filename_op) && (strlen(property_value) > 0 ))
    {
        size_t m_filename_op_size = (strlen(property_value) + 1)*sizeof(char);
        m_filename_op =
            (char *) malloc(m_filename_op_size);
        if (m_filename_op == NULL)
        {
            OMX_SWVDEC_LOG_ERROR("failed to allocate %zu bytes for "
                                 "output filename string",
                                 m_filename_op_size);
        }
        else
        {
            strlcpy(m_filename_op, property_value,m_filename_op_size);
            OMX_SWVDEC_LOG_HIGH("vendor.omx_swvdec.filename.op: %s", m_filename_op);
            if ((m_file_op = fopen(m_filename_op, "wb")) == NULL)
            {
                OMX_SWVDEC_LOG_ERROR("cannot open output file '%s' logging error : %d",
                                     m_filename_op,errno);
            }
        }
    }
}
RefPtr<MediaDataDecoder::InitPromise>
GonkVideoDecoderManager::Init()
{
  mNeedsCopyBuffer = false;

  nsIntSize displaySize(mDisplayWidth, mDisplayHeight);
  nsIntRect pictureRect(0, 0, mVideoWidth, mVideoHeight);

  uint32_t maxWidth, maxHeight;
  char propValue[PROPERTY_VALUE_MAX];
  property_get("ro.moz.omx.hw.max_width", propValue, "-1");
  maxWidth = -1 == atoi(propValue) ? MAX_VIDEO_WIDTH : atoi(propValue);
  property_get("ro.moz.omx.hw.max_height", propValue, "-1");
  maxHeight = -1 == atoi(propValue) ? MAX_VIDEO_HEIGHT : atoi(propValue) ;

  if (mVideoWidth * mVideoHeight > maxWidth * maxHeight) {
    GVDM_LOG("Video resolution exceeds hw codec capability");
    return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
  }

  // Validate the container-reported frame and pictureRect sizes. This ensures
  // that our video frame creation code doesn't overflow.
  nsIntSize frameSize(mVideoWidth, mVideoHeight);
  if (!IsValidVideoRegion(frameSize, pictureRect, displaySize)) {
    GVDM_LOG("It is not a valid region");
    return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
  }

  mReaderTaskQueue = AbstractThread::GetCurrent()->AsTaskQueue();
  MOZ_ASSERT(mReaderTaskQueue);

  if (mDecodeLooper.get() != nullptr) {
    return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
  }

  if (!InitLoopers(MediaData::VIDEO_DATA)) {
    return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
  }

  RefPtr<InitPromise> p = mInitPromise.Ensure(__func__);
  android::sp<GonkVideoDecoderManager> self = this;
  mDecoder = MediaCodecProxy::CreateByType(mDecodeLooper, mMimeType.get(), false);

  uint32_t capability = MediaCodecProxy::kEmptyCapability;
  if (mDecoder->getCapability(&capability) == OK && (capability &
      MediaCodecProxy::kCanExposeGraphicBuffer)) {
#if ANDROID_VERSION >= 21
    sp<IGonkGraphicBufferConsumer> consumer;
    GonkBufferQueue::createBufferQueue(&mGraphicBufferProducer, &consumer);
    mNativeWindow = new GonkNativeWindow(consumer);
#else
    mNativeWindow = new GonkNativeWindow();
#endif
  }

  mVideoCodecRequest.Begin(mDecoder->AsyncAllocateVideoMediaCodec()
    ->Then(mReaderTaskQueue, __func__,
      [self] (bool) -> void {
        self->mVideoCodecRequest.Complete();
        self->codecReserved();
      }, [self] (bool) -> void {
        self->mVideoCodecRequest.Complete();
        self->codecCanceled();
      }));

  return p;
}