[Samsung Galaxy Nexus] mrzzheng:
[Update 10/21/2012]

Added Phone.apk for AOKP JB Build 5;

This thread is dedicated to the method of modifying Phone.apk so that when an outgoing call is connected (answered) the phone vibrates to notify. This feature is useful when driving and is good for health as the wireless signal boosts at the instant when a call is connected so it is better to keep it at a distance and be notified as soon as it is connected.

The method here is inspired by the codes in CM9, but much simpler: only less than 30 lines of smali codes are added to a single file. It works on the latest Phone.apk source codes, and also a modded Phone.apk for AOKP M6 is provided as an attachment. Feel free to mod it in your own ROM, but I just did for AOKP (at least for now) since I would stick to that ROM for best LED notification support.

After baksmali-ing Phone.apk, the file to modify is CallNotifier.smali. Added codes are marked by "+" and "+ { }" and are in red. All modifications below are based on AOKP M6.

1. Add two instance variables

# instance fields
...
[COLOR="Red"]+.field private mVibrator:Landroid/os/Vibrator;
+.field private mLastVibratedCall:J
[/COLOR]

2. Modify init method to initialize Vibrator

.method private constructor <init>(Lcom/android/phone/PhoneApp;Lcom/android/internal/telephony/Phone;Lcom/android/phone/Ringer;Lcom/android/phone/BluetoothHandsfree;Lcom/android/phone/CallLogAsync;)V
.registers 11
.parameter "app"
.parameter "phone"
.parameter "ringer"
.parameter "btMgr"
.parameter "callLog"

.prologue
const/4 v3, 0x0

.line 198
invoke-direct {p0}, Landroid/os/Handler;-><init>()V

[COLOR="red"]+ new-instance v2, Landroid/os/Vibrator;
+ invoke-direct {v2}, Landroid/os/Vibrator;-><init>()V
+ iput-object v2, p0, Lcom/android/phone/CallNotifier;->mVibrator:Landroid/os/Vibrator;
[/COLOR]
.line 105
iput-boolean v3, p0, Lcom/android/phone/CallNotifier;->mCallWaitingTimeOut:Z

Note: for JB, use

[COLOR="red"]+ new-instance v2, Landroid/os/SystemVibrator;;
+ invoke-direct {v2}, Landroid/os/SystemVibrator;-><init>()V
[/COLOR]

3. Add the codes in method onPhoneStateChanged to implement the vibrate logic when an outgoing call is connected (with removal of potential repetitive vibrates). This happens right after the CallWaitingTonePlayer codes and before the setAudioMode codes.

.method private onPhoneStateChanged(Landroid/os/AsyncResult;)V
...
if-ne v4, v6, :cond_ae

.line 801
iget-object v6, p0, Lcom/android/phone/CallNotifier;->mCallWaitingTonePlayer:Lcom/android/phone/CallNotifier$InCallTonePlayer;
if-eqz v6, :cond_72

.line 802
iget-object v6, p0, Lcom/android/phone/CallNotifier;->mCallWaitingTonePlayer:Lcom/android/phone/CallNotifier$InCallTonePlayer;
invoke-virtual {v6}, Lcom/android/phone/CallNotifier$InCallTonePlayer;->stopTone()V

.line 803
iput-object v13, p0, Lcom/android/phone/CallNotifier;->mCallWaitingTonePlayer:Lcom/android/phone/CallNotifier$InCallTonePlayer;

.line 808
:cond_72

[COLOR="red"]+ {
invoke-interface {v3}, Lcom/android/internal/telephony/Phone;->getForegroundCall()Lcom/android/internal/telephony/Call;
move-result-object v6
invoke-virtual {v6}, Lcom/android/internal/telephony/Call;->getState()Lcom/android/internal/telephony/Call$State;
move-result-object v6
sget-object v9, Lcom/android/internal/telephony/Call$State;->ACTIVE:Lcom/android/internal/telephony/Call$State;
if-ne v6, v9, :cond_72end

invoke-interface {v3}, Lcom/android/internal/telephony/Phone;->getForegroundCall()Lcom/android/internal/telephony/Call;
move-result-object v6
invoke-virtual {v6}, Lcom/android/internal/telephony/Call;->getLatestConnection()Lcom/android/internal/telephony/Connection;
move-result-object v6
invoke-virtual {v6}, Lcom/android/internal/telephony/Connection;->isIncoming()Z
move-result v9
if-nez v9, :cond_72end

invoke-virtual {v6}, Lcom/android/internal/telephony/Connection;->getCreateTime()J
move-result-wide v5
iget-wide v9, p0, Lcom/android/phone/CallNotifier;->mLastVibratedCall:J
cmp-long v9, v5, v9
if-eqz v9, :cond_72end

iput-wide v5, p0, Lcom/android/phone/CallNotifier;->mLastVibratedCall:J
iget-object v6, p0, Lcom/android/phone/CallNotifier;->mVibrator:Landroid/os/Vibrator;
const-wide/16 v9, 0x100
invoke-virtual {v6, v9, v10}, Landroid/os/Vibrator;->vibrate(J)V

:cond_72end
}
[/COLOR]
iget-object v6, p0, Lcom/android/phone/CallNotifier;->mCM:Lcom/android/internal/telephony/CallManager;
invoke-static {v6}, Lcom/android/phone/PhoneUtils;->setAudioMode(Lcom/android/internal/telephony/CallManager;)V
...

As you can see only a small amount of codes is needed to implement the feature. What the mod does in detail:

(1) When a call changes its state to ACTIVE,

(2) Check if it is outgoing,

(3) Also check if it has already vibrated on connect/answer (if we don't have this code then an outgoing connected call will vibrate each time the Phone app switches in/out home screen),

(4) If Y in (2) and N in (3), then vibrate and store the creation time of this call for future checks in (3).

Note that the codes do not create any new objects when a call is connected/answered so the memory overhead should be approximately zero.

See attachment for the modded Phone.apk for AOKP M6. I may do it also for JB ROMs when I switch to them. If you want to cook this mod into your own ROM feel free to do so.

Phone.apk for AOKP JB Build 5 is added on 10/21/2012.