/*
// Copyright (c) 2014 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
#ifndef __MULTIDISPLAY_OBSERVER_H
#define __MULTIDISPLAY_OBSERVER_H
#ifdef TARGET_HAS_MULTIPLE_DISPLAY
#include <display/MultiDisplayService.h>
#include <SimpleThread.h>
#else
#include <utils/Errors.h>
#endif
#include <string.h>
namespace android {
namespace intel {
struct VideoSourceInfo {
VideoSourceInfo() {
memset(this, 0, sizeof(VideoSourceInfo));
}
int width;
int height;
int frameRate;
bool isProtected;
};
#ifdef TARGET_HAS_MULTIPLE_DISPLAY
class MultiDisplayObserver;
class MultiDisplayCallback : public BnMultiDisplayCallback {
public:
MultiDisplayCallback(MultiDisplayObserver *observer);
virtual ~MultiDisplayCallback();
status_t blankSecondaryDisplay(bool blank);
status_t updateVideoState(int sessionId, MDS_VIDEO_STATE state);
status_t setHdmiTiming(const MDSHdmiTiming& timing);
status_t setHdmiScalingType(MDS_SCALING_TYPE type);
status_t setHdmiOverscan(int hValue, int vValue);
status_t updateInputState(bool state);
private:
MultiDisplayObserver *mDispObserver;
MDS_VIDEO_STATE mVideoState;
};
class MultiDisplayObserver {
public:
MultiDisplayObserver();
virtual ~MultiDisplayObserver();
public:
bool initialize();
void deinitialize();
status_t notifyHotPlug(bool connected);
status_t getVideoSourceInfo(int sessionID, VideoSourceInfo* info);
int getVideoSessionNumber();
bool isExternalDeviceTimingFixed() const;
status_t notifyWidiConnectionStatus(bool connected);
status_t setDecoderOutputResolution(int sessionID,
int32_t width, int32_t height,
int32_t offX, int32_t offY,
int32_t bufWidth, int32_t bufHeight);
private:
bool isMDSRunning();
bool initMDSClient();
bool initMDSClientAsync();
void deinitMDSClient();
status_t blankSecondaryDisplay(bool blank);
status_t updateVideoState(int sessionId, MDS_VIDEO_STATE state);
status_t setHdmiTiming(const MDSHdmiTiming& timing);
status_t updateInputState(bool active);
friend class MultiDisplayCallback;
private:
enum {
THREAD_LOOP_DELAY = 10, // 10 ms
THREAD_LOOP_BOUND = 2000, // 20s
};
private:
sp<IMultiDisplayCallbackRegistrar> mMDSCbRegistrar;
sp<IMultiDisplayInfoProvider> mMDSInfoProvider;
sp<IMultiDisplayConnectionObserver> mMDSConnObserver;
sp<IMultiDisplayDecoderConfig> mMDSDecoderConfig;
sp<MultiDisplayCallback> mMDSCallback;
mutable Mutex mLock;
Condition mCondition;
int mThreadLoopCount;
bool mDeviceConnected;
// indicate external devices's timing is set
bool mExternalHdmiTiming;
bool mInitialized;
private:
DECLARE_THREAD(MDSClientInitThread, MultiDisplayObserver);
};
#else
// dummy declaration and implementation of MultiDisplayObserver
class MultiDisplayObserver {
public:
MultiDisplayObserver() {}
virtual ~MultiDisplayObserver() {}
bool initialize() { return true; }
void deinitialize() {}
status_t notifyHotPlug(bool connected) { return NO_ERROR; }
status_t getVideoSourceInfo(int sessionID, VideoSourceInfo* info) { return INVALID_OPERATION; }
int getVideoSessionNumber() { return 0; }
bool isExternalDeviceTimingFixed() const { return false; }
status_t notifyWidiConnectionStatus(bool connected) { return NO_ERROR; }
status_t setDecoderOutputResolution(
int sessionID,
int32_t width, int32_t height,
int32_t, int32_t, int32_t, int32_t) { return NO_ERROR; }
};
#endif //TARGET_HAS_MULTIPLE_DISPLAY
} // namespace intel
} // namespace android
#endif /* __MULTIMultiDisplayObserver_H_ */