summaryrefslogtreecommitdiff
path: root/tvapi/android/libtvbinder/TvClient.cpp (plain)
blob: 432be8b3bb0bb01393b94c946a114992155af096
1#define LOG_TAG "TvClient"
2#include <utils/Log.h>
3#include <utils/threads.h>
4#include <signal.h>
5#include <binder/IServiceManager.h>
6#include <binder/IMemory.h>
7
8#include <include/TvClient.h>
9#include <include/ITvService.h>
10
11// client singleton for tv service binder interface
12Mutex TvClient::mLock;
13sp<ITvService> TvClient::mTvService;
14sp<TvClient::DeathNotifier> TvClient::mDeathNotifier;
15
16// establish binder interface to tv service
17const sp<ITvService> &TvClient::getTvService()
18{
19 Mutex::Autolock _l(mLock);
20 if (mTvService.get() == 0) {
21 sp<IServiceManager> sm = defaultServiceManager();
22 sp<IBinder> binder;
23 do {
24 binder = sm->getService(String16("aml.tvserver"));
25 if (binder != 0)
26 break;
27 ALOGW("TvService not published, waiting...");
28 usleep(500000); // 0.5 s
29 } while (true);
30 if (mDeathNotifier == NULL) {
31 mDeathNotifier = new DeathNotifier();
32 }
33 binder->linkToDeath(mDeathNotifier);
34 mTvService = interface_cast<ITvService>(binder);
35 }
36 ALOGE_IF(mTvService == 0, "no TvService!?");
37 return mTvService;
38}
39
40TvClient::TvClient()
41{
42 init();
43}
44
45// construct a tv client from an existing tv remote
46sp<TvClient> TvClient::create(const sp<ITv> &tv)
47{
48 ALOGD("create");
49 if (tv == 0) {
50 ALOGE("tv remote is a NULL pointer");
51 return 0;
52 }
53
54 sp<TvClient> c = new TvClient();
55 if (tv->connect(c) == NO_ERROR) {
56 c->mStatus = NO_ERROR;
57 c->mTv = tv;
58 IInterface::asBinder(tv)->linkToDeath(c);
59 }
60 return c;
61}
62
63void TvClient::init()
64{
65 mStatus = UNKNOWN_ERROR;
66}
67
68TvClient::~TvClient()
69{
70 disconnect();
71}
72
73sp<TvClient> TvClient::connect()
74{
75 ALOGD("Tv::connect------------------------------------------");
76 sp<TvClient> c = new TvClient();
77 const sp<ITvService> &cs = getTvService();
78 if (cs != 0) {
79 c->mTv = cs->connect(c);
80 }
81 if (c->mTv != 0) {
82 IInterface::asBinder(c->mTv)->linkToDeath(c);
83 c->mStatus = NO_ERROR;
84 } else {
85 c.clear();
86 }
87 return c;
88}
89
90void TvClient::disconnect()
91{
92 ALOGD("disconnect");
93 if (mTv != 0) {
94 mTv->disconnect();
95 IInterface::asBinder(mTv)->unlinkToDeath(this);
96 mTv = 0;
97 }
98}
99
100status_t TvClient::reconnect()
101{
102 ALOGD("reconnect");
103 sp <ITv> c = mTv;
104 if (c == 0) return NO_INIT;
105 return c->connect(this);
106}
107
108sp<ITv> TvClient::remote()
109{
110 return mTv;
111}
112
113status_t TvClient::lock()
114{
115 sp <ITv> c = mTv;
116 if (c == 0) return NO_INIT;
117 return c->lock();
118}
119
120status_t TvClient::unlock()
121{
122 sp <ITv> c = mTv;
123 if (c == 0) return NO_INIT;
124 return c->unlock();
125}
126
127status_t TvClient::processCmd(const Parcel &p, Parcel *r)
128{
129 sp <ITv> c = mTv;
130 if (c == 0) return NO_INIT;
131 return c->processCmd(p, r);
132}
133
134status_t TvClient::createSubtitle(const sp<IMemory> &share_mem)
135{
136 sp <ITv> c = mTv;
137 if (c == 0) return NO_INIT;
138 return c->createSubtitle(share_mem);
139}
140
141status_t TvClient::createVideoFrame(const sp<IMemory> &share_mem, int iSourceMode, int iCapVideoLayerOnly)
142{
143 sp <ITv> c = mTv;
144 if (c == 0) return NO_INIT;
145 return c->createVideoFrame(share_mem, iSourceMode, iCapVideoLayerOnly);
146}
147
148void TvClient::setListener(const sp<TvListener> &listener)
149{
150 ALOGD("tv------------Tv::setListener");
151 Mutex::Autolock _l(mLock);
152 mListener = listener;
153}
154
155// callback from tv service
156void TvClient::notifyCallback(int32_t msgType, const Parcel &p)
157{
158 int size = p.dataSize();
159 int pos = p.dataPosition();
160 p.setDataPosition(0);
161 sp<TvListener> listener;
162 {
163 Mutex::Autolock _l(mLock);
164 listener = mListener;
165 }
166 if (listener != NULL) {
167 listener->notify(msgType, p);
168 }
169}
170
171void TvClient::binderDied(const wp<IBinder> &who)
172{
173 ALOGW("ITv died");
174 //notifyCallback(1, 2, 0);
175}
176
177void TvClient::DeathNotifier::binderDied(const wp<IBinder> &who)
178{
179 ALOGW("-----------------binderDied");
180 Mutex::Autolock _l(TvClient::mLock);
181 TvClient::mTvService.clear();
182 ALOGW("kill myself");
183 kill(getpid(), SIGKILL);
184 ALOGW("----------------Tv server died!");
185}
186
187