Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ef18b1e authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4476081 from b6568d73 to pi-release

Change-Id: Ifdcd13626688827b49a6680ca9b7bcded0d48ec1
parents 0f2e5719 b6568d73
Loading
Loading
Loading
Loading
+52 −22
Original line number Original line Diff line number Diff line
@@ -342,6 +342,56 @@ static int prepare_app_quota(const std::unique_ptr<std::string>& uuid, const std
#endif
#endif
}
}


static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) {
    if (!property_get_bool("dalvik.vm.usejitprofiles", false)) {
        return true;
    }

    int32_t uid = multiuser_get_uid(userId, appId);
    int shared_app_gid = multiuser_get_shared_gid(userId, appId);
    if (shared_app_gid == -1) {
        // TODO(calin): this should no longer be possible but do not continue if we don't get
        // a valid shared gid.
        PLOG(WARNING) << "Invalid shared_app_gid for " << packageName;
        return true;
    }

    const std::string profile_dir =
            create_primary_current_profile_package_dir_path(userId, packageName);
    // read-write-execute only for the app user.
    if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) {
        PLOG(ERROR) << "Failed to prepare " << profile_dir;
        return false;
    }
    const std::string profile_file = create_current_profile_path(userId, packageName,
            /*is_secondary_dex*/false);
    // read-write only for the app user.
    if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) {
        PLOG(ERROR) << "Failed to prepare " << profile_file;
        return false;
    }

    const std::string ref_profile_path =
            create_primary_reference_profile_package_dir_path(packageName);

    // Prepare the reference profile directory. Note that we use the non strict version of
    // fs_prepare_dir. This will fix the permission and the ownership to the correct values.
    // This is particularly important given that in O there were some fixes for how the
    // shared_app_gid is computed.
    //
    // Note that by the time we get here we know that we are using a correct uid (otherwise
    // prepare_app_dir and the above fs_prepare_file_strict which check the uid). So we
    // are sure that the gid being used belongs to the owning app and not someone else.
    //
    // dex2oat/profman runs under the shared app gid and it needs to read/write reference profiles.
    if (fs_prepare_dir(ref_profile_path.c_str(), 0770, AID_SYSTEM, shared_app_gid) != 0) {
        PLOG(ERROR) << "Failed to prepare " << ref_profile_path;
        return false;
    }

    return true;
}

binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid,
        const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
        const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
        const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) {
        const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) {
@@ -417,28 +467,8 @@ binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::s
            return error("Failed to set hard quota " + path);
            return error("Failed to set hard quota " + path);
        }
        }


        if (property_get_bool("dalvik.vm.usejitprofiles", false)) {
        if (!prepare_app_profile_dir(packageName, appId, userId)) {
            const std::string profile_dir =
            return error("Failed to prepare profiles for " + packageName);
                    create_primary_current_profile_package_dir_path(userId, pkgname);
            // read-write-execute only for the app user.
            if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) {
                return error("Failed to prepare " + profile_dir);
            }
            const std::string profile_file = create_current_profile_path(userId, pkgname,
                    /*is_secondary_dex*/false);
            // read-write only for the app user.
            if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) {
                return error("Failed to prepare " + profile_file);
            }
            const std::string ref_profile_path =
                    create_primary_reference_profile_package_dir_path(pkgname);
            // dex2oat/profman runs under the shared app gid and it needs to read/write reference
            // profiles.
            int shared_app_gid = multiuser_get_shared_gid(0, appId);
            if ((shared_app_gid != -1) && fs_prepare_dir_strict(
                    ref_profile_path.c_str(), 0701, shared_app_gid, shared_app_gid) != 0) {
                return error("Failed to prepare " + ref_profile_path);
            }
        }
        }
    }
    }
    return ok();
    return ok();
