registrierte Callback Listener im System finden

  • Antworten:3
Gelöschter Account
  • Forum-Beiträge: 5.136

14.09.2009, 16:10:54 via Website

Hallo zusammen,

vielleicht weiß ja einer von Euch einen Ansatzpunkt.

Ich suche eine Möglichkeit innerhalb einer App festzustellen, ob und wenn ja welche ANDEREN Apps einen "Listener" auf den gleichen Callback registriert haben. Auf das möchte ich innerhalb der App dann reagieren können.

So ein Listener sieht bspw. so aus:
1TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
2
3 PhoneStateListener callStateListener = new PhoneStateListener() {
4 public void onCallStateChanged(int state, String incomingNumber) { }; //end of callstateListener
5
6 //Hier wird der Listener registriert
7 telephonyManager.listen(callStateListener,PhoneStateListener.LISTEN_CALL_STATE);


Ich hab im Moment so gar keinen Ansatz wo ich da noch suchen könnte. Irgendwie find ich da so gar nix ... oder such eben an der falschen Stelle. Weiß einer der anderen Programmierer hier vielleicht einen Rat?

lg
Voss

lg Voss

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

14.09.2009, 16:45:07 via Website

Das würde nur funtzten wenn du Android eine Proxy Klasse unterjubeln könntest die alle Listener die sich danach registrieren "aufzeichnet". Was aber hier wohl nicht geht ;)

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

14.09.2009, 17:19:27 via Website

So, hab mal den Source ausgecheckt mittels git.

mac@mac-desktop:~/workspace/android/mydroid$ find . -name 'TelephonyManager.java'
./frameworks/base/telephony/java/android/telephony/TelephonyManager.java



