blob: c3348c9b54abcb674dd44db7b78ffd1293ba4342
1 | #define LOG_TAG "Tv" |
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/Tv.h> |
9 | #include <include/ITvService.h> |
10 | |
11 | // client singleton for tv service binder interface |
12 | Mutex Tv::mLock; |
13 | sp<ITvService> Tv::mTvService; |
14 | sp<Tv::DeathNotifier> Tv::mDeathNotifier; |
15 | |
16 | // establish binder interface to tv service |
17 | const sp<ITvService> &Tv::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 | |
40 | Tv::Tv() |
41 | { |
42 | init(); |
43 | } |
44 | |
45 | // construct a tv client from an existing tv remote |
46 | sp<Tv> Tv::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<Tv> c = new Tv(); |
55 | if (tv->connect(c) == NO_ERROR) { |
56 | c->mStatus = NO_ERROR; |
57 | c->mTv = tv; |
58 | tv->asBinder()->linkToDeath(c); |
59 | } |
60 | return c; |
61 | } |
62 | |
63 | void Tv::init() |
64 | { |
65 | mStatus = UNKNOWN_ERROR; |
66 | } |
67 | |
68 | Tv::~Tv() |
69 | { |
70 | disconnect(); |
71 | } |
72 | |
73 | sp<Tv> Tv::connect() |
74 | { |
75 | ALOGD("Tv::connect------------------------------------------"); |
76 | sp<Tv> c = new Tv(); |
77 | const sp<ITvService> &cs = getTvService(); |
78 | if (cs != 0) { |
79 | c->mTv = cs->connect(c); |
80 | } |
81 | if (c->mTv != 0) { |
82 | c->mTv->asBinder()->linkToDeath(c); |
83 | c->mStatus = NO_ERROR; |
84 | } else { |
85 | c.clear(); |
86 | } |
87 | return c; |
88 | } |
89 | |
90 | void Tv::disconnect() |
91 | { |
92 | ALOGD("disconnect"); |
93 | if (mTv != 0) { |
94 | mTv->disconnect(); |
95 | mTv->asBinder()->unlinkToDeath(this); |
96 | mTv = 0; |
97 | } |
98 | } |
99 | |
100 | status_t Tv::reconnect() |
101 | { |
102 | ALOGD("reconnect"); |
103 | sp <ITv> c = mTv; |
104 | if (c == 0) return NO_INIT; |
105 | return c->connect(this); |
106 | } |
107 | |
108 | sp<ITv> Tv::remote() |
109 | { |
110 | return mTv; |
111 | } |
112 | |
113 | status_t Tv::lock() |
114 | { |
115 | sp <ITv> c = mTv; |
116 | if (c == 0) return NO_INIT; |
117 | return c->lock(); |
118 | } |
119 | |
120 | status_t Tv::unlock() |
121 | { |
122 | sp <ITv> c = mTv; |
123 | if (c == 0) return NO_INIT; |
124 | return c->unlock(); |
125 | } |
126 | |
127 | status_t Tv::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 | |
134 | // |
135 | status_t Tv::createSubtitle(const sp<IMemory> &share_mem) |
136 | { |
137 | sp <ITv> c = mTv; |
138 | if (c == 0) return NO_INIT; |
139 | return c->createSubtitle(share_mem); |
140 | } |
141 | |
142 | status_t Tv::createVideoFrame(const sp<IMemory> &share_mem) |
143 | { |
144 | sp <ITv> c = mTv; |
145 | if (c == 0) return NO_INIT; |
146 | return c->createVideoFrame(share_mem); |
147 | } |
148 | |
149 | |
150 | void Tv::setListener(const sp<TvListener> &listener) |
151 | { |
152 | ALOGD("tv------------Tv::setListener"); |
153 | Mutex::Autolock _l(mLock); |
154 | mListener = listener; |
155 | } |
156 | |
157 | |
158 | // callback from tv service |
159 | void Tv::notifyCallback(int32_t msgType, const Parcel &p) |
160 | { |
161 | int size = p.dataSize(); |
162 | int pos = p.dataPosition(); |
163 | p.setDataPosition(0); |
164 | sp<TvListener> listener; |
165 | { |
166 | Mutex::Autolock _l(mLock); |
167 | listener = mListener; |
168 | } |
169 | if (listener != NULL) { |
170 | listener->notify(msgType, p); |
171 | } |
172 | } |
173 | |
174 | void Tv::binderDied(const wp<IBinder> &who) |
175 | { |
176 | ALOGW("ITv died"); |
177 | //notifyCallback(1, 2, 0); |
178 | } |
179 | |
180 | void Tv::DeathNotifier::binderDied(const wp<IBinder> &who) |
181 | { |
182 | ALOGW("-----------------binderDied"); |
183 | Mutex::Autolock _l(Tv::mLock); |
184 | Tv::mTvService.clear(); |
185 | ALOGW("kill myself"); |
186 | kill(getpid(), SIGKILL); |
187 | ALOGW("----------------Tv server died!"); |
188 | } |
189 | |
190 |