+58 −5
Original line number Original line Diff line number Diff line
@@ -144,10 +144,11 @@ protected:
    static constexpr uid_t kSystemGid = 1000;
    static constexpr uid_t kSystemGid = 1000;
    static constexpr int32_t kOSdkVersion = 25;
    static constexpr int32_t kOSdkVersion = 25;
    static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE;
    static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE;
    static constexpr uid_t kTestAppUid = 19999;
    static constexpr gid_t kTestAppGid = 19999;
    static constexpr uid_t kTestAppId = kTestAppUid;
    static constexpr int32_t kTestUserId = 0;
    static constexpr int32_t kTestUserId = 0;
    static constexpr uid_t kTestAppId = 19999;

    const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId);
    const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId);


    InstalldNativeService* service_;
    InstalldNativeService* service_;
    std::unique_ptr<std::string> volume_uuid_;
    std::unique_ptr<std::string> volume_uuid_;
@@ -245,7 +246,10 @@ protected:


    void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag,
    void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag,
            bool should_binder_call_succeed, bool should_dex_be_compiled = true,
            bool should_binder_call_succeed, bool should_dex_be_compiled = true,
            int uid = kTestAppUid) {
            int32_t uid = -1) {
        if (uid == -1) {
            uid = kTestAppUid;
        }
        std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
        std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
        int32_t dexopt_needed = 0;  // does not matter;
        int32_t dexopt_needed = 0;  // does not matter;
        std::unique_ptr<std::string> out_path = nullptr;  // does not matter
        std::unique_ptr<std::string> out_path = nullptr;  // does not matter
@@ -279,7 +283,10 @@ protected:


    void reconcile_secondary_dex(const std::string& path, int32_t storage_flag,
    void reconcile_secondary_dex(const std::string& path, int32_t storage_flag,
            bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted,
            bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted,
            int uid = kTestAppUid, std::string* package_override = nullptr) {
            int32_t uid = -1, std::string* package_override = nullptr) {
        if (uid == -1) {
            uid = kTestAppUid;
        }
        std::vector<std::string> isas;
        std::vector<std::string> isas;
        isas.push_back(kRuntimeIsa);
        isas.push_back(kRuntimeIsa);
        bool out_secondary_dex_exists = false;
        bool out_secondary_dex_exists = false;
@@ -556,5 +563,51 @@ TEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) {
    ASSERT_EQ(ENOENT, errno);
    ASSERT_EQ(ENOENT, errno);
}
}


TEST_F(ProfileTest, ProfileDirOk) {
    LOG(INFO) << "ProfileDirOk";

    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
            kTestUserId, package_name_);
    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
            /*is_secondary_dex*/false);
    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);

    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
    CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
}