1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.telephony;
18
19import com.android.internal.telephony.*;
20
21import java.util.ArrayList;
22import java.util.List;
23
24import android.annotation.SdkConstant.SdkConstantType;
25import android.annotation.SdkConstant;
26import android.content.Context;
27import android.os.Bundle;
28import android.os.RemoteException;
29import android.os.ServiceManager;
30import android.os.SystemProperties;
31
32
33/**
34 * Provides access to information about the telephony services on
35 * the device. Applications can use the methods in this class to
36 * determine telephony services and states, as well as to access some
37 * types of subscriber information. Applications can also register
38 * a listener to receive notification of telephony state changes.
39 * <p>
40 * You do not instantiate this class directly; instead, you retrieve
41 * a reference to an instance through
42 * {@link android.content.Context#getSystemService
43 * Context.getSystemService(Context.TELEPHONY_SERVICE)}.
44 * <p>
45 * Note that acess to some telephony information is
46 * permission-protected. Your application cannot access the protected
47 * information unless it has the appropriate permissions declared in
48 * its manifest file. Where permissions apply, they are noted in the
49 * the methods through which you access the protected information.
50 */
51public class TelephonyManager {
52 private static final String TAG = "TelephonyManager";
53
54 private Context mContext;
55 private ITelephonyRegistry mRegistry;
56
57 /** @hide */
58 public TelephonyManager(Context context) {
59 mContext = context;
60 mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
61 "telephony.registry"));
62 }
63
64 /** @hide */
65 private TelephonyManager() {
66 }
67
68 private static TelephonyManager sInstance = new TelephonyManager();
69
70 /** @hide */
71 public static TelephonyManager getDefault() {
72 return sInstance;
73 }
74
75
76 //
77 // Broadcast Intent actions
78 //
79
80 /**
81 * Broadcast intent action indicating that the call state (cellular)
82 * on the device has changed.
83 *
84 * <p>
85 * The {@link #EXTRA_STATE} extra indicates the new call state.
86 * If the new state is RINGING, a second extra
87 * {@link #EXTRA_INCOMING_NUMBER} provides the incoming phone number as
88 * a String.
89 *
90 * <p class="note">
91 * Requires the READ_PHONE_STATE permission.
92 *
93 * <p class="note">
94 * This was a {@link android.content.Context#sendStickyBroadcast sticky}
95 * broadcast in version 1.0, but it is no longer sticky.
96 * Instead, use {@link #getCallState} to synchronously query the current call state.
97 *
98 * @see #EXTRA_STATE
99 * @see #EXTRA_INCOMING_NUMBER
100 * @see #getCallState
101 */
102 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
103 public static final String ACTION_PHONE_STATE_CHANGED =
104 "android.intent.action.PHONE_STATE";
105
106 /**
107 * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
108 * for a String containing the new call state.
109 *
110 * @see #EXTRA_STATE_IDLE
111 * @see #EXTRA_STATE_RINGING
112 * @see #EXTRA_STATE_OFFHOOK
113 *
114 * <p class="note">
115 * Retrieve with
116 * {@link android.content.Intent#getStringExtra(String)}.
117 */
118 public static final String EXTRA_STATE = Phone.STATE_KEY;
119
120 /**
121 * Value used with {@link #EXTRA_STATE} corresponding to
122 * {@link #CALL_STATE_IDLE}.
123 */
124 public static final String EXTRA_STATE_IDLE = Phone.State.IDLE.toString();
125
126 /**
127 * Value used with {@link #EXTRA_STATE} corresponding to
128 * {@link #CALL_STATE_RINGING}.
129 */
130 public static final String EXTRA_STATE_RINGING = Phone.State.RINGING.toString();
131
132 /**
133 * Value used with {@link #EXTRA_STATE} corresponding to
134 * {@link #CALL_STATE_OFFHOOK}.
135 */
136 public static final String EXTRA_STATE_OFFHOOK = Phone.State.OFFHOOK.toString();
137
138 /**
139 * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
140 * for a String containing the incoming phone number.
141 * Only valid when the new call state is RINGING.
142 *
143 * <p class="note">
144 * Retrieve with
145 * {@link android.content.Intent#getStringExtra(String)}.
146 */
147 public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
148
149
150 //
151 //
152 // Device Info
153 //
154 //
155
156 /**
157 * Returns the software version number for the device, for example,
158 * the IMEI/SV for GSM phones.
159 *
160 * <p>Requires Permission:
161 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
162 */
163 public String getDeviceSoftwareVersion() {
164 try {
165 return getSubscriberInfo().getDeviceSvn();
166 } catch (RemoteException ex) {
167 }
168 return null;
169 }
170
171 /**
172 * Returns the unique device ID, for example,the IMEI for GSM
173 * phones.
174 *
175 * <p>Requires Permission:
176 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
177 */
178 public String getDeviceId() {
179 try {
180 return getSubscriberInfo().getDeviceId();
181 } catch (RemoteException ex) {
182 }
183 return null;
184 }
185
186 /**
187 * Returns the current location of the device.
188 *
189 * <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
190 * ACCESS_COARSE_LOCATION}.
191 */
192 public CellLocation getCellLocation() {
193 try {
194 Bundle bundle = getITelephony().getCellLocation();
195 return CellLocation.newFromBundle(bundle);
196 } catch (RemoteException ex) {
197 }
198 return null;
199 }
200
201 /**
202 * Enables location update notifications. {@link PhoneStateListener#onCellLocationChanged
203 * PhoneStateListener.onCellLocationChanged} will be called on location updates.
204 *
205 * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
206 * CONTROL_LOCATION_UPDATES}
207 *
208 * @hide
209 */
210 public void enableLocationUpdates() {
211 try {
212 getITelephony().enableLocationUpdates();
213 } catch (RemoteException ex) {
214 }
215 }
216
217 /**
218 * Disables location update notifications. {@link PhoneStateListener#onCellLocationChanged
219 * PhoneStateListener.onCellLocationChanged} will be called on location updates.
220 *
221 * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
222 * CONTROL_LOCATION_UPDATES}
223 *
224 * @hide
225 */
226 public void disableLocationUpdates() {
227 try {
228 getITelephony().disableLocationUpdates();
229 } catch (RemoteException ex) {
230 }
231 }
232
233 /**
234 * Returns the neighboring cell information of the device.
235 *
236 * @return List of NeighboringCellInfo or null if info unavailable.
237 *
238 * <p>Requires Permission:
239 * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
240 */
241 public List<NeighboringCellInfo> getNeighboringCellInfo() {
242 try {
243 return getITelephony().getNeighboringCellInfo();
244 } catch (RemoteException ex) {
245 }
246 return null;
247
248 }
249
250 /**
251 * No phone module
252 */
253 public static final int PHONE_TYPE_NONE = 0;
254
255 /**
256 * GSM phone
257 */
258 public static final int PHONE_TYPE_GSM = 1;
259
260 /**
261 * Returns a constant indicating the device phone type.
262 *
263 * @see #PHONE_TYPE_NONE
264 * @see #PHONE_TYPE_GSM
265 */
266 public int getPhoneType() {
267 // in the future, we should really check this
268 return PHONE_TYPE_GSM;
269 }
270
271 //
272 //
273 // Current Network
274 //
275 //
276
277 /**
278 * Returns the alphabetic name of current registered operator.
279 * <p>
280 * Availability: Only when user is registered to a network
281 */
282 public String getNetworkOperatorName() {
283 return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA);
284 }
285
286 /**
287 * Returns the numeric name (MCC+MNC) of current registered operator.
288 * <p>
289 * Availability: Only when user is registered to a network
290 */
291 public String getNetworkOperator() {
292 return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
293 }
294
295 /**
296 * Returns true if the device is considered roaming on the current
297 * network, for GSM purposes.
298 * <p>
299 * Availability: Only when user registered to a network
300 */
301 public boolean isNetworkRoaming() {
302 return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
303 }
304
305 /**
306 * Returns the ISO country code equivilent of the current registered
307 * operator's MCC (Mobile Country Code).
308 * <p>
309 * Availability: Only when user is registered to a network
310 */
311 public String getNetworkCountryIso() {
312 return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
313 }
314
315 /** Network type is unknown */
316 public static final int NETWORK_TYPE_UNKNOWN = 0;
317 /** Current network is GPRS */
318 public static final int NETWORK_TYPE_GPRS = 1;
319 /** Current network is EDGE */
320 public static final int NETWORK_TYPE_EDGE = 2;
321 /** Current network is UMTS */
322 public static final int NETWORK_TYPE_UMTS = 3;
323
324 /**
325 * Returns a constant indicating the radio technology (network type)
326 * currently in use on the device.
327 * @return the network type
328 *
329 * @see #NETWORK_TYPE_UNKNOWN
330 * @see #NETWORK_TYPE_GPRS
331 * @see #NETWORK_TYPE_EDGE
332 * @see #NETWORK_TYPE_UMTS
333 */
334 public int getNetworkType() {
335 String prop = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE);
336 if ("GPRS".equals(prop)) {
337 return NETWORK_TYPE_GPRS;
338 }
339 else if ("EDGE".equals(prop)) {
340 return NETWORK_TYPE_EDGE;
341 }
342 else if ("UMTS".equals(prop)) {
343 return NETWORK_TYPE_UMTS;
344 }
345 else {
346 return NETWORK_TYPE_UNKNOWN;
347 }
348 }
349
350 /**
351 * Returns a string representation of the radio technology (network type)
352 * currently in use on the device.
353 * @return the name of the radio technology
354 *
355 * @hide pending API council review
356 */
357 public String getNetworkTypeName() {
358 switch (getNetworkType()) {
359 case NETWORK_TYPE_GPRS:
360 return "GPRS";
361 case NETWORK_TYPE_EDGE:
362 return "EDGE";
363 case NETWORK_TYPE_UMTS:
364 return "UMTS";
365 default:
366 return "UNKNOWN";
367 }
368 }
369
370 //
371 //
372 // SIM Card
373 //
374 //
375
376 /** SIM card state: Unknown. Signifies that the SIM is in transition
377 * between states. For example, when the user inputs the SIM pin
378 * under PIN_REQUIRED state, a query for sim status returns
379 * this state before turning to SIM_STATE_READY. */
380 public static final int SIM_STATE_UNKNOWN = 0;
381 /** SIM card state: no SIM card is available in the device */
382 public static final int SIM_STATE_ABSENT = 1;
383 /** SIM card state: Locked: requires the user's SIM PIN to unlock */
384 public static final int SIM_STATE_PIN_REQUIRED = 2;
385 /** SIM card state: Locked: requires the user's SIM PUK to unlock */
386 public static final int SIM_STATE_PUK_REQUIRED = 3;
387 /** SIM card state: Locked: requries a network PIN to unlock */
388 public static final int SIM_STATE_NETWORK_LOCKED = 4;
389 /** SIM card state: Ready */
390 public static final int SIM_STATE_READY = 5;
391
392 /**
393 * Returns a constant indicating the state of the
394 * device SIM card.
395 *
396 * @see #SIM_STATE_UNKNOWN
397 * @see #SIM_STATE_ABSENT
398 * @see #SIM_STATE_PIN_REQUIRED
399 * @see #SIM_STATE_PUK_REQUIRED
400 * @see #SIM_STATE_NETWORK_LOCKED
401 * @see #SIM_STATE_READY
402 */
403 public int getSimState() {
404 String prop = SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE);
405 if ("ABSENT".equals(prop)) {
406 return SIM_STATE_ABSENT;
407 }
408 else if ("PIN_REQUIRED".equals(prop)) {
409 return SIM_STATE_PIN_REQUIRED;
410 }
411 else if ("PUK_REQUIRED".equals(prop)) {
412 return SIM_STATE_PUK_REQUIRED;
413 }
414 else if ("NETWORK_LOCKED".equals(prop)) {
415 return SIM_STATE_NETWORK_LOCKED;
416 }
417 else if ("READY".equals(prop)) {
418 return SIM_STATE_READY;
419 }
420 else {
421 return SIM_STATE_UNKNOWN;
422 }
423 }
424
425 /**
426 * Returns the MCC+MNC (mobile country code + mobile network code) of the
427 * provider of the SIM. 5 or 6 decimal digits.
428 * <p>
429 * Availability: SIM state must be {@link #SIM_STATE_READY}
430 *
431 * @see #getSimState
432 */
433 public String getSimOperator() {
434 return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC);
435 }
436
437 /**
438 * Returns the Service Provider Name (SPN).
439 * <p>
440 * Availability: SIM state must be {@link #SIM_STATE_READY}
441 *
442 * @see #getSimState
443 */
444 public String getSimOperatorName() {
445 return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ALPHA);
446 }
447
448 /**
449 * Returns the ISO country code equivalent for the SIM provider's country code.
450 */
451 public String getSimCountryIso() {
452 return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ISO_COUNTRY);
453 }
454
455 /**
456 * Returns the serial number of the SIM, if applicable.
457 * <p>
458 * Requires Permission:
459 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
460 */
461 public String getSimSerialNumber() {
462 try {
463 return getSubscriberInfo().getSimSerialNumber();
464 } catch (RemoteException ex) {
465 }
466 return null;
467 }
468
469 //
470 //
471 // Subscriber Info
472 //
473 //
474
475 /**
476 * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
477 * <p>
478 * Requires Permission:
479 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
480 */
481 public String getSubscriberId() {
482 try {
483 return getSubscriberInfo().getSubscriberId();
484 } catch (RemoteException ex) {
485 }
486 return null;
487 }
488
489 /**
490 * Returns the phone number string for line 1, for example, the MSISDN
491 * for a GSM phone.
492 * <p>
493 * Requires Permission:
494 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
495 */
496 public String getLine1Number() {
497 try {
498 return getSubscriberInfo().getLine1Number();
499 } catch (RemoteException ex) {
500 }
501 return null;
502 }
503
504 /**
505 * Returns the alphabetic identifier associated with the line 1 number.
506 * <p>
507 * Requires Permission:
508 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
509 * @hide
510 * nobody seems to call this.
511 */
512 public String getLine1AlphaTag() {
513 try {
514 return getSubscriberInfo().getLine1AlphaTag();
515 } catch (RemoteException ex) {
516 }
517 return null;
518 }
519
520 /**
521 * Returns the voice mail number.
522 * <p>
523 * Requires Permission:
524 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
525 */
526 public String getVoiceMailNumber() {
527 try {
528 return getSubscriberInfo().getVoiceMailNumber();
529 } catch (RemoteException ex) {
530 }
531 return null;
532 }
533
534 /**
535 * Retrieves the alphabetic identifier associated with the voice
536 * mail number.
537 * <p>
538 * Requires Permission:
539 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
540 */
541 public String getVoiceMailAlphaTag() {
542 try {
543 return getSubscriberInfo().getVoiceMailAlphaTag();
544 } catch (RemoteException ex) {
545 }
546 return null;
547 }
548
549 private IPhoneSubInfo getSubscriberInfo() {
550 // get it each time because that process crashes a lot
551 return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
552 }
553
554
555 /** Device call state: No activity. */
556 public static final int CALL_STATE_IDLE = 0;
557 /** Device call state: Ringing. A new call arrived and is
558 * ringing or waiting. In the latter case, another call is
559 * already active. */
560 public static final int CALL_STATE_RINGING = 1;
561 /** Device call state: Off-hook. At least one call exists
562 * that is dialing, active, or on hold, and no calls are ringing
563 * or waiting. */
564 public static final int CALL_STATE_OFFHOOK = 2;
565
566 /**
567 * Returns a constant indicating the call state (cellular) on the device.
568 */
569 public int getCallState() {
570 try {
571 return getITelephony().getCallState();
572 } catch (RemoteException ex) {
573 // the phone process is restarting.
574 return CALL_STATE_IDLE;
575 }
576 }
577
578 /** Data connection activity: No traffic. */
579 public static final int DATA_ACTIVITY_NONE = 0x00000000;
580 /** Data connection activity: Currently receiving IP PPP traffic. */
581 public static final int DATA_ACTIVITY_IN = 0x00000001;
582 /** Data connection activity: Currently sending IP PPP traffic. */
583 public static final int DATA_ACTIVITY_OUT = 0x00000002;
584 /** Data connection activity: Currently both sending and receiving
585 * IP PPP traffic. */
586 public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
587
588 /**
589 * Returns a constant indicating the type of activity on a data connection
590 * (cellular).
591 *
592 * @see #DATA_ACTIVITY_NONE
593 * @see #DATA_ACTIVITY_IN
594 * @see #DATA_ACTIVITY_OUT
595 * @see #DATA_ACTIVITY_INOUT
596 */
597 public int getDataActivity() {
598 try {
599 return getITelephony().getDataActivity();
600 } catch (RemoteException ex) {
601 // the phone process is restarting.
602 return DATA_ACTIVITY_NONE;
603 }
604 }
605
606 /** Data connection state: Disconnected. IP traffic not available. */
607 public static final int DATA_DISCONNECTED = 0;
608 /** Data connection state: Currently setting up a data connection. */
609 public static final int DATA_CONNECTING = 1;
610 /** Data connection state: Connected. IP traffic should be available. */
611 public static final int DATA_CONNECTED = 2;
612 /** Data connection state: Suspended. The connection is up, but IP
613 * traffic is temporarily unavailable. For example, in a 2G network,
614 * data activity may be suspended when a voice call arrives. */
615 public static final int DATA_SUSPENDED = 3;
616
617 /**
618 * Returns a constant indicating the current data connection state
619 * (cellular).
620 *
621 * @see #DATA_DISCONNECTED
622 * @see #DATA_CONNECTING
623 * @see #DATA_CONNECTED
624 * @see #DATA_SUSPENDED
625 */
626 public int getDataState() {
627 try {
628 return getITelephony().getDataState();
629 } catch (RemoteException ex) {
630 // the phone process is restarting.
631 return DATA_DISCONNECTED;
632 }
633 }
634
635 private ITelephony getITelephony() {
636 return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
637 }
638
639 //
640 //
641 // PhoneStateListener
642 //
643 //
644
645 /**
646 * Registers a listener object to receive notification of changes
647 * in specified telephony states.
648 * <p>
649 * To register a listener, pass a {@link PhoneStateListener}
650 * and specify at least one telephony state of interest in
651 * the events argument.
652 *
653 * At registration, and when a specified telephony state
654 * changes, the telephony manager invokes the appropriate
655 * callback method on the listener object and passes the
656 * current (udpated) values.
657 * <p>
658 * To unregister a listener, pass the listener object and set the
659 * events argument to
660 * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
661 *
662 * @param listener The {@link PhoneStateListener} object to register
663 * (or unregister)
664 * @param events The telephony state(s) of interest to the listener,
665 * as a bitwise-OR combination of {@link PhoneStateListener}
666 * LISTEN_ flags.
667 */
668 public void listen(PhoneStateListener listener, int events) {
669 String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
670 try {
671 Boolean notifyNow = (getITelephony() != null);
672 mRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
673 } catch (RemoteException ex) {
674 // system process dead
675 }
676 }
677}


