diff --git a/.classpath b/.classpath
index 442e71149..be759ecd4 100644
--- a/.classpath
+++ b/.classpath
@@ -1,11 +1,11 @@
-
+
-
+
diff --git a/build.xml b/build.xml
new file mode 100644
index 000000000..e77878e4d
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,1336 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @{elseText}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @{elseText}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Running tests ...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Uninstalling @{app.package} from the default emulator or device...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gathering info for ${ant.project.name}...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Building Libraries
+
+
+ ############################################
+ **** Back to project ${ant.project.name} ****
+ ############################################
+
+
+
+
+
+
+
+
+
+
+
+ Building tested project at ${tested.project.absolute.dir}
+
+
+
+
+ ############################################
+ **** Back to project ${ant.project.name} ****
+ ############################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Switching from instrumented to non-instrumented build.
+ Deleting previous compilation output:
+
+
+
+
+ Creating output directories if needed...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ----------
+ Handling aidl files...
+
+
+
+
+
+ ----------
+ Handling RenderScript files...
+
+
+
+
+ ----------
+ Handling Resources...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Creating library output jar file...
+
+
+
+
+
+
+ Custom jar packaging exclusion: ${android.package.excludes}
+
+
+
+
+
+
+
+
+
+
+
+
+ Instrumenting classes from ${out.absolute.dir}/classes...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @${proguard.config}
+ -injars ${project.jars}
+ -outjars "${obfuscated.jar.file}"
+ -libraryjars ${android.libraryjars}
+ -dump "${obfuscate.absolute.dir}/dump.txt"
+ -printseeds "${obfuscate.absolute.dir}/seeds.txt"
+ -printusage "${obfuscate.absolute.dir}/usage.txt"
+ -printmapping "${obfuscate.absolute.dir}/mapping.txt"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Debug Package: ${out.final.file}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No key.store and key.alias properties found in build.properties.
+ Please sign ${out.packaged.file} manually
+ and run zipalign from the Android SDK tools.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ *************************************************
+ **** Android Manifest has debuggable=true ****
+ **** Doing DEBUG packaging with RELEASE keys ****
+ *************************************************
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Signing final apk...
+
+
+
+
+ Release Package: ${out.final.file}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Instrumented Package: ${out.final.file}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WARNING: Code Coverage is currently only supported on the emulator and rooted devices.
+
+
+
+
+
+
+
+ Downloading coverage file into project directory...
+
+
+
+
+
+
+ Extracting coverage report...
+
+
+
+
+
+
+
+
+
+
+
+ Cleaning up temporary files...
+
+
+ Saving the report file in ${basedir}/coverage/coverage.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Installing ${out.final.file} onto default emulator or device...
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Install file not specified.
+
+ 'ant install' now requires the build target to be specified as well.
+
+
+ ant debug install
+ ant release install
+ ant instrument install
+ This will build the given package and install it.
+
+ Alternatively, you can use
+ ant installd
+ ant installr
+ ant installi
+ ant installt
+ to only install an existing package (this will not rebuild the package.)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Could not find application package in manifest. Cannot run 'adb uninstall'.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Could not find tested application package in manifest. Cannot run 'adb uninstall'.
+
+
+
+
+
+
+
+
+
+
+ Android Ant Build. Available targets:
+ help: Displays this help.
+ clean: Removes output files created by other targets.
+ The 'all' target can be used to clean dependencies
+ (tested projects and libraries)at the same time
+ using: 'ant all clean'
+ debug: Builds the application and signs it with a debug key.
+ release: Builds the application. The generated apk file must be
+ signed before it is published.
+ instrument:Builds an instrumented package and signs it with a
+ debug key.
+ test: Runs the tests. Project must be a test project and
+ must have been built. Typical usage would be:
+ ant [emma] debug installt test
+ emma: Transiently enables code coverage for subsequent
+ targets.
+ install: Installs the newly build package. Must either be used
+ in conjunction with a build target (debug/release/
+ instrument) or with the proper suffix indicating
+ which package to install (see below).
+ If the application was previously installed, the
+ application is reinstalled if the signature matches.
+ installd: Installs (only) the debug package.
+ installr: Installs (only) the release package.
+ installi: Installs (only) the instrumented package.
+ installt: Installs (only) the test and tested packages.
+ uninstall: Uninstalls the application from a running emulator or
+ device.
+
+
diff --git a/res/drawable/conf_speaking.png b/res/drawable/conf_speaking.png
new file mode 100644
index 000000000..2324d81c3
Binary files /dev/null and b/res/drawable/conf_speaking.png differ
diff --git a/res/layout/conf_callee.xml b/res/layout/conf_callee.xml
index f2fa06a33..e3792b58d 100644
--- a/res/layout/conf_callee.xml
+++ b/res/layout/conf_callee.xml
@@ -23,8 +23,9 @@
android:layout_width="wrap_content" android:layout_height="fill_parent"
android:layout_centerVertical="true">
-
-
+
+
+
diff --git a/src/org/linphone/AbstractCalleesActivity.java b/src/org/linphone/AbstractCalleesActivity.java
index 3b40cb296..c88db583b 100644
--- a/src/org/linphone/AbstractCalleesActivity.java
+++ b/src/org/linphone/AbstractCalleesActivity.java
@@ -67,6 +67,7 @@ public abstract class AbstractCalleesActivity extends ListActivity implements Li
private Handler callqualityHandler;
private List viewsToUpdateCallQuality;
+ private boolean shouldDisplayWhoIsTalking = false;
@Override
/**
* Called by the child classes AFTER their own onCreate.
@@ -215,6 +216,12 @@ public abstract class AbstractCalleesActivity extends ListActivity implements Li
}
protected final void initCallQualityListener() {
+ final int timeToRefresh;
+ if (shouldDisplayWhoIsTalking)
+ timeToRefresh = 100;
+ else
+ timeToRefresh = 1000;
+
callqualityHandler = new Handler();
viewsToUpdateCallQuality = new ArrayList();
callqualityHandler.postDelayed(new Runnable() {
@@ -222,16 +229,24 @@ public abstract class AbstractCalleesActivity extends ListActivity implements Li
if (viewsToUpdateCallQuality == null) {
return;
}
-
+
for (View v : viewsToUpdateCallQuality) {
LinphoneCall call = (LinphoneCall) v.getTag();
float newQuality = call.getCurrentQuality();
- updateQualityOfSignalIcon(v, newQuality);
+ updateQualityOfSignalIcon(v, newQuality);
+
+ // We also use this handler to display the ones who speaks
+ ImageView speaking = (ImageView) v.findViewById(R.id.callee_status_speeking);
+ if (shouldDisplayWhoIsTalking && call.getPlayVolume() >= -20) {
+ speaking.setVisibility(View.VISIBLE);
+ } else if (speaking.getVisibility() != View.GONE) {
+ speaking.setVisibility(View.GONE);
+ }
}
- callqualityHandler.postDelayed(this, 1000);
+ callqualityHandler.postDelayed(this, timeToRefresh);
}
- },1000);
+ },timeToRefresh);
}
protected final void registerCallQualityListener(final View v, final LinphoneCall call) {
@@ -241,6 +256,10 @@ public abstract class AbstractCalleesActivity extends ListActivity implements Li
v.setTag(call);
viewsToUpdateCallQuality.add(v);
}
+
+ protected final void registerCallSpeakerListener() {
+ shouldDisplayWhoIsTalking = true;
+ }
}
@Override
@@ -282,7 +301,10 @@ public abstract class AbstractCalleesActivity extends ListActivity implements Li
void updateQualityOfSignalIcon(View v, float quality)
{
- ImageView qos = (ImageView) v.findViewById(R.id.QoS);
+ ImageView qos = (ImageView) v.findViewById(R.id.callee_status_qos);
+ if (!(qos.getVisibility() == View.VISIBLE)) {
+ qos.setVisibility(View.VISIBLE);
+ }
if (quality >= 4) // Good Quality
{
qos.setImageDrawable(getResources().getDrawable(R.drawable.stat_sys_signal_4));
diff --git a/src/org/linphone/ConferenceDetailsActivity.java b/src/org/linphone/ConferenceDetailsActivity.java
index 08bcea633..a0bb02d8b 100644
--- a/src/org/linphone/ConferenceDetailsActivity.java
+++ b/src/org/linphone/ConferenceDetailsActivity.java
@@ -95,6 +95,8 @@ public class ConferenceDetailsActivity extends AbstractCalleesActivity {
dialog.show();
}
});
+
+ setVisibility(v, R.id.callee_status_qos, true);
// May be greatly sped up using a drawable cache
ImageView pictureView = (ImageView) v.findViewById(R.id.picture);
@@ -102,6 +104,7 @@ public class ConferenceDetailsActivity extends AbstractCalleesActivity {
registerCallDurationTimer(v, call);
registerCallQualityListener(v, call);
+ registerCallSpeakerListener();
return v;
}
diff --git a/src/org/linphone/IncallActivity.java b/src/org/linphone/IncallActivity.java
index 91cda16cd..0f7738f8b 100644
--- a/src/org/linphone/IncallActivity.java
+++ b/src/org/linphone/IncallActivity.java
@@ -456,7 +456,7 @@ public class IncallActivity extends AbstractCalleesActivity implements
boolean statusPaused = state== State.Paused || state == State.PausedByRemote;
setVisibility(v, R.id.callee_status_paused, statusPaused);
- setVisibility(v, R.id.QoS, !statusPaused);
+ setVisibility(v, R.id.callee_status_qos, !statusPaused);
final OnLongClickListener showCallActionsLongListener = new OnLongClickListener() {
public boolean onLongClick(View v) {
diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java
index c1a479ab2..b3103987f 100644
--- a/src/org/linphone/LinphoneService.java
+++ b/src/org/linphone/LinphoneService.java
@@ -38,6 +38,7 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -48,6 +49,8 @@ import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
+import android.net.wifi.WifiManager.WifiLock;
+import android.net.wifi.WifiManager;
/**
*
@@ -73,7 +76,8 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
// private boolean mTestDelayElapsed; // add a timer for testing
private boolean mTestDelayElapsed = true; // no timer
-
+ private WifiManager mWifiManager ;
+ private WifiLock mWifiLock ;
public static boolean isReady() {
return instance!=null && instance.mTestDelayElapsed;
}
@@ -136,8 +140,11 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
LinphoneManager.createAndStart(this, this);
LinphoneManager.getLc().setPresenceInfo(0, null, OnlineStatus.Online);
+ mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+ mWifiLock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, this.getPackageName()+"-wifi-call-lock");
+ mWifiLock.setReferenceCounted(false);
instance = this; // instance is ready once linphone manager has been created
-
+
// Retrieve methods to publish notification and keep Android
// from killing us and keep the audio quality high.
@@ -365,7 +372,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
// Make sure our notification is gone.
stopForegroundCompat(NOTIF_ID);
mNM.cancel(INCALL_NOTIF_ID);
-
+ mWifiLock.release();
super.onDestroy();
}
@@ -444,10 +451,13 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
if (state == State.StreamsRunning) {
// Workaround bug current call seems to be updated after state changed to streams running
refreshIncallIcon(call);
+ mWifiLock.acquire();
} else {
refreshIncallIcon(LinphoneManager.getLc().getCurrentCall());
}
-
+ if ((state == State.CallEnd || state == State.Error) && LinphoneManager.getLc().getCallsNb() < 1) {
+ mWifiLock.release();
+ }
mHandler.post(new Runnable() {
public void run() {
if (guiListener() != null)
diff --git a/src/org/linphone/core/LinphoneCallImpl.java b/src/org/linphone/core/LinphoneCallImpl.java
index 802801155..b2b71dcb5 100644
--- a/src/org/linphone/core/LinphoneCallImpl.java
+++ b/src/org/linphone/core/LinphoneCallImpl.java
@@ -147,4 +147,9 @@ class LinphoneCallImpl implements LinphoneCall {
public String toString() {
return "Call " + nativePtr;
}
+
+ private native float getPlayVolume(long nativePtr);
+ public float getPlayVolume() {
+ return getPlayVolume(nativePtr);
+ }
}
diff --git a/submodules/linphone b/submodules/linphone
index 5bf95231b..29e89fc9d 160000
--- a/submodules/linphone
+++ b/submodules/linphone
@@ -1 +1 @@
-Subproject commit 5bf95231b51641ce095af49a864cf00fa6837750
+Subproject commit 29e89fc9de102f88b8ebf36a5fe7449a26a8bbff