// Verify that the profile directories are fixed up during an upgrade.
// (The reference profile directory is prepared lazily).
TEST_F(ProfileTest, ProfileDirOkAfterFixup) {
    LOG(INFO) << "ProfileDirOkAfterFixup";

    std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
            kTestUserId, package_name_);
    std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
            /*is_secondary_dex*/false);
    std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);

    // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700.
    ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid));
    ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700));

    // Run createAppData again which will offer to fix-up the profile directories.
    ASSERT_TRUE(service_->createAppData(
            volume_uuid_,
            package_name_,
            kTestUserId,
            kAppDataFlags,
            kTestAppUid,
            se_info_,
            kOSdkVersion,
            &ce_data_inode_).isOk());

    // Check the file access.
    CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
    CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
    CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
}

}  // namespace installd
}  // namespace installd
}  // namespace android
}  // namespace android
+24 −47
Original line number Original line Diff line number Diff line
@@ -100,13 +100,17 @@ public:
        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
    }
    }


    virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
    virtual status_t captureScreen(const sp<IBinder>& display,
            const sp<IGraphicBufferProducer>& producer,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
                                   int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
            int32_t minLayerZ, int32_t maxLayerZ,
                                   ISurfaceComposer::Rotation rotation) {
            bool useIdentityTransform,
            ISurfaceComposer::Rotation rotation)
    {
        Parcel data, reply;
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeStrongBinder(display);
        data.writeStrongBinder(display);
        data.writeStrongBinder(IInterface::asBinder(producer));
        data.write(sourceCrop);
        data.write(sourceCrop);
        data.writeUint32(reqWidth);
        data.writeUint32(reqWidth);
        data.writeUint32(reqHeight);
        data.writeUint32(reqHeight);
@@ -114,45 +118,21 @@ public:
        data.writeInt32(maxLayerZ);
        data.writeInt32(maxLayerZ);
        data.writeInt32(static_cast<int32_t>(useIdentityTransform));
        data.writeInt32(static_cast<int32_t>(useIdentityTransform));
        data.writeInt32(static_cast<int32_t>(rotation));
        data.writeInt32(static_cast<int32_t>(rotation));
        status_t err = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
        remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);

        return reply.readInt32();
        if (err != NO_ERROR) {
            return err;
        }

        err = reply.readInt32();
        if (err != NO_ERROR) {
            return err;
        }

        *outBuffer = new GraphicBuffer();
        reply.read(**outBuffer);
        return err;
    }
    }


    virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
    virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
                                   sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
                                   const sp<IGraphicBufferProducer>& producer,
                                   float frameScale) {
                                   const Rect& sourceCrop, float frameScale) {
        Parcel data, reply;
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeStrongBinder(layerHandleBinder);
        data.writeStrongBinder(layerHandleBinder);
        data.writeStrongBinder(IInterface::asBinder(producer));
        data.write(sourceCrop);
        data.write(sourceCrop);
        data.writeFloat(frameScale);
        data.writeFloat(frameScale);
        status_t err = remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);
        remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);

        return reply.readInt32();
        if (err != NO_ERROR) {
            return err;
        }

        err = reply.readInt32();
        if (err != NO_ERROR) {
            return err;
        }

        *outBuffer = new GraphicBuffer();
        reply.read(**outBuffer);

        return err;
    }
    }


    virtual bool authenticateSurfaceTexture(
    virtual bool authenticateSurfaceTexture(
@@ -603,7 +583,8 @@ status_t BnSurfaceComposer::onTransact(
        case CAPTURE_SCREEN: {
        case CAPTURE_SCREEN: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> display = data.readStrongBinder();
            sp<IBinder> display = data.readStrongBinder();
            sp<GraphicBuffer> outBuffer;
            sp<IGraphicBufferProducer> producer =
                    interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
            Rect sourceCrop(Rect::EMPTY_RECT);
            Rect sourceCrop(Rect::EMPTY_RECT);
            data.read(sourceCrop);
            data.read(sourceCrop);
            uint32_t reqWidth = data.readUint32();
            uint32_t reqWidth = data.readUint32();
@@ -613,28 +594,24 @@ status_t BnSurfaceComposer::onTransact(
            bool useIdentityTransform = static_cast<bool>(data.readInt32());
            bool useIdentityTransform = static_cast<bool>(data.readInt32());
            int32_t rotation = data.readInt32();
            int32_t rotation = data.readInt32();


            status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight,
            status_t res = captureScreen(display, producer,
                                         minLayerZ, maxLayerZ, useIdentityTransform,
                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
                    useIdentityTransform,
                    static_cast<ISurfaceComposer::Rotation>(rotation));
                    static_cast<ISurfaceComposer::Rotation>(rotation));
            reply->writeInt32(res);
            reply->writeInt32(res);
            if (res == NO_ERROR) {
                reply->write(*outBuffer);
            }
            return NO_ERROR;
            return NO_ERROR;
        }
        }
        case CAPTURE_LAYERS: {
        case CAPTURE_LAYERS: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> layerHandleBinder = data.readStrongBinder();
            sp<IBinder> layerHandleBinder = data.readStrongBinder();
            sp<GraphicBuffer> outBuffer;
            sp<IGraphicBufferProducer> producer =
                    interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
            Rect sourceCrop(Rect::EMPTY_RECT);
            Rect sourceCrop(Rect::EMPTY_RECT);
            data.read(sourceCrop);
            data.read(sourceCrop);
            float frameScale = data.readFloat();
            float frameScale = data.readFloat();


            status_t res = captureLayers(layerHandleBinder, &outBuffer, sourceCrop, frameScale);
            status_t res = captureLayers(layerHandleBinder, producer, sourceCrop, frameScale);
            reply->writeInt32(res);
            reply->writeInt32(res);
            if (res == NO_ERROR) {
                reply->write(*outBuffer);
            }
            return NO_ERROR;
            return NO_ERROR;
        }
        }
        case AUTHENTICATE_SURFACE: {
        case AUTHENTICATE_SURFACE: {
+0 −21
Original line number Original line Diff line number Diff line
@@ -1760,25 +1760,4 @@ status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out)
    return OK;
    return OK;
}
}


status_t Surface::attachAndQueueBuffer(Surface* surface, sp<GraphicBuffer> buffer) {
    if (buffer == nullptr) {
        return BAD_VALUE;
    }
    int err = static_cast<ANativeWindow*>(surface)->perform(surface, NATIVE_WINDOW_API_CONNECT,
                                                            NATIVE_WINDOW_API_CPU);
    if (err != OK) {
        return err;
    }
    err = surface->attachBuffer(buffer->getNativeBuffer());
    if (err != OK) {
        return err;
    }
    err = static_cast<ANativeWindow*>(surface)->queueBuffer(surface, buffer->getNativeBuffer(), -1);
    if (err != OK) {
        return err;
    }
    err = surface->disconnect(NATIVE_WINDOW_API_CPU);
    return err;
}

}; // namespace android
}; // namespace android
+164 −10
Original line number Original line Diff line number Diff line
@@ -717,27 +717,181 @@ status_t SurfaceComposerClient::getHdrCapabilities(const sp<IBinder>& display,


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
status_t ScreenshotClient::capture(
                                   uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
        const sp<IBinder>& display,
                                   bool useIdentityTransform, uint32_t rotation,
        const sp<IGraphicBufferProducer>& producer,
        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
        int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == NULL) return NO_INIT;
    return s->captureScreen(display, producer, sourceCrop,
            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
}

status_t ScreenshotClient::captureToBuffer(const sp<IBinder>& display,
        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
        int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
        uint32_t rotation,
        sp<GraphicBuffer>* outBuffer) {
        sp<GraphicBuffer>* outBuffer) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == NULL) return NO_INIT;
    if (s == NULL) return NO_INIT;
    status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight, minLayerZ,

                                    maxLayerZ, useIdentityTransform,
    sp<IGraphicBufferConsumer> gbpConsumer;
    sp<IGraphicBufferProducer> producer;
    BufferQueue::createBufferQueue(&producer, &gbpConsumer);
    sp<BufferItemConsumer> consumer(new BufferItemConsumer(gbpConsumer,
           GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER,
           1, true));

    status_t ret = s->captureScreen(display, producer, sourceCrop, reqWidth, reqHeight,
            minLayerZ, maxLayerZ, useIdentityTransform,
            static_cast<ISurfaceComposer::Rotation>(rotation));
            static_cast<ISurfaceComposer::Rotation>(rotation));
    if (ret != NO_ERROR) {
    if (ret != NO_ERROR) {
        return ret;
        return ret;
    }
    }
    BufferItem b;
    consumer->acquireBuffer(&b, 0, true);
    *outBuffer = b.mGraphicBuffer;
    return ret;
    return ret;
}
}


status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle,
                                         const sp<IGraphicBufferProducer>& producer,
                                         Rect sourceCrop, float frameScale) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == NULL) return NO_INIT;
    return s->captureLayers(layerHandle, producer, sourceCrop, frameScale);
}

status_t ScreenshotClient::captureLayersToBuffer(const sp<IBinder>& layerHandle, Rect sourceCrop,
                                                 float frameScale, sp<GraphicBuffer>* outBuffer) {
                                                 float frameScale, sp<GraphicBuffer>* outBuffer) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == NULL) return NO_INIT;
    if (s == NULL) return NO_INIT;
    status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale);

    sp<IGraphicBufferConsumer> gbpConsumer;
    sp<IGraphicBufferProducer> producer;
    BufferQueue::createBufferQueue(&producer, &gbpConsumer);
    sp<BufferItemConsumer> consumer(new BufferItemConsumer(gbpConsumer,
                                                           GRALLOC_USAGE_HW_TEXTURE |
                                                                   GRALLOC_USAGE_SW_READ_NEVER |
                                                                   GRALLOC_USAGE_SW_WRITE_NEVER,
                                                           1, true));

    status_t ret = s->captureLayers(layerHandle, producer, sourceCrop, frameScale);
    if (ret != NO_ERROR) {
        return ret;
    }
    BufferItem b;
    consumer->acquireBuffer(&b, 0, true);
    *outBuffer = b.mGraphicBuffer;
    return ret;
    return ret;
}
}

ScreenshotClient::ScreenshotClient()
    : mHaveBuffer(false) {
    memset(&mBuffer, 0, sizeof(mBuffer));
}

ScreenshotClient::~ScreenshotClient() {
    ScreenshotClient::release();
}

sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const {
    if (mCpuConsumer == NULL) {
        sp<IGraphicBufferConsumer> consumer;
        BufferQueue::createBufferQueue(&mProducer, &consumer);
        mCpuConsumer = new CpuConsumer(consumer, 1);
        mCpuConsumer->setName(String8("ScreenshotClient"));
    }
    return mCpuConsumer;
}

status_t ScreenshotClient::update(const sp<IBinder>& display,
        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
        int32_t minLayerZ, int32_t maxLayerZ,
        bool useIdentityTransform, uint32_t rotation) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == NULL) return NO_INIT;
    sp<CpuConsumer> cpuConsumer = getCpuConsumer();

    if (mHaveBuffer) {
        mCpuConsumer->unlockBuffer(mBuffer);
        memset(&mBuffer, 0, sizeof(mBuffer));
        mHaveBuffer = false;
    }

    status_t err = s->captureScreen(display, mProducer, sourceCrop,
            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
            static_cast<ISurfaceComposer::Rotation>(rotation));

    if (err == NO_ERROR) {
        err = mCpuConsumer->lockNextBuffer(&mBuffer);
        if (err == NO_ERROR) {
            mHaveBuffer = true;
        }
    }
    return err;
}

status_t ScreenshotClient::update(const sp<IBinder>& display,
        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
        int32_t minLayerZ, int32_t maxLayerZ,
        bool useIdentityTransform) {

    return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight,
            minLayerZ, maxLayerZ, useIdentityTransform, ISurfaceComposer::eRotateNone);
}

status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
        bool useIdentityTransform) {
    return ScreenshotClient::update(display, sourceCrop, 0, 0,
            INT32_MIN, INT32_MAX,
            useIdentityTransform, ISurfaceComposer::eRotateNone);
}

status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
        uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) {
    return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight,
            INT32_MIN, INT32_MAX,
            useIdentityTransform, ISurfaceComposer::eRotateNone);
}

void ScreenshotClient::release() {
    if (mHaveBuffer) {
        mCpuConsumer->unlockBuffer(mBuffer);
        memset(&mBuffer, 0, sizeof(mBuffer));
        mHaveBuffer = false;
    }
    mCpuConsumer.clear();
}

void const* ScreenshotClient::getPixels() const {
    return mBuffer.data;
}

uint32_t ScreenshotClient::getWidth() const {
    return mBuffer.width;
}

uint32_t ScreenshotClient::getHeight() const {
    return mBuffer.height;
}

PixelFormat ScreenshotClient::getFormat() const {
    return mBuffer.format;
}

uint32_t ScreenshotClient::getStride() const {
    return mBuffer.stride;
}

size_t ScreenshotClient::getSize() const {
    return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format);
}

android_dataspace ScreenshotClient::getDataSpace() const {
    return mBuffer.dataSpace;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
}; // namespace android
}; // namespace android
Loading