Die mRegistry scheint interresant zu sein:
mac@mac-desktop:~/workspace/android/mydroid$ find . -name 'ITelephonyRegistry.aidl'
./frameworks/base/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aid
l

1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony;
18
19import android.content.Intent;
20import android.os.Bundle;
21import android.telephony.ServiceState;
22import com.android.internal.telephony.IPhoneStateListener;
23
24interface ITelephonyRegistry {
25 void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);
26
27 void notifyCallState(int state, String incomingNumber);
28 void notifyServiceState(in ServiceState state);
29 void notifySignalStrength(int signalStrengthASU);
30 void notifyMessageWaitingChanged(boolean mwi);
31 void notifyCallForwardingChanged(boolean cfi);
32 void notifyDataActivity(int state);
33 void notifyDataConnection(int state, boolean isDataConnectivityPossible,
34 String reason, String apn, String interfaceName);
35 void notifyDataConnectionFailed(String reason);
36 void notifyCellLocation(in Bundle cellLocation);
37}

Das AIDL ist nur der Stub, wo ist jetzt die Impl. davon ?
Sollte wohl ebenfalls so heissen, nur mit .java.

Bingo:

mac@mac-desktop:~/workspace/android/mydroid$ find . -name 'TelephonyRegistry.java'
./frameworks/base/services/java/com/android/server/TelephonyRegistry.java



1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
19import android.content.Context;
20import android.content.Intent;
21import android.content.pm.PackageManager;
22import android.os.Binder;
23import android.os.Bundle;
24import android.os.IBinder;
25import android.os.RemoteException;
26import android.telephony.CellLocation;
27import android.telephony.PhoneStateListener;
28import android.telephony.ServiceState;
29import android.telephony.TelephonyManager;
30import android.text.TextUtils;
31import android.util.Log;
32
33import java.util.ArrayList;
34import java.io.FileDescriptor;
35import java.io.PrintWriter;
36
37import com.android.internal.app.IBatteryStats;
38import com.android.internal.telephony.ITelephonyRegistry;
39import com.android.internal.telephony.IPhoneStateListener;
40import com.android.internal.telephony.DefaultPhoneNotifier;
41import com.android.internal.telephony.Phone;
42import com.android.internal.telephony.PhoneStateIntentReceiver;
43import com.android.internal.telephony.TelephonyIntents;
44import com.android.server.am.BatteryStatsService;
45
46
47/**
48 * Since phone process can be restarted, this class provides a centralized
49 * place that applications can register and be called back from.
50 */
51class TelephonyRegistry extends ITelephonyRegistry.Stub {
52 private static final String TAG = "TelephonyRegistry";
53
54 private static class Record {
55 String pkgForDebug;
56 IBinder binder;
57 IPhoneStateListener callback;
58 int events;
59 }
60
61 private final Context mContext;
62 private final ArrayList<Record> mRecords = new ArrayList();
63 private final IBatteryStats mBatteryStats;
64
65 private int mCallState = TelephonyManager.CALL_STATE_IDLE;
66 private String mCallIncomingNumber = "";
67 private ServiceState mServiceState = new ServiceState();
68 private int mSignalStrength = -1;
69 private boolean mMessageWaiting = false;
70 private boolean mCallForwarding = false;
71 private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
72 private int mDataConnectionState = TelephonyManager.DATA_CONNECTED;
73 private boolean mDataConnectionPossible = false;
74 private String mDataConnectionReason = "";
75 private String mDataConnectionApn = "";
76 private String mDataConnectionInterfaceName = "";
77 private Bundle mCellLocation = new Bundle();
78
79 // we keep a copy of all of the sate so we can send it out when folks register for it
80 //
81 // In these calls we call with the lock held. This is safe becasuse remote
82 // calls go through a oneway interface and local calls going through a handler before
83 // they get to app code.
84
85 TelephonyRegistry(Context context) {
86 CellLocation.getEmpty().fillInNotifierBundle(mCellLocation);
87 mContext = context;
88 mBatteryStats = BatteryStatsService.getService();
89 }
90
91 public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
92 boolean notifyNow) {
93 //Log.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events));
94 if (events != 0) {
95 // check permissions
96 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
97 mContext.enforceCallingOrSelfPermission(
98 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
99
100 }
101
102 synchronized (mRecords) {
103 // register
104 Record r = null;
105 find_and_add: {
106 IBinder b = callback.asBinder();
107 final int N = mRecords.size();
108 for (int i=0; i<N; i++) {
109 r = mRecords.get(i);
110 if (b == r.binder) {
111 break find_and_add;
112 }
113 }
114 r = new Record();
115 r.binder = b;
116 r.callback = callback;
117 r.pkgForDebug = pkgForDebug;
118 mRecords.add(r);
119 }
120 int send = events & (events ^ r.events);
121 r.events = events;
122 if (notifyNow) {
123 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
124 sendServiceState(r, mServiceState);
125 }
126 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
127 try {
128 r.callback.onSignalStrengthChanged(mSignalStrength);
129 } catch (RemoteException ex) {
130 remove(r.binder);
131 }
132 }
133 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
134 try {
135 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
136 } catch (RemoteException ex) {
137 remove(r.binder);
138 }
139 }
140 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
141 try {
142 r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
143 } catch (RemoteException ex) {
144 remove(r.binder);
145 }
146 }
147 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
148 sendCellLocation(r, mCellLocation);
149 }
150 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
151 try {
152 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
153 } catch (RemoteException ex) {
154 remove(r.binder);
155 }
156 }
157 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
158 try {
159 r.callback.onDataConnectionStateChanged(mDataConnectionState);
160 } catch (RemoteException ex) {
161 remove(r.binder);
162 }
163 }
164 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
165 try {
166 r.callback.onDataActivity(mDataActivity);
167 } catch (RemoteException ex) {
168 remove(r.binder);
169 }
170 }
171 }
172 }
173 } else {
174 remove(callback.asBinder());
175 }
176 }
177
178 private void remove(IBinder binder) {
179 synchronized (mRecords) {
180 final int N = mRecords.size();
181 for (int i=0; i<N; i++) {
182 if (mRecords.get(i).binder == binder) {
183 mRecords.remove(i);
184 return;
185 }
186 }
187 }
188 }
189
190 public void notifyCallState(int state, String incomingNumber) {
191 if (!checkPhoneStatePermission("notifyCallState()")) {
192 return;
193 }
194 synchronized (mRecords) {
195 mCallState = state;
196 mCallIncomingNumber = incomingNumber;
197 final int N = mRecords.size();
198 for (int i=N-1; i>=0; i--) {
199 Record r = mRecords.get(i);
200 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
201 try {
202 r.callback.onCallStateChanged(state, incomingNumber);
203 } catch (RemoteException ex) {
204 remove(r.binder);
205 }
206 }
207 }
208 }
209 broadcastCallStateChanged(state, incomingNumber);
210 }
211
212 public void notifyServiceState(ServiceState state) {
213 if (!checkPhoneStatePermission("notifyServiceState()")) {
214 return;
215 }
216 synchronized (mRecords) {
217 mServiceState = state;
218 final int N = mRecords.size();
219 for (int i=N-1; i>=0; i--) {
220 Record r = mRecords.get(i);
221 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
222 sendServiceState(r, state);
223 }
224 }
225 }
226 broadcastServiceStateChanged(state);
227 }
228
229 public void notifySignalStrength(int signalStrengthASU) {
230 if (!checkPhoneStatePermission("notifySignalStrength()")) {
231 return;
232 }
233 synchronized (mRecords) {
234 mSignalStrength = signalStrengthASU;
235 final int N = mRecords.size();
236 for (int i=N-1; i>=0; i--) {
237 Record r = mRecords.get(i);
238 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
239 try {
240 r.callback.onSignalStrengthChanged(signalStrengthASU);
241 } catch (RemoteException ex) {
242 remove(r.binder);
243 }
244 }
245 }
246 }
247 broadcastSignalStrengthChanged(signalStrengthASU);
248 }
249
250 public void notifyMessageWaitingChanged(boolean mwi) {
251 if (!checkPhoneStatePermission("notifyMessageWaitingChanged()")) {
252 return;
253 }
254 synchronized (mRecords) {
255 mMessageWaiting = mwi;
256 final int N = mRecords.size();
257 for (int i=N-1; i>=0; i--) {
258 Record r = mRecords.get(i);
259 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
260 try {
261 r.callback.onMessageWaitingIndicatorChanged(mwi);
262 } catch (RemoteException ex) {
263 remove(r.binder);
264 }
265 }
266 }
267 }
268 }
269
270 public void notifyCallForwardingChanged(boolean cfi) {
271 if (!checkPhoneStatePermission("notifyCallForwardingChanged()")) {
272 return;
273 }
274 synchronized (mRecords) {
275 mCallForwarding = cfi;
276 final int N = mRecords.size();
277 for (int i=N-1; i>=0; i--) {
278 Record r = mRecords.get(i);
279 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
280 try {
281 r.callback.onCallForwardingIndicatorChanged(cfi);
282 } catch (RemoteException ex) {
283 remove(r.binder);
284 }
285 }
286 }
287 }
288 }
289
290 public void notifyDataActivity(int state) {
291 if (!checkPhoneStatePermission("notifyDataActivity()")) {
292 return;
293 }
294 synchronized (mRecords) {
295 mDataActivity = state;
296 final int N = mRecords.size();
297 for (int i=N-1; i>=0; i--) {
298 Record r = mRecords.get(i);
299 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
300 try {
301 r.callback.onDataActivity(state);
302 } catch (RemoteException ex) {
303 remove(r.binder);
304 }
305 }
306 }
307 }
308 }
309
310 public void notifyDataConnection(int state, boolean isDataConnectivityPissible,
311 String reason, String apn, String interfaceName) {
312 if (!checkPhoneStatePermission("notifyDataConnection()")) {
313 return;
314 }
315 synchronized (mRecords) {
316 mDataConnectionState = state;
317 mDataConnectionPossible = isDataConnectivityPissible;
318 mDataConnectionReason = reason;
319 mDataConnectionApn = apn;
320 mDataConnectionInterfaceName = interfaceName;
321 final int N = mRecords.size();
322 for (int i=N-1; i>=0; i--) {
323 Record r = mRecords.get(i);
324 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
325 try {
326 r.callback.onDataConnectionStateChanged(state);
327 } catch (RemoteException ex) {
328 remove(r.binder);
329 }
330 }
331 }
332 }
333 broadcastDataConnectionStateChanged(state, isDataConnectivityPissible,
334 reason, apn, interfaceName);
335 }
336
337 public void notifyDataConnectionFailed(String reason) {
338 if (!checkPhoneStatePermission("notifyDataConnectionFailed()")) {
339 return;
340 }
341 /*
342 * This is commented out because there is on onDataConnectionFailed callback
343 * on PhoneStateListener. There should be.
344 synchronized (mRecords) {
345 mDataConnectionFailedReason = reason;
346 final int N = mRecords.size();
347 for (int i=N-1; i>=0; i--) {
348 Record r = mRecords.get(i);
349 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
350 // XXX
351 }
352 }
353 }
354 */
355 broadcastDataConnectionFailed(reason);
356 }
357
358 public void notifyCellLocation(Bundle cellLocation) {
359 if (!checkPhoneStatePermission("notifyCellLocation()")) {
360 return;
361 }
362 synchronized (mRecords) {
363 mCellLocation = cellLocation;
364 final int N = mRecords.size();
365 for (int i=N-1; i>=0; i--) {
366 Record r = mRecords.get(i);
367 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
368 sendCellLocation(r, cellLocation);
369 }
370 }
371 }
372 }
373
374 //
375 // the new callback broadcasting
376 //
377 // copy the service state object so they can't mess it up in the local calls
378 //
379 public void sendServiceState(Record r, ServiceState state) {
380 try {
381 r.callback.onServiceStateChanged(new ServiceState(state));
382 } catch (RemoteException ex) {
383 remove(r.binder);
384 }
385 }
386
387 public void sendCellLocation(Record r, Bundle cellLocation) {
388 try {
389 r.callback.onCellLocationChanged(new Bundle(cellLocation));
390 } catch (RemoteException ex) {
391 remove(r.binder);
392 }
393 }
394
395
396 @Override
397 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
398 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
399 != PackageManager.PERMISSION_GRANTED) {
400 pw.println("Permission Denial: can't dump telephony.registry from from pid="
401 + Binder.getCallingPid()
402 + ", uid=" + Binder.getCallingUid());
403 return;
404 }
405 synchronized (mRecords) {
406 final int N = mRecords.size();
407 pw.println("last known state:");
408 pw.println(" mCallState=" + mCallState);
409 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
410 pw.println(" mServiceState=" + mServiceState);
411 pw.println(" mSignalStrength=" + mSignalStrength);
412 pw.println(" mMessageWaiting=" + mMessageWaiting);
413 pw.println(" mCallForwarding=" + mCallForwarding);
414 pw.println(" mDataActivity=" + mDataActivity);
415 pw.println(" mDataConnectionState=" + mDataConnectionState);
416 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
417 pw.println(" mDataConnectionReason=" + mDataConnectionReason);
418 pw.println(" mDataConnectionApn=" + mDataConnectionApn);
419 pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
420 pw.println(" mCellLocation=" + mCellLocation);
421 pw.println("registrations: count=" + N);
422 for (int i=0; i<N; i++) {
423 Record r = mRecords.get(i);
424 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
425 }
426 }
427 }
428
429
430 //
431 // the legacy intent broadcasting
432 //
433
434 private void broadcastServiceStateChanged(ServiceState state) {
435 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
436 Bundle data = new Bundle();
437 state.fillInNotifierBundle(data);
438 intent.putExtras(data);
439 mContext.sendStickyBroadcast(intent);
440 }
441
442 private void broadcastSignalStrengthChanged(int asu) {
443 long ident = Binder.clearCallingIdentity();
444 try {
445 mBatteryStats.notePhoneSignalStrength(asu);
446 } catch (RemoteException e) {
447 } finally {
448 Binder.restoreCallingIdentity(ident);
449 }
450
451 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
452 intent.putExtra(PhoneStateIntentReceiver.INTENT_KEY_ASU, asu);
453 mContext.sendStickyBroadcast(intent);
454 }
455
456 private void broadcastCallStateChanged(int state, String incomingNumber) {
457 long ident = Binder.clearCallingIdentity();
458 try {
459 if (state == TelephonyManager.CALL_STATE_IDLE) {
460 mBatteryStats.notePhoneOff();
461 } else {
462 mBatteryStats.notePhoneOn();
463 }
464 } catch (RemoteException e) {
465 } finally {
466 Binder.restoreCallingIdentity(ident);
467 }
468
469 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
470 intent.putExtra(Phone.STATE_KEY,
471 DefaultPhoneNotifier.convertCallState(state).toString());
472 if (!TextUtils.isEmpty(incomingNumber)) {
473 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
474 }
475 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
476 }
477
478 private void broadcastDataConnectionStateChanged(int state, boolean isDataConnectivityPossible,
479 String reason, String apn, String interfaceName) {
480 // Note: not reporting to the battery stats service here, because the
481 // status bar takes care of that after taking into account all of the
482 // required info.
483 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
484 intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
485 if (!isDataConnectivityPossible) {
486 intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
487 }
488 if (reason != null) {
489 intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
490 }
491 intent.putExtra(Phone.DATA_APN_KEY, apn);
492 intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
493 mContext.sendStickyBroadcast(intent);
494 }
495
496 private void broadcastDataConnectionFailed(String reason) {
497 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
498 intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
499 mContext.sendStickyBroadcast(intent);
500 }
501
502 private boolean checkPhoneStatePermission(String method) {
503 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
504 == PackageManager.PERMISSION_GRANTED) {
505 return true;
506 }
507 String msg = "Modify Phone State Permission Denial: " + method + " from pid="
508 + Binder.getCallingPid()
509 + ", uid=" + Binder.getCallingUid();
510 Log.w(TAG, msg);
511 return false;
512 }
513}

Die CallbackHandler liegen wohl in:

1private final ArrayList<Record> mRecords = new ArrayList();


Sieht momentan nicht danach aus als ob hier ein Ansatzpunkt zu finden wäre das auszulesen ...


- Mac

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Gelöschter Account
  • Forum-Beiträge: 5.136

14.09.2009, 19:56:30 via Website

Servus Mac,

ähnlich weit war ich auch schon ... auf einem anderen Weg aber viele Wege führen nach Rom.

Das Grundübel liegt mal darin, dass man an die zu Grunde liegenden android.internal.telephony usw. ja mal überhaupt nicht herankommt. Nicht mal mit Reflection ist dem beizukommen. Das haben die total weggekapselt.

Schade schade .. *seufz*

Trotzdem mal herzlichen Dank für Deine Bemühungen!!
Dachte, vielleicht gibts da noch ein Hintertürchen das ich nur nicht sehe ..


lg
Voss

lg Voss

Antworten