Skip to content
Snippets Groups Projects
Commit b179bab0 authored by Adrien Béraud's avatar Adrien Béraud Committed by Guillaume Roguez
Browse files

android: first publishable implementation of Ring on Android

Change-Id: I6d65993a0bbed0ac680d6fe5980aae0fb931116e
parent 75540ff6
No related branches found
No related tags found
No related merge requests found
Showing
with 1165 additions and 656 deletions
......@@ -122,7 +122,7 @@ case "$REL" in
if [ "${HAVE_64}" = 1 ];then
ANDROID_API=android-21
else
ANDROID_API=android-15
ANDROID_API=android-16
fi
CXXSTL="/"${GCCVER}
;;
......@@ -131,7 +131,7 @@ case "$REL" in
echo "You need the NDKv10 or later for 64 bits build"
exit 1
fi
ANDROID_API=android-15
ANDROID_API=android-16
CXXSTL="/"${GCCVER}
;;
7|8|*)
......@@ -174,7 +174,7 @@ ANDROID_PATH="`pwd`"
if [ "$FETCH" = 1 ]
then
# 1/ dring
TESTED_HASH=0012eab6f3bbc2df4461b85df788b86be1299f11
TESTED_HASH=6f868d66377a2305120986ce79cc03411080d196
if [ ! -d "ring-daemon" ]; then
echo "ring daemon source not found, cloning"
git clone https://gerrit-ring.savoirfairelinux.com/ring-daemon.git
......@@ -326,8 +326,8 @@ else
RELEASE=0
fi
echo "EXTRA_CFLAGS= -g ${EXTRA_CFLAGS}" >> config.mak
echo "EXTRA_CXXFLAGS= -g ${EXTRA_CXXFLAGS}" >> config.mak
echo "EXTRA_CFLAGS= -g -fpic ${EXTRA_CFLAGS}" >> config.mak
echo "EXTRA_CXXFLAGS= -g -fpic ${EXTRA_CXXFLAGS}" >> config.mak
echo "EXTRA_LDFLAGS= ${EXTRA_LDFLAGS}" >> config.mak
export RING_EXTRA_CFLAGS="${EXTRA_CFLAGS}"
export RING_EXTRA_CXXFLAGS="${EXTRA_CXXFLAGS}"
......@@ -413,7 +413,7 @@ cd ../..
echo "Building Ring for Android ${PWD}"
make $CLEAN
make -j1 TARGET_TUPLE=$TARGET_TUPLE PLATFORM_SHORT_ARCH=$PLATFORM_SHORT_ARCH CXXSTL=$CXXSTL RELEASE=$RELEASE $TARGET
ANDROID_ABI="${ANDROID_ABI}" make -j1 TARGET_TUPLE=$TARGET_TUPLE PLATFORM_SHORT_ARCH=$PLATFORM_SHORT_ARCH CXXSTL=$CXXSTL RELEASE=$RELEASE $TARGET
#
# Exporting a environment script with all the necessary variables
......
......@@ -18,7 +18,7 @@ fi
RING_SOURCEDIR=`cd ..; pwd`
CFLAGS="-g -O2 -fstrict-aliasing -funsafe-math-optimizations"
CFLAGS="-fpic -g -O2 -fstrict-aliasing -funsafe-math-optimizations"
if [ -n "$HAVE_ARM" -a ! -n "$HAVE_64" ]; then
CFLAGS="${CFLAGS} -mlong-calls"
fi
......
......@@ -3,7 +3,31 @@
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="Android API 22 Platform" project-jdk-type="Android SDK">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
......@@ -12,10 +12,12 @@
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
<afterSyncTasks>
<task>generateDebugAndroidTestSources</task>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
......@@ -24,7 +26,7 @@
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
<exclude-output />
......@@ -34,13 +36,13 @@
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build-types/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build-types/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build-types/debug/assets" type="java-resource" />
......@@ -67,11 +69,12 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/22.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v13/22.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v13/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.astuetz/pagerslidingtabstrip/1.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/se.emilsjolander/stickylistheaders/2.7.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
......@@ -87,16 +90,18 @@
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="ormlite-android-4.48" level="project" />
<orderEntry type="library" exported="" name="libphonenumber-7.0.11" level="project" />
<orderEntry type="library" exported="" name="pagerslidingtabstrip-1.0.1" level="project" />
<orderEntry type="library" exported="" name="ormlite-core-4.48" level="project" />
<orderEntry type="library" exported="" name="robotium-solo-5.0.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" />
<orderEntry type="library" exported="" name="support-v13-22.2.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" />
<orderEntry type="library" exported="" name="design-22.2.0" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-22.2.0" level="project" />
<orderEntry type="library" exported="" name="support-v13-23.0.1" level="project" />
<orderEntry type="library" exported="" name="stickylistheaders-2.7.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
<orderEntry type="library" exported="" name="robotium-solo-5.4.1" level="project" />
<orderEntry type="library" exported="" name="design-23.0.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
</component>
</module>
\ No newline at end of file
apply plugin: 'com.android.application'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile fileTree(include: '*.jar', dir: 'libs')
compile 'com.j256.ormlite:ormlite-core:4.48'
compile 'com.j256.ormlite:ormlite-android:4.48'
compile "com.android.support:support-v13:22.2.0"
compile 'com.android.support:design:22.2.0'
compile 'com.android.support:support-v13:23.0.+'
compile 'com.android.support:design:23.0.+'
compile 'com.jayway.android.robotium:robotium-solo:5.4.1'
compile 'com.astuetz:pagerslidingtabstrip:1.0.1'
compile 'com.googlecode.libphonenumber:libphonenumber:7.0.11'
compile 'se.emilsjolander:stickylistheaders:2.7.+'
}
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
compileSdkVersion 23
buildToolsVersion "23.0.1"
sourceSets {
main {
......@@ -33,4 +35,8 @@ android {
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
Adrien Beraud <adrien.beraud@gmail.com>
......@@ -36,6 +36,10 @@ as that of the covered work.
android:versionCode="14"
android:versionName="2.0.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="23" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
......@@ -43,10 +47,6 @@ as that of the covered work.
android:smallScreens="true"
android:xlargeScreens="true" />
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
......@@ -67,6 +67,8 @@ as that of the covered work.
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.USE_SIP" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-feature
android:name="android.hardware.wifi"
......@@ -89,7 +91,7 @@ as that of the covered work.
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name="cx.ring.client.HomeActivity"
android:name=".client.HomeActivity"
android:label="@string/title_activity_sflphone_home"
android:screenOrientation="portrait"
android:theme="@style/AppThemeWithOverlay"
......@@ -101,40 +103,74 @@ as that of the covered work.
</intent-filter>
</activity>
<activity
android:name="cx.ring.client.AccountWizard"
android:name=".client.AccountWizard"
android:screenOrientation="portrait"
android:theme="@style/AppThemeWithoutOverlay" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="cx.ring.client.AccountPreferenceActivity" />
android:value="cx.ring.client.AccountEditionActivity" />
</activity>
<activity
android:name="cx.ring.client.AccountEditionActivity"
android:name=".client.AccountEditionActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppThemeWithoutOverlay" />
<activity
android:name="cx.ring.client.DetailHistoryActivity"
android:name=".client.DetailHistoryActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppThemeWithoutOverlay" />
<activity android:name=".client.NewConversationActivity" android:theme="@style/AppThemeWithoutOverlay" android:label="@string/app_name" >
</activity>
<activity
android:name="cx.ring.client.CallActivity"
android:name=".client.CallActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppThemeWithoutOverlay"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<action android:name="android.intent.action.CALL" />
<action android:name="android.intent.action.DIAL" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
<data android:scheme="ring" />
<data android:scheme="sip" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.CALL" />
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/phone" />
<data android:mimeType="vnd.android.cursor.item/phone_v2" />
<data android:mimeType="vnd.android.cursor.item/person" />
</intent-filter>
</activity>
<activity
android:name=".client.ConversationActivity"
android:label="@string/app_name"
android:parentActivityName=".client.HomeActivity"
android:screenOrientation="portrait"
android:theme="@style/AppThemeWithoutOverlay"
android:windowSoftInputMode="adjustResize" >
</activity>
<service
android:name="cx.ring.service.SipService"
android:name=".service.LocalService"
android:exported="false" >
<intent-filter>
<action android:name=".service.LocalService" />
</intent-filter>
</service>
<service
android:name=".service.SipService"
android:exported="false" >
<intent-filter>
<action android:name=".service.SipService" />
......
......@@ -32,12 +32,11 @@
package cx.ring.adapters;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import cx.ring.R;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
......@@ -51,12 +50,12 @@ public class AccountSelectionAdapter extends BaseAdapter {
private static final String TAG = AccountSelectionAdapter.class.getSimpleName();
ArrayList<Account> accounts;
List<Account> accounts;
Context mContext;
int selectedAccount = -1;
static final String DEFAULT_ACCOUNT_ID = "IP2IP";
public AccountSelectionAdapter(Context cont, ArrayList<Account> newList) {
public AccountSelectionAdapter(Context cont, List<Account> newList) {
super();
accounts = newList;
mContext = cont;
......@@ -133,7 +132,11 @@ public class AccountSelectionAdapter extends BaseAdapter {
private void updateAccountView(AccountView entryView, Account acc) {
entryView.alias.setText(acc.getAlias());
entryView.host.setText(acc.getHost()/*+ " - " + acc.getRegistered_state()*/);
if (acc.isRing()) {
entryView.host.setText(acc.getBasicDetails().getUsername());
} else {
entryView.host.setText(acc.getBasicDetails().getUsername() + "@" + acc.getBasicDetails().getHostname());
}
entryView.error.setVisibility(acc.isRegistered() ? View.GONE : View.VISIBLE);
}
......@@ -171,7 +174,13 @@ public class AccountSelectionAdapter extends BaseAdapter {
}
public void addAll(ArrayList<Account> results) {
public void addAll(List<Account> results) {
accounts.addAll(results);
notifyDataSetChanged();
}
public void replaceAll(List<Account> results) {
accounts.clear();
accounts.addAll(results);
notifyDataSetChanged();
}
......@@ -184,7 +193,7 @@ public class AccountSelectionAdapter extends BaseAdapter {
for (Account a : accounts) {
if (a.getAccountID().contentEquals(accoundID)) {
a.setRegistered_state(state, code);
a.setRegistrationState(state, code);
Log.i(TAG, "updateAccount " + accoundID + " " + code);
notifyDataSetChanged();
return;
......
......@@ -32,6 +32,8 @@
package cx.ring.adapters;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import cx.ring.R;
import cx.ring.model.CallContact;
......@@ -51,20 +53,55 @@ import android.graphics.RectF;
import android.graphics.Shader;
import android.net.Uri;
import android.provider.ContactsContract;
import android.util.Log;
import android.util.LruCache;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
public class ContactPictureTask implements Runnable {
private ImageView view;
private CallContact contact;
static final String TAG = ContactPictureTask.class.getSimpleName();
private final WeakReference<ImageView> view;
private final CallContact contact;
private ContentResolver cr;
private static int PADDING = 5;
private final Resources res;
//private PictureLoadedCallback cb;
private final ArrayList<PictureLoadedCallback> callbacks = new ArrayList<>(1);
//int w = photo_bmp.getWidth(), h = photo_bmp.getHeight();
private final int vw, vh;
public void addCallback(PictureLoadedCallback cb) {
//this.cb = callback;
synchronized (callbacks) {
view.clear();
callbacks.add(cb);
}
}
// private final String TAG = ContactPictureTask.class.getSimpleName();
public interface PictureLoadedCallback {
void onPictureLoaded(Bitmap bmp);
};
public ContactPictureTask(Context context, ImageView element, CallContact item) {
contact = item;
cr = context.getContentResolver();
view = element;
res = context.getResources();
view = new WeakReference<>(element);
vw = element.getWidth();
vh = element.getHeight();
}
public ContactPictureTask(Context context, ImageView element, CallContact item, PictureLoadedCallback cb) {
contact = item;
cr = context.getContentResolver();
res = context.getResources();
vw = element.getWidth();
vh = element.getHeight();
view = new WeakReference<>(element);
addCallback(cb);
}
public static Bitmap loadContactPhoto(ContentResolver cr, long id) {
......@@ -80,17 +117,27 @@ public class ContactPictureTask implements Runnable {
@Override
public void run() {
Log.i(TAG, "ContactPictureTask run " + contact.getId());
Bitmap photo_bmp;
try {
photo_bmp = loadContactPhoto(cr, contact.getId());
} catch (IllegalArgumentException e) {
photo_bmp = null;
}
cr = null;
int dpiPadding = (int) (PADDING * view.getResources().getDisplayMetrics().density);
/*final ImageView v = view.get();
view.clear();
if (v == null) {
Log.i(TAG, "ContactPictureTask cancelling: view is now null");
return;
}*/
//int dpiPadding = (int) (PADDING * view.getResources().getDisplayMetrics().density);
if (photo_bmp == null) {
photo_bmp = decodeSampledBitmapFromResource(view.getResources(), R.drawable.ic_contact_picture, view.getWidth(), view.getHeight());
photo_bmp = decodeSampledBitmapFromResource(res, R.drawable.ic_contact_picture, vw, vh);
}
int w = photo_bmp.getWidth(), h = photo_bmp.getHeight();
......@@ -119,15 +166,42 @@ public class ContactPictureTask implements Runnable {
// internalCanvas.drawOval(new RectF(PADDING, PADDING, externalBMP.getWidth() - dpiPadding, externalBMP.getHeight() - dpiPadding), paint);
internalCanvas.drawOval(new RectF(0, 0, externalBMP.getWidth(), externalBMP.getHeight()), paint);
view.post(new Runnable() {
photo_bmp.recycle();
contact.setPhoto(externalBMP);
//v.invalidate();
synchronized (callbacks) {
final ImageView v = view.get();
view.clear();
if (v == null) {
for (PictureLoadedCallback cb : callbacks) {
cb.onPictureLoaded(externalBMP);
}
} else {
v.post(new Runnable() {
@Override
public void run() {
view.setImageBitmap(externalBMP);
contact.setPhoto(externalBMP);
view.invalidate();
v.setImageBitmap(externalBMP);
}
});
}
callbacks.clear();
}
/*v.post(new Runnable() {
@Override
public void run() {
Log.w(TAG, "ContactPictureTask END " + contact.getId());
//v.setImageBitmap(externalBMP);
contact.setPhoto(externalBMP);
//v.invalidate();
for (PictureLoadedCallback cb : callbacks) {
cb.onPictureLoaded(externalBMP);
}
callbacks.clear();
}
});*/
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
......
......@@ -33,28 +33,30 @@ package cx.ring.adapters;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import cx.ring.R;
import cx.ring.fragments.ContactListFragment;
import cx.ring.model.CallContact;
import cx.ring.views.stickylistheaders.StickyListHeadersAdapter;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SectionIndexer;
import android.widget.TextView;
import android.widget.Toast;
public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer {
private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
Context mContext;
......@@ -64,30 +66,41 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
WeakReference<ContactListFragment> parent;
private LayoutInflater mInflater;
// private static final String TAG = ContactsAdapter.class.getSimpleName();
final private LruCache<Long, Bitmap> mMemoryCache;
final private HashMap<Long, WeakReference<ContactPictureTask>> running_tasks = new HashMap<>();
private static final String TAG = ContactsAdapter.class.getSimpleName();
public ContactsAdapter(ContactListFragment contactListFragment) {
super();
mContext = contactListFragment.getActivity();
mInflater = LayoutInflater.from(mContext);
parent = new WeakReference<ContactListFragment>(contactListFragment);
mContacts = new ArrayList<CallContact>();
parent = new WeakReference<>(contactListFragment);
mContacts = new ArrayList<>();
mSectionIndices = getSectionIndices();
mSectionLetters = getSectionLetters();
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<Long, Bitmap>(cacheSize){
@Override
protected int sizeOf(Long key, Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
}
public static final int TYPE_HEADER = 0;
public static final int TYPE_CONTACT = 1;
private int[] getSectionIndices() {
ArrayList<Integer> sectionIndices = new ArrayList<Integer>();
ArrayList<Integer> sectionIndices = new ArrayList<>();
if (mContacts.isEmpty())
return new int[0];
char lastFirstChar = mContacts.get(0).getmDisplayName().charAt(0);
char lastFirstChar = mContacts.get(0).getDisplayName().charAt(0);
sectionIndices.add(0);
for (int i = 1; i < mContacts.size(); i++) {
if (mContacts.get(i).getmDisplayName().charAt(0) != lastFirstChar) {
lastFirstChar = mContacts.get(i).getmDisplayName().charAt(0);
if (mContacts.get(i).getDisplayName().charAt(0) != lastFirstChar) {
lastFirstChar = mContacts.get(i).getDisplayName().charAt(0);
sectionIndices.add(i);
}
}
......@@ -101,26 +114,27 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
private Character[] getSectionLetters() {
Character[] letters = new Character[mSectionIndices.length];
for (int i = 0; i < mSectionIndices.length; i++) {
letters[i] = mContacts.get(mSectionIndices[i]).getmDisplayName().charAt(0);
letters[i] = mContacts.get(mSectionIndices[i]).getDisplayName().charAt(0);
}
return letters;
}
@Override
public View getView(int position, View convertView, ViewGroup root) {
public View getView(final int position, View convertView, ViewGroup root) {
ContactView entryView;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_contact, null);
entryView = new ContactView();
entryView.quick_starred = (ImageButton) convertView.findViewById(R.id.quick_starred);
/*entryView.quick_starred = (ImageButton) convertView.findViewById(R.id.quick_starred);
entryView.quick_edit = (ImageButton) convertView.findViewById(R.id.quick_edit);
entryView.quick_discard = (ImageButton) convertView.findViewById(R.id.quick_discard);
entryView.quick_call = (ImageButton) convertView.findViewById(R.id.quick_call);
entryView.quick_msg = (ImageButton) convertView.findViewById(R.id.quick_message);
entryView.quick_msg = (ImageButton) convertView.findViewById(R.id.quick_message);*/
entryView.photo = (ImageView) convertView.findViewById(R.id.photo);
entryView.display_name = (TextView) convertView.findViewById(R.id.display_name);
entryView.position = -1;
convertView.setTag(entryView);
} else {
entryView = (ContactView) convertView.getTag();
......@@ -128,14 +142,56 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
final CallContact item = mContacts.get(position);
entryView.display_name.setText(item.getmDisplayName());
if (entryView.position == position || (entryView.contact != null && entryView.contact.get() != null && item.getId() == entryView.contact.get().getId()))
return convertView;
entryView.display_name.setText(item.getDisplayName());
entryView.contact = new WeakReference<>(item);
entryView.position = position;
final Long cid = item.getId();
final Long pid = item.getPhotoId();
Bitmap bmp = item.getPhoto();
if (bmp == null) {
bmp = mMemoryCache.get(pid);
if (bmp != null) item.setPhoto(bmp);
}
if (item.hasPhoto()) {
entryView.photo.setImageBitmap(item.getPhoto());
if (bmp != null) {
entryView.photo.setImageBitmap(bmp);
} else {
infos_fetcher.execute(new ContactPictureTask(mContext, entryView.photo, item));
entryView.photo.setImageBitmap(null);
final WeakReference<ContactView> wh = new WeakReference<>(entryView);
infos_fetcher.execute(new ContactPictureTask(mContext, entryView.photo, item, new ContactPictureTask.PictureLoadedCallback() {
@Override
public void onPictureLoaded(final Bitmap bmp) {
mMemoryCache.put(pid, bmp);
final ContactView fh = wh.get();
if (fh == null || fh.photo.getParent() == null)
return;
if (fh.position == position)
fh.photo.post(new Runnable() {
@Override
public void run() {
final CallContact c = fh.contact.get();
if (c.getId() == cid) {
c.setPhoto(bmp);
fh.photo.setImageBitmap(bmp);
fh.photo.startAnimation(AnimationUtils.loadAnimation(fh.photo.getContext(), R.anim.contact_fadein));
}
}
});
}
}));
}
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
parent.get().mCallbacks.onTextContact(item);
}
});
/*
entryView.quick_call.setOnClickListener(new OnClickListener() {
@Override
......@@ -182,7 +238,7 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
entryView.quick_edit.setClickable(false);
entryView.quick_discard.setClickable(false);
entryView.quick_starred.setClickable(false);
*/
return convertView;
}
......@@ -190,9 +246,11 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
* ViewHolder Pattern
*********************/
public class ContactView {
ImageButton quick_starred, quick_edit, quick_discard, quick_call, quick_msg;
ImageButton /*quick_starred, quick_edit, quick_discard, */quick_call, quick_msg;
ImageView photo;
TextView display_name;
WeakReference<CallContact> contact = new WeakReference<>(null);
int position;
}
@Override
......@@ -224,7 +282,7 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
}
// set header text as first char in name
char headerChar = mContacts.get(position).getmDisplayName().subSequence(0, 1).charAt(0);
char headerChar = mContacts.get(position).getDisplayName().subSequence(0, 1).charAt(0);
holder.text.setText("" + headerChar);
......@@ -240,7 +298,7 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
public long getHeaderId(int position) {
// return the first character of the name as ID because this is what
// headers are based upon
return mContacts.get(position).getmDisplayName().subSequence(0, 1).charAt(0);
return mContacts.get(position).getDisplayName().subSequence(0, 1).charAt(0);
}
@Override
......@@ -274,14 +332,14 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
}
public void clear() {
mContacts = new ArrayList<CallContact>();
mContacts = new ArrayList<>();
mSectionIndices = new int[0];
mSectionLetters = new Character[0];
notifyDataSetChanged();
}
/*
public void restore() {
mContacts = new ArrayList<CallContact>();
mContacts = new ArrayList<>();
mSectionIndices = getSectionIndices();
mSectionLetters = getSectionLetters();
notifyDataSetChanged();
......@@ -292,6 +350,13 @@ public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAda
mSectionIndices = getSectionIndices();
mSectionLetters = getSectionLetters();
notifyDataSetChanged();
}*/
public void setData(ArrayList<CallContact> contacts) {
mContacts = contacts;
mSectionIndices = getSectionIndices();
mSectionLetters = getSectionLetters();
notifyDataSetChanged();
}
}
/*
* Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
*
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
package cx.ring.adapters;
import java.util.ArrayList;
import java.util.List;
import cx.ring.R;
import cx.ring.model.SipMessage;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class DiscussArrayAdapter extends BaseAdapter {
private TextView countryName;
private List<SipMessage> messages = new ArrayList<SipMessage>();
private LinearLayout wrapper;
private Context mContext;
public DiscussArrayAdapter(Context context, Bundle args) {
mContext = context;
if(args == null)
messages = new ArrayList<SipMessage>();
else
messages = args.getParcelableArrayList("messages");
}
public void add(SipMessage object) {
messages.add(object);
notifyDataSetChanged();
}
public int getCount() {
return this.messages.size();
}
public SipMessage getItem(int index) {
return this.messages.get(index);
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
row = inflater.inflate(R.layout.item_message, parent, false);
}
wrapper = (LinearLayout) row.findViewById(R.id.wrapper);
SipMessage coment = getItem(position);
countryName = (TextView) row.findViewById(R.id.comment);
countryName.setText(coment.comment);
countryName.setBackgroundResource(coment.left ? R.drawable.bubble_left_selector : R.drawable.bubble_right_selector);
wrapper.setGravity(coment.left ? Gravity.LEFT : Gravity.RIGHT);
return row;
}
@Override
public long getItemId(int position) {
return 0;
}
}
\ No newline at end of file
......@@ -50,12 +50,11 @@ public class SectionsPagerAdapter extends FragmentStatePagerAdapter implements P
private static final String TAG = SectionsPagerAdapter.class.getSimpleName();
Context mContext;
ArrayList<Fragment> fragments;
private final ArrayList<Fragment> fragments = new ArrayList<>();
public SectionsPagerAdapter(Context c, FragmentManager fm) {
super(fm);
mContext = c;
fragments = new ArrayList<Fragment>();
fragments.add(new DialingFragment());
fragments.add(new CallListFragment());
fragments.add(new HistoryFragment());
......
......@@ -70,6 +70,11 @@ public class StarredContactsAdapter extends BaseAdapter {
notifyDataSetChanged();
}
public void setData(ArrayList<CallContact> contacts) {
dataset = contacts;
notifyDataSetChanged();
}
@Override
public int getCount() {
return dataset.size();
......@@ -97,7 +102,7 @@ public class StarredContactsAdapter extends BaseAdapter {
CallContact item = dataset.get(pos);
((TextView) v.findViewById(R.id.display_name)).setText(item.getmDisplayName());
((TextView) v.findViewById(R.id.display_name)).setText(item.getDisplayName());
ImageView photo_view = (ImageView) v.findViewById(R.id.photo);
if(item.hasPhoto()){
......
......@@ -37,6 +37,7 @@ import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.*;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
......@@ -49,26 +50,33 @@ import android.view.MenuItem;
import cx.ring.R;
import cx.ring.fragments.AdvancedAccountFragment;
import cx.ring.fragments.AudioManagementFragment;
import cx.ring.fragments.HomeFragment;
import cx.ring.fragments.MenuFragment;
import cx.ring.fragments.NestedSettingsFragment;
import cx.ring.fragments.SecurityAccountFragment;
import cx.ring.model.account.Account;
import cx.ring.service.ISipService;
import cx.ring.service.LocalService;
import cx.ring.service.SipService;
import com.astuetz.PagerSlidingTabStrip;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;
import cx.ring.fragments.GeneralAccountFragment;
public class AccountEditionActivity extends Activity implements GeneralAccountFragment.Callbacks, AudioManagementFragment.Callbacks,
public class AccountEditionActivity extends Activity implements LocalService.Callbacks, GeneralAccountFragment.Callbacks, AudioManagementFragment.Callbacks,
AdvancedAccountFragment.Callbacks, SecurityAccountFragment.Callbacks, NestedSettingsFragment.Callbacks {
private static final String TAG = AccountEditionActivity.class.getSimpleName();
public static final Uri CONTENT_URI = Uri.withAppendedPath(LocalService.AUTHORITY_URI, "accounts");
private boolean mBound = false;
private ISipService service;
private Account acc_selected;
private LocalService service;
private Account acc_selected = null;
private NestedSettingsFragment toDisplay;
......@@ -81,14 +89,25 @@ public class AccountEditionActivity extends Activity implements GeneralAccountFr
};
PreferencesPagerAdapter mPreferencesPagerAdapter;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder binder) {
service = ISipService.Stub.asInterface(binder);
public void onServiceConnected(ComponentName className, IBinder s) {
LocalService.LocalBinder binder = (LocalService.LocalBinder) s;
service = binder.getService();
mBound = true;
ArrayList<Fragment> fragments = new ArrayList<Fragment>();
setContentView(R.layout.activity_account_settings);
getActionBar().setDisplayHomeAsUpEnabled(true);
String account_id = getIntent().getData().getLastPathSegment();
Log.i(TAG, "Service connected " + className.getClassName() + " " + getIntent().getData().toString());
acc_selected = service.getAccount(account_id);
acc_selected.addObserver(mAccountObserver);
getActionBar().setTitle(acc_selected.getAlias());
ArrayList<Fragment> fragments = new ArrayList<>();
if (acc_selected.isIP2IP()) {
fragments.add(new AudioManagementFragment());
} else {
......@@ -110,33 +129,22 @@ public class AccountEditionActivity extends Activity implements GeneralAccountFr
final PagerSlidingTabStrip strip = PagerSlidingTabStrip.class.cast(findViewById(R.id.pager_sliding_strip));
strip.setViewPager(mViewPager);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
acc_selected.deleteObserver(mAccountObserver);
mBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account_settings);
getActionBar().setDisplayHomeAsUpEnabled(true);
acc_selected = getIntent().getExtras().getParcelable("account");
acc_selected.addObserver(mAccountObserver);
if (!mBound) {
Log.i(TAG, "onCreate: Binding service...");
Intent intent = new Intent(this, SipService.class);
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
}
@Override
......@@ -206,8 +214,12 @@ public class AccountEditionActivity extends Activity implements GeneralAccountFr
private void processAccount() {
try {
service.setCredentials(acc_selected.getAccountID(), acc_selected.getCredentialsHashMapList());
service.setAccountDetails(acc_selected.getAccountID(), acc_selected.getDetails());
service.getRemoteService().setCredentials(acc_selected.getAccountID(), acc_selected.getCredentialsHashMapList());
Map<String, String> details = acc_selected.getDetails();
service.getRemoteService().setAccountDetails(acc_selected.getAccountID(), details);
Log.w(TAG, "service.setAccountDetails " + details.get("Account.hostname"));
getActionBar().setTitle(acc_selected.getAlias());;
} catch (RemoteException e) {
e.printStackTrace();
}
......@@ -225,7 +237,7 @@ public class AccountEditionActivity extends Activity implements GeneralAccountFr
bundle.putString("AccountID", acc_selected.getAccountID());
try {
service.removeAccount(acc_selected.getAccountID());
service.getRemoteService().removeAccount(acc_selected.getAccountID());
} catch (RemoteException e) {
e.printStackTrace();
}
......@@ -244,6 +256,16 @@ public class AccountEditionActivity extends Activity implements GeneralAccountFr
return alertDialog;
}
@Override
public ISipService getRemoteService() {
return service.getRemoteService();
}
@Override
public LocalService getService() {
return service;
}
public class PreferencesPagerAdapter extends FragmentStatePagerAdapter {
Context mContext;
......@@ -289,11 +311,6 @@ public class AccountEditionActivity extends Activity implements GeneralAccountFr
}
}
@Override
public ISipService getService() {
return service;
}
@Override
public Account getAccount() {
return acc_selected;
......
......@@ -33,28 +33,25 @@
package cx.ring.client;
import java.util.*;
import android.app.Activity;
import android.util.Log;
import cx.ring.R;
import cx.ring.fragments.CallFragment;
import cx.ring.fragments.IMFragment;
import cx.ring.model.Conversation;
import cx.ring.model.TextMessage;
import cx.ring.model.account.Account;
import cx.ring.model.CallContact;
import cx.ring.model.Conference;
import cx.ring.model.SipCall;
import cx.ring.model.SipMessage;
import cx.ring.model.account.AccountDetailBasic;
import cx.ring.service.ISipService;
import cx.ring.service.SipService;
import cx.ring.service.LocalService;
import cx.ring.utils.CallProximityManager;
import cx.ring.views.CallPaneLayout;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Bundle;
......@@ -62,88 +59,37 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.support.v4.widget.SlidingPaneLayout;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class CallActivity extends Activity implements IMFragment.Callbacks, CallFragment.Callbacks, CallProximityManager.ProximityDirector {
public class CallActivity extends Activity implements LocalService.Callbacks, CallFragment.Callbacks, CallProximityManager.ProximityDirector {
@SuppressWarnings("unused")
static final String TAG = "CallActivity";
private ISipService mService;
CallPaneLayout mSlidingPaneLayout;
private boolean init = false;
private LocalService service;
IMFragment mIMFragment;
CallFragment mCurrentCallFragment;
private Conference mDisplayedConference;
/* result code sent in case of call failure */
public static int RESULT_FAILURE = -10;
private CallProximityManager mProximityManager;
private CallProximityManager mProximityManager = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "CallActivity onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call_layout);
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
setUpSlidingPanel();
mProximityManager = new CallProximityManager(this, this);
mProximityManager.startTracking();
mCurrentCallFragment = new CallFragment();
mIMFragment = new IMFragment();
if(!checkExternalCall()) {
mDisplayedConference = getIntent().getParcelableExtra("conference");
Bundle IMBundle = new Bundle();
if (getIntent().getBooleanExtra("resuming", false)) {
IMBundle.putParcelableArrayList("messages", mDisplayedConference.getMessages());
mIMFragment.setArguments(IMBundle);
} else {
IMBundle.putParcelableArrayList("messages", new ArrayList<SipMessage>());
mIMFragment.setArguments(IMBundle);
}
}
mSlidingPaneLayout.setCurFragment(mCurrentCallFragment);
getFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment)
.replace(R.id.message_list_frame, mIMFragment).commit();
}
private void setUpSlidingPanel() {
mSlidingPaneLayout = (CallPaneLayout) findViewById(R.id.slidingpanelayout);
mSlidingPaneLayout.setParallaxDistance(500);
mSlidingPaneLayout.setSliderFadeColor(Color.TRANSPARENT);
mSlidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View view, float offSet) {
}
@Override
public void onPanelOpened(View view) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
}
@Override
public void onPanelClosed(View view) {
mCurrentCallFragment.getBubbleView().restartDrawing();
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
}
});
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
public void onFragmentCreated() {
Intent intent = new Intent(this, SipService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
......@@ -182,11 +128,12 @@ public class CallActivity extends Activity implements IMFragment.Callbacks, Call
@Override
protected void onDestroy() {
Log.i(TAG, "CallActivity onDestroy");
unbindService(mConnection);
if (mProximityManager != null) {
mProximityManager.stopTracking();
mProximityManager.release(0);
}
super.onDestroy();
}
......@@ -198,15 +145,34 @@ public class CallActivity extends Activity implements IMFragment.Callbacks, Call
@SuppressWarnings("unchecked")
@Override
public void onServiceConnected(ComponentName className, IBinder binder) {
mService = ISipService.Stub.asInterface(binder);
service = ((LocalService.LocalBinder)binder).getService();
if (!init) {
mProximityManager = new CallProximityManager(CallActivity.this, CallActivity.this);
mProximityManager.startTracking();
if(!checkExternalCall()) {
mDisplayedConference = getIntent().getParcelableExtra("conference");
}
Log.i(TAG, "CallActivity onCreate in:" + mDisplayedConference.isIncoming() + " out:" + mDisplayedConference.isOnGoing() + " contact" + mDisplayedConference.getParticipants().get(0).getContact().getDisplayName());
init = true;
}
if (mDisplayedConference.getState().contentEquals("NONE")) {
SipCall call = mDisplayedConference.getParticipants().get(0);
try {
mService.placeCall(mDisplayedConference.getParticipants().get(0));
String callId = service.getRemoteService().placeCall(call);
if (callId == null || callId.isEmpty()) {
CallActivity.this.terminateCall();
}
mDisplayedConference = service.getRemoteService().getConference(callId);
} catch (RemoteException e) {
e.printStackTrace();
}
}
setContentView(R.layout.activity_call_layout);
mCurrentCallFragment = (CallFragment) getFragmentManager().findFragmentById(R.id.ongoingcall_pane);
}
@Override
......@@ -217,25 +183,30 @@ public class CallActivity extends Activity implements IMFragment.Callbacks, Call
private boolean checkExternalCall() {
Uri u = getIntent().getData();
if (u != null) {
CallContact c = CallContact.ContactBuilder.buildUnknownContact(u.getSchemeSpecificPart());
String number = u.getSchemeSpecificPart();
Log.w(TAG, "number " + number);
number = CallContact.canonicalNumber(number);
Log.w(TAG, "canonicalNumber " + number);
CallContact c = service.findContactByNumber(number);
Conversation conv = service.getByContact(c);
if (conv == null)
conv = new Conversation(c);
Account acc = service.getAccounts().get(0);
String id = conv.getLastAccountUsed();
if (id != null && !id.isEmpty()) {
Account alt_acc = service.getAccount(id);
Log.w(TAG, "Found suitable account for calling " + u.getSchemeSpecificPart() + " " + id + " " + alt_acc.getBasicDetails().getDetailString(AccountDetailBasic.CONFIG_ACCOUNT_TYPE));
if (alt_acc.isEnabled())
acc = alt_acc;
} else {
acc = service.guessAccount(c, number);
}
try {
String accountID = (String) mService.getAccountList().get(1); // We use the first account to place outgoing calls
Map<String, String> details = (Map<String, String>) mService.getAccountDetails(accountID);
ArrayList<Map<String, String>> credentials = (ArrayList<Map<String, String>>) mService.getCredentials(accountID);
Map<String, String> state = (Map<String, String>) mService.getVolatileAccountDetails(accountID);
Account acc = new Account(accountID, details, credentials, state);
Bundle args = new Bundle();
args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
args.putParcelable(SipCall.ACCOUNT, acc);
args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_NONE);
args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
args.putParcelable(SipCall.CONTACT, c);
SipCall call = new SipCall(null, acc.getAccountID(), number, SipCall.Direction.OUTGOING);
call.setCallState(SipCall.State.NONE);
call.setContact(c);
mDisplayedConference = new Conference(Conference.DEFAULT_ID);
mDisplayedConference.getParticipants().add(new SipCall(args));
} catch (RemoteException e) {
e.printStackTrace();
mDisplayedConference.getParticipants().add(call);
} catch (Exception e) {
e.printStackTrace();
}
......@@ -245,8 +216,13 @@ public class CallActivity extends Activity implements IMFragment.Callbacks, Call
}
@Override
public ISipService getService() {
return mService;
public ISipService getRemoteService() {
return service.getRemoteService();
}
@Override
public LocalService getService() {
return service;
}
@Override
......@@ -273,48 +249,14 @@ public class CallActivity extends Activity implements IMFragment.Callbacks, Call
@Override
public void terminateCall() {
mHandler.removeCallbacks(mUpdateTimeTask);
mCurrentCallFragment.getBubbleView().stopThread();
TimerTask quit = new TimerTask() {
@Override
public void run() {
finish();
}
};
new Timer().schedule(quit, 1000);
}
@Override
public boolean sendIM(SipMessage msg) {
try {
Log.i(TAG, "Sending:"+msg.comment+"to"+mDisplayedConference.getId());
mService.sendTextMessage(mDisplayedConference.getId(), msg);
} catch (RemoteException e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
public void startTimer() {
mHandler.postDelayed(mUpdateTimeTask, 0);
}
@Override
public void slideChatScreen() {
if (mSlidingPaneLayout.isOpen()) {
mSlidingPaneLayout.closePane();
} else {
mCurrentCallFragment.getBubbleView().stopThread();
mSlidingPaneLayout.openPane();
}
}
@Override
public boolean shouldActivateProximity() {
return true;
......@@ -322,7 +264,5 @@ public class CallActivity extends Activity implements IMFragment.Callbacks, Call
@Override
public void onProximityTrackingChanged(boolean acquired) {
// TODO Stub de la méthode généré automatiquement
}
}
package cx.ring.client;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import cx.ring.R;
import cx.ring.adapters.ContactPictureTask;
import cx.ring.model.CallContact;
import cx.ring.model.Conference;
import cx.ring.model.Conversation;
import cx.ring.model.SipCall;
import cx.ring.model.TextMessage;
import cx.ring.model.account.Account;
import cx.ring.service.LocalService;
public class ConversationActivity extends Activity {
private static final String TAG = ConversationActivity.class.getSimpleName();
public static final Uri CONTENT_URI = Uri.withAppendedPath(LocalService.AUTHORITY_URI, "conversations");
private boolean mBound = false;
private LocalService service = null;
private Conversation conversation = null;
private String preferredNumber = null;
private ListView histList = null;
private View msgSendBtn = null;
private EditText msgEditTxt = null;
private ViewGroup bottomPane = null;
private ConversationAdapter adapter = null;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder binder) {
service = ((LocalService.LocalBinder)binder).getService();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(LocalService.ACTION_CONF_UPDATE);
registerReceiver(receiver, intentFilter);
mBound = true;
String conv_id = getIntent().getData().getLastPathSegment();
preferredNumber = getIntent().getStringExtra("number");
conversation = service.getConversation(conv_id);
if (conversation == null) {
long contact_id = CallContact.contactIdFromId(conv_id);
CallContact contact;
if (contact_id >= 0)
contact = service.findContactById(contact_id);
else if (preferredNumber != null && !preferredNumber.isEmpty()) {
contact = service.findContactByNumber(preferredNumber);
if (contact == null)
contact = CallContact.ContactBuilder.buildUnknownContact(conv_id);
} else {
contact = service.findContactByNumber(conv_id);
if (contact == null)
contact = CallContact.ContactBuilder.buildUnknownContact(conv_id);
preferredNumber = conv_id;
}
conversation = service.startConversation(contact);
}
Log.w(TAG, "ConversationActivity onServiceConnected " + conv_id);
if (conversation == null) {
finish();
return;
}
getActionBar().setTitle(conversation.getContact().getDisplayName());
Conference conf = conversation.getCurrentCall();
bottomPane.setVisibility(conf == null ? View.GONE : View.VISIBLE);
if (conf != null) {
Log.w(TAG, "ConversationActivity onServiceConnected " + conf.getId() + " " + conversation.getCurrentCall());
bottomPane.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(ConversationActivity.this.getApplicationContext(), CallActivity.class).putExtra("conference", conversation.getCurrentCall()));
}
});
}
adapter.updateDataset(conversation.getHistory());
scrolltoBottom();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
Log.w(TAG, "ConversationActivity onServiceDisconnected " + arg0.getClassName());
mBound = false;
}
};
final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.w(TAG, "onReceive " + intent.getAction() + " " + intent.getDataString());
//conversation = service.getConversation(conversation.getId());
conversation = service.getByContact(conversation.getContact());
adapter.updateDataset(conversation.getHistory());
scrolltoBottom();
Conference conf = conversation.getCurrentCall();
bottomPane.setVisibility(conf == null ? View.GONE : View.VISIBLE);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frag_conversation);
msgEditTxt = (EditText) findViewById(R.id.msg_input_txt);
msgSendBtn = findViewById(R.id.msg_send);
msgSendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onSendTextMessage(msgEditTxt.getText().toString());
msgEditTxt.setText("");
}
});
bottomPane = (ViewGroup) findViewById(R.id.ongoingcall_pane);
bottomPane.setVisibility(View.GONE);
//getActionBar().setDisplayHomeAsUpEnabled(true);
conversation = getIntent().getParcelableExtra("conversation");
adapter = new ConversationAdapter(this);
histList = (ListView) findViewById(R.id.hist_list);
histList.setAdapter(adapter);
if (!mBound) {
Log.i(TAG, "onCreate: Binding service...");
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
service = null;
}
}
private void scrolltoBottom() {
histList.post(new Runnable() {
@Override
public void run() {
// Select the last row so it will scroll into view...
histList.setSelection(adapter.getCount() - 1);
}
});
}
private class ConversationAdapter extends BaseAdapter {
final private Context context;
final private ArrayList<Conversation.ConversationElement> texts = new ArrayList<>();
private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
public void updateDataset(ArrayList<Conversation.ConversationElement> list) {
Log.i(TAG, "updateDataset " + list.size());
if (list.size() == 0 && texts.size() == 0)
return;
texts.clear();
texts.addAll(list);
notifyDataSetChanged();
}
ConversationAdapter(Context ctx) {
context = ctx;
}
@Override
public int getCount() {
return texts.size();
}
@Override
public Conversation.ConversationElement getItem(int position) {
return texts.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = LayoutInflater.from(context).inflate(R.layout.item_textmsg, null);
ViewGroup txtEntry = (ViewGroup) convertView.findViewById(R.id.txt_entry);
TextView msgTxt = (TextView) convertView.findViewById(R.id.msg_txt);
TextView msgDetailTxt = (TextView) convertView.findViewById(R.id.msg_details_txt);
ImageView photo = (ImageView) convertView.findViewById(R.id.photo);
ViewGroup txtEntryRight = (ViewGroup) convertView.findViewById(R.id.txt_entry_right);
TextView msgTxtRight = (TextView) convertView.findViewById(R.id.msg_txt_right);
TextView msgDetailTxtRight = (TextView) convertView.findViewById(R.id.msg_details_txt_right);
ViewGroup callEntry = (ViewGroup) convertView.findViewById(R.id.call_entry);
TextView histTxt = (TextView) convertView.findViewById(R.id.call_hist_txt);
TextView histDetailTxt = (TextView) convertView.findViewById(R.id.call_details_txt);
Conversation.ConversationElement txt = texts.get(position);
if (txt.text != null) {
callEntry.setVisibility(View.GONE);
if (txt.text.isIncoming()) {
txtEntry.setVisibility(View.VISIBLE);
txtEntryRight.setVisibility(View.GONE);
msgTxt.setText(txt.text.getMessage());
msgDetailTxt.setText(DateFormat.getDateTimeInstance().format(new Date(txt.text.getTimestamp())));
infos_fetcher.execute(new ContactPictureTask(context, photo, txt.text.getContact()));
} else {
txtEntry.setVisibility(View.GONE);
txtEntryRight.setVisibility(View.VISIBLE);
msgTxtRight.setText(txt.text.getMessage());
msgDetailTxtRight.setText(DateFormat.getDateTimeInstance().format(new Date(txt.text.getTimestamp())));
}
} else {
callEntry.setVisibility(View.VISIBLE);
txtEntry.setVisibility(View.GONE);
txtEntryRight.setVisibility(View.GONE);
msgTxt.setText("");
histTxt.setText((txt.call.isIncoming() ? "Incoming" : "Outgoing") + " call with " + txt.call.getNumber());
histDetailTxt.setText(DateFormat.getDateTimeInstance().format(txt.call.getStartDate()));
}
return convertView;
}
}
@Override
protected void onDestroy() {
if (mBound) {
unregisterReceiver(receiver);
unbindService(mConnection);
mBound = false;
}
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.conversation_actions, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.conv_action_audiocall:
onAudioCall();
return true;
case R.id.conv_action_videocall:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void launchCallActivity(SipCall infos) {
Conference tmp = conversation.getCurrentCall();
if (tmp == null)
//tmp = service.startConversation(infos.getContact());
tmp = new Conference(Conference.DEFAULT_ID);
tmp.getParticipants().add(infos);
Intent intent = new Intent().setClass(this, CallActivity.class);
intent.putExtra("conference", tmp);
intent.putExtra("resuming", false);
startActivityForResult(intent, HomeActivity.REQUEST_CODE_CALL);
// overridePendingTransition(R.anim.slide_down, R.anim.slide_up);
}
private void onSendTextMessage(String txt) {
Conference conf = conversation.getCurrentCall();
if (conf == null || !conf.isOnGoing()) {
String account = conversation.getLastAccountUsed();
if (account == null || account.isEmpty())
account = service.guessAccount(conversation.getContact(), conversation.contact.getPhones().get(0).getNumber()).getAccountID();
String number = preferredNumber;
if (number == null || number.isEmpty())
number = conversation.getLastNumberUsed(account);
if (number == null || number.isEmpty())
number = conversation.contact.getPhones().get(0).getNumber();
try {
service.getRemoteService().sendAccountTextMessage(account, number, txt);
} catch (RemoteException e) {
e.printStackTrace();
}
} else {
try {
service.getRemoteService().sendTextMessage(conf.getId(), new TextMessage(false, txt));
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
private void onAudioCall() {
Conference conf = conversation.getCurrentCall();
if (conf != null) {
startActivity(new Intent(ConversationActivity.this.getApplicationContext(), CallActivity.class).putExtra("conference", conversation.getCurrentCall()));
return;
}
if (service.getAccounts().isEmpty()) {
//createNotRegisteredDialog().show();
return;
}
Account usedAccount = service.getAccounts().get(0);
CallContact contact = null;
if (conversation != null) {
String last_used = conversation.getLastAccountUsed();
Account a = service.getAccount(last_used);
if (a != null/* && a.isEnabled()*/)
usedAccount = a;
else {
Set<String> acc_ids = conversation.getAccountsUsed();
for (Account acc : service.getAccounts()) {
if (acc_ids.contains(acc.getAccountID())) {
usedAccount = acc;
break;
}
}
}
contact = conversation.getContact();
}
String number = preferredNumber;
if (number == null)
number = conversation.getLastNumberUsed(usedAccount.getAccountID());
if (number == null && contact != null)
number = contact.getPhones().get(0).getNumber();
//conversation.getHistory().getAccountID()
//if (usedAccount.isRegistered() || usedAccount.isIP2IP()) {
/* Bundle args = new Bundle();
args.putParcelable(SipCall.ACCOUNT, usedAccount);
args.putInt(SipCall.STATE, SipCall.State.NONE);
args.putInt(SipCall.TYPE, SipCall.Direction.OUTGOING);
args.putParcelable(SipCall.CONTACT, contact);*/
SipCall call = new SipCall(null, usedAccount.getAccountID(), number, SipCall.Direction.OUTGOING);
call.setContact(contact);
try {
launchCallActivity(call);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.toString());
}
/*} else {
createNotRegisteredDialog().show();
}*/
}
}
......@@ -36,9 +36,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Pattern;
import android.app.Activity;
import android.app.AlertDialog;
......@@ -52,14 +51,13 @@ import cx.ring.fragments.HistoryFragment;
import cx.ring.fragments.HomeFragment;
import cx.ring.fragments.MenuFragment;
import cx.ring.history.HistoryEntry;
import cx.ring.history.HistoryManager;
import cx.ring.loaders.LoaderConstants;
import cx.ring.model.account.Account;
import cx.ring.model.CallContact;
import cx.ring.model.Conference;
import cx.ring.model.SipCall;
import cx.ring.service.ISipService;
import cx.ring.service.SipService;
import cx.ring.views.SlidingUpPanelLayout;
import cx.ring.views.SlidingUpPanelLayout.PanelSlideListener;
import cx.ring.service.LocalService;
import android.app.Fragment;
import android.app.FragmentManager;
......@@ -72,18 +70,12 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
......@@ -91,14 +83,14 @@ import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.Toast;
public class HomeActivity extends AppCompatActivity implements DialingFragment.Callbacks, AccountsManagementFragment.Callbacks,
ContactListFragment.Callbacks, CallListFragment.Callbacks, HistoryFragment.Callbacks, NavigationView.OnNavigationItemSelectedListener, MenuFragment.Callbacks {
public class HomeActivity extends AppCompatActivity implements LocalService.Callbacks, DialingFragment.Callbacks,
/*ContactListFragment.Callbacks, */HistoryFragment.Callbacks, NavigationView.OnNavigationItemSelectedListener {
static final String TAG = HomeActivity.class.getSimpleName();
......@@ -107,12 +99,13 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
private MenuFragment fMenuHead = null;
private boolean mBound = false;
private ISipService service;
private LocalService service;
public static final int REQUEST_CODE_PREFERENCES = 1;
public static final int REQUEST_CODE_CALL = 3;
public static final int REQUEST_CODE_CONVERSATION = 4;
SlidingUpPanelLayout mContactDrawer;
//SlidingUpPanelLayout mContactDrawer;
private DrawerLayout mNavigationDrawer;
private ActionBarDrawerToggle mDrawerToggle;
private Toolbar toolbar;
......@@ -123,6 +116,22 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
protected Fragment fContent;
public static final Pattern RING_ID_REGEX = Pattern.compile("^\\s+(?:ring(?:[\\s\\:]+))?(\\p{XDigit}{40})\\s+$", Pattern.CASE_INSENSITIVE);
private static void setDefaultUncaughtExceptionHandler() {
try {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
Log.e(TAG, "Uncaught Exception detected in thread ", e);
//e.printStackTrace();
}
});
} catch (SecurityException e) {
Log.e(TAG, "Could not set the Default Uncaught Exception Handler");
}
}
/* called before activity is killed, e.g. rotation */
@Override
protected void onSaveInstanceState(Bundle bundle) {
......@@ -131,14 +140,18 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
@Override
public void onCreate(Bundle savedInstanceState) {
setDefaultUncaughtExceptionHandler();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// Bind to LocalService
if (!mBound) {
Log.i(TAG, "onStart: Binding service...");
Intent intent = new Intent(this, SipService.class);
/*Intent intent = new Intent(this, SipService.class);
startService(intent);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);*/
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
......@@ -148,9 +161,13 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
fMenu = (NavigationView) findViewById(R.id.left_drawer);
fMenu.setNavigationItemSelectedListener(this);
/*
FragmentManager fm = getFragmentManager();
mContactsFragment = (ContactListFragment) fm.findFragmentByTag(ContactListFragment.TAG);
if(mContactsFragment == null) {
mContactsFragment = new ContactListFragment();
getFragmentManager().beginTransaction().replace(R.id.contacts_frame, mContactsFragment).commit();
getFragmentManager().beginTransaction().replace(R.id.contacts_frame, mContactsFragment, ContactListFragment.TAG).commit();
}
mContactDrawer = (SlidingUpPanelLayout) findViewById(R.id.contact_panel);
// mContactDrawer.setShadowDrawable(getResources().getDrawable(R.drawable.above_shadow));
......@@ -187,7 +204,7 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
}
});
*/
mNavigationDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
......@@ -217,17 +234,23 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
// Sync the toggle State after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
if (mContactDrawer.isExpanded()) {
/*if (mContactDrawer.isExpanded()) {
getSupportActionBar().hide();
}
}*/
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
//mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.history, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
......@@ -248,7 +271,11 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
int abSz = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
ViewGroup.LayoutParams params = toolbar.getLayoutParams();
ViewGroup.LayoutParams params = toolbar.getLayoutParams();//toolbar.setContentInsetsRelative();
//TypedArray a = obtainStyledAttributes(attrs, R.styleable.Toolbar_titleMarginBottom);
//toolbar.get
if (double_h) {
params.height = abSz*2;
actionButton.setVisibility(View.VISIBLE);
......@@ -261,6 +288,7 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
toolbar.setMinimumHeight(abSz);
}
toolbar.setTitle(title_res);
//toolbar.setTitleTextAppearance(toolbar.getT);
}
public FloatingActionButton getActionButton() {
......@@ -336,10 +364,10 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
return;
}
if (mContactDrawer.isExpanded() || mContactDrawer.isAnchored()) {
/*if (mContactDrawer.isExpanded() || mContactDrawer.isAnchored()) {
mContactDrawer.collapsePane();
return;
}
}*/
if (getFragmentManager().getBackStackEntryCount() > 1) {
popCustomBackStack();
......@@ -347,20 +375,7 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
return;
}
if (isClosing) {
super.onBackPressed();
t.cancel();
finish();
} else {
t.schedule(new TimerTask() {
@Override
public void run() {
isClosing = false;
}
}, 3000);
Toast.makeText(this, getResources().getString(R.string.close_msg), Toast.LENGTH_SHORT).show();
isClosing = true;
}
}
private void popCustomBackStack() {
......@@ -376,20 +391,20 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
@Override
protected void onPause() {
super.onPause();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
Log.d(TAG, "onPause");
}
/* activity finishes itself or is being killed by the system */
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy: destroying service...");
Intent sipServiceIntent = new Intent(this, SipService.class);
stopService(sipServiceIntent);
if (mBound) {
unbindService(mConnection);
mBound = false;
}
//Log.i(TAG, "onDestroy: destroying service...");
//Intent sipServiceIntent = new Intent(this, SipService.class);
//stopService(sipServiceIntent);
}
public void launchCallActivity(SipCall infos) {
......@@ -410,9 +425,13 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder binder) {
service = ISipService.Stub.asInterface(binder);
fContent = new HomeFragment();
public void onServiceConnected(ComponentName className, IBinder s) {
Log.i(TAG, "onServiceConnected " + className.getClassName());
LocalService.LocalBinder binder = (LocalService.LocalBinder) s;
service = binder.getService();
//service = ISipService.Stub.asInterface(binder);
fContent = new CallListFragment();
if (fMenuHead != null)
fMenu.removeHeaderView(fMenuHead.getView());
fMenu.inflateHeaderView(R.layout.menuheader);
......@@ -420,18 +439,19 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
getFragmentManager().beginTransaction().replace(R.id.main_frame, fContent, "Home").addToBackStack("Home").commit();
mBound = true;
Log.d(TAG, "Service connected service=" + service);
Log.i(TAG, "Service connected service=" + service);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
public void onServiceDisconnected(ComponentName className) {
Log.i(TAG, "onServiceConnected " + className.getClassName());
if (fMenuHead != null) {
fMenu.removeHeaderView(fMenuHead.getView());
fMenuHead = null;
}
mBound = false;
Log.d(TAG, "Service disconnected service=" + service);
Log.i(TAG, "Service disconnected service=" + service);
}
};
......@@ -442,9 +462,18 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
case R.id.menu_clear_history:
// TODO clean Database!
//mHistoryManager.clearDB();
//getLoaderManager().restartLoader(LoaderConstants.HISTORY_LOADER, null, this);
HistoryManager m = new HistoryManager(this);
m.clearDB();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
......@@ -466,10 +495,16 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
}
@Override
public ISipService getService() {
public ISipService getRemoteService() {
return service.getRemoteService();
}
@Override
public LocalService getService() {
return service;
}
/*
@Override
public void onTextContact(final CallContact c) {
// TODO
......@@ -483,6 +518,7 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
startActivity(intent);
}
@Override
public void onCallContact(final CallContact c) {
......@@ -506,10 +542,10 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
public void run() {
Bundle args = new Bundle();
args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
//args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
args.putParcelable(SipCall.ACCOUNT, fMenuHead.getSelectedAccount());
args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_NONE);
args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
args.putInt(SipCall.STATE, SipCall.State.NONE);
args.putInt(SipCall.TYPE, SipCall.Direction.OUTGOING);
Cursor cPhones = getContentResolver().query(Phone.CONTENT_URI, CONTACTS_PHONES_PROJECTION, Phone.CONTACT_ID + " =" + c.getId(),
null, null);
......@@ -533,10 +569,10 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
}
});
launcher.start();
mContactDrawer.collapsePane();
//mContactDrawer.collapsePane();
}
*/
@Override
public void onCallHistory(HistoryEntry to) {
......@@ -549,10 +585,10 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
if (usedAccount.isRegistered()) {
Bundle args = new Bundle();
args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
//args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
args.putParcelable(SipCall.ACCOUNT, usedAccount);
args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_NONE);
args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
args.putInt(SipCall.STATE, SipCall.State.NONE);
args.putInt(SipCall.TYPE, SipCall.Direction.OUTGOING);
args.putParcelable(SipCall.CONTACT, to.getContact());
try {
......@@ -567,7 +603,15 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
@Override
public void onCallDialed(String to) {
Account usedAccount = fMenuHead.getSelectedAccount();
Intent intent = new Intent()
.setClass(this, CallActivity.class)
.setAction(Intent.ACTION_CALL)
.setData(Uri.parse(to));
/*intent.putExtra("conference", tmp);
intent.putExtra("resuming", false);*/
startActivityForResult(intent, REQUEST_CODE_CALL);
/*Account usedAccount = fMenuHead.getSelectedAccount();
if (usedAccount == null) {
createAccountDialog().show();
......@@ -576,10 +620,14 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
if (usedAccount.isRegistered() || usedAccount.isIP2IP()) {
Bundle args = new Bundle();
args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
Matcher m = RING_ID_REGEX.matcher(to);
if (m.matches() && m.groupCount() > 0) {
to = "ring:"+m.group(1);
}
args.putParcelable(SipCall.ACCOUNT, usedAccount);
args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_NONE);
args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
args.putInt(SipCall.STATE, SipCall.State.NONE);
args.putInt(SipCall.TYPE, SipCall.Direction.OUTGOING);
args.putParcelable(SipCall.CONTACT, CallContact.ContactBuilder.buildUnknownContact(to));
try {
......@@ -589,7 +637,7 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
}
} else {
createNotRegisteredDialog().show();
}
}*/
}
private AlertDialog createNotRegisteredDialog() {
......@@ -634,6 +682,7 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
return alertDialog;
}
/*
@Override
public void onContactDragged() {
mContactDrawer.collapsePane();
......@@ -661,7 +710,7 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
public void setDragView(RelativeLayout relativeLayout) {
mContactDrawer.setDragView(relativeLayout);
}
*/
@Override
public boolean onNavigationItemSelected(MenuItem pos) {
pos.setChecked(true);
......@@ -670,7 +719,7 @@ public class HomeActivity extends AppCompatActivity implements DialingFragment.C
switch (pos.getItemId()) {
case R.id.menuitem_home:
if (fContent instanceof HomeFragment)
if (fContent instanceof CallListFragment)
break;
if (getFragmentManager().getBackStackEntryCount() == 1)
......
package cx.ring.client;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.RelativeLayout;
import android.widget.SearchView;
import cx.ring.R;
import cx.ring.fragments.ContactListFragment;
import cx.ring.model.CallContact;
public class NewConversationActivity extends Activity implements ContactListFragment.Callbacks {
//private SearchView searchView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.activity_new_conversation);
}
/*
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.newconv_option_menu, menu);
//searchView = (SearchView) menu.findItem(R.id.contact_search).getActionView();
return true;
}
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onCallContact(final CallContact c) {
if (c.getPhones().size() > 1) {
final CharSequence colors[] = new CharSequence[c.getPhones().size()];
int i = 0;
for (CallContact.Phone p : c.getPhones())
colors[i++] = p.getNumber();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose a number");
builder.setItems(colors, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
CharSequence selected = colors[which];
Intent intent = new Intent()
.setClass(NewConversationActivity.this, ConversationActivity.class)
.setAction(Intent.ACTION_VIEW)
.setData(Uri.withAppendedPath(ConversationActivity.CONTENT_URI, c.getIds().get(0)))
.putExtra("number", selected);
startActivityForResult(intent, HomeActivity.REQUEST_CODE_CONVERSATION);
}
});
builder.show();
} else {
Intent intent = new Intent()
.setClass(this, ConversationActivity.class)
.setAction(Intent.ACTION_VIEW)
.setData(Uri.withAppendedPath(ConversationActivity.CONTENT_URI, c.getIds().get(0)));
startActivityForResult(intent, HomeActivity.REQUEST_CODE_CONVERSATION);
}
}
@Override
public void onTextContact(final CallContact c) {
if (c.getPhones().size() > 1) {
final CharSequence colors[] = new CharSequence[c.getPhones().size()];// {"red", "green", "blue", "black"};
int i = 0;
for (CallContact.Phone p : c.getPhones())
colors[i++] = p.getNumber();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose a number");
builder.setItems(colors, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
CharSequence selected = colors[which];
Intent intent = new Intent()
.setClass(NewConversationActivity.this, ConversationActivity.class)
.setAction(Intent.ACTION_VIEW)
.setData(Uri.withAppendedPath(ConversationActivity.CONTENT_URI, c.getIds().get(0)))
.putExtra("number", selected);
startActivityForResult(intent, HomeActivity.REQUEST_CODE_CONVERSATION);
}
});
builder.show();
} else {
Intent intent = new Intent()
.setClass(this, ConversationActivity.class)
.setAction(Intent.ACTION_VIEW)
.setData(Uri.withAppendedPath(ConversationActivity.CONTENT_URI, c.getIds().get(0)));
startActivityForResult(intent, HomeActivity.REQUEST_CODE_CONVERSATION);
}
}
@Override
public void onContactDragged() {
}
@Override
public void toggleDrawer() {
}
@Override
public void onEditContact(CallContact item) {
}
@Override
public void setDragView(RelativeLayout relativeLayout) {
}
@Override
public void toggleForSearchDrawer() {
}
/*
@Override
public SearchView getSearchView() {
return searchView;
}*/
}
/*
* Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
*
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
package cx.ring.fragments;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.app.Fragment;
import android.util.Log;
import cx.ring.interfaces.AccountsInterface;
import cx.ring.service.ConfigurationManagerCallback;
public abstract class AccountWrapperFragment extends Fragment implements AccountsInterface
{
static final String TAG = "AccountWrapperFragment";
private AccountsReceiver mReceiver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReceiver = new AccountsReceiver();
}
@Override
public void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
intentFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
getActivity().registerReceiver(mReceiver, intentFilter);
}
@Override
public void accountsChanged() {
Log.i(TAG, "accountsChanged");
}
@Override
public void accountStateChanged(String accoundID, String state, int code) {
Log.i(TAG, "accountStateChanged" + accoundID + " " + state + " " + code);
}
@Override
public void onPause() {
super.onPause();
getActivity().unregisterReceiver(mReceiver);
}
public class AccountsReceiver extends BroadcastReceiver {
private final String TAG = AccountsReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED)) {
Log.i(TAG, "Received " + intent.getAction() + " " + intent.getStringExtra("Account") + " " + intent.getStringExtra("state") + " " + intent.getIntExtra("code", 0));
accountStateChanged(intent.getStringExtra("Account"), intent.getStringExtra("state"), intent.getIntExtra("code", 0));
} else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_CHANGED)) {
Log.i(TAG, "Received" + intent.getAction());
accountsChanged();
}
}
}
}
\ No newline at end of file
......@@ -3,6 +3,7 @@
*
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Alexandre Lision <alexandre.lision@savoirfairelinux.com>
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -35,11 +36,12 @@ package cx.ring.fragments;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.app.LoaderManager;
import android.content.AsyncTaskLoader;
import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.design.widget.FloatingActionButton;
......@@ -53,28 +55,25 @@ import cx.ring.R;
import cx.ring.client.AccountEditionActivity;
import cx.ring.client.AccountWizard;
import cx.ring.client.HomeActivity;
import cx.ring.loaders.AccountsStateLoader;
import cx.ring.loaders.AccountsLoader;
import cx.ring.loaders.LoaderConstants;
import cx.ring.model.account.Account;
import cx.ring.model.account.AccountDetailAdvanced;
import cx.ring.model.account.AccountDetailBasic;
import cx.ring.service.ISipService;
import cx.ring.service.LocalService;
import cx.ring.views.dragsortlv.DragSortListView;
import java.io.File;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;
public class AccountsManagementFragment extends AccountWrapperFragment implements LoaderManager.LoaderCallbacks<Bundle> {
static final String TAG = "AccountManagementFrag";
static final String DEFAULT_ACCOUNT_ID = "IP2IP";
static final int ACCOUNT_CREATE_REQUEST = 1;
public class AccountsManagementFragment extends Fragment {
static final String TAG = AccountsManagementFragment.class.getSimpleName();
private static final String DEFAULT_ACCOUNT_ID = "IP2IP";
public static final int ACCOUNT_CREATE_REQUEST = 1;
public static final int ACCOUNT_EDIT_REQUEST = 2;
AccountsAdapter mAccountsAdapter;
AccountsAdapter mIP2IPAdapter;
private AccountsAdapter mAccountsAdapter;
private AccountsAdapter mIP2IPAdapter;
DragSortListView mDnDListView;
private DragSortListView mDnDListView;
private View mLoadingView;
private int mShortAnimationDuration;
......@@ -86,46 +85,31 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
mAccountsAdapter.remove(item);
mAccountsAdapter.insert(item, to);
try {
mCallbacks.getService().setAccountOrder(mAccountsAdapter.generateAccountOrder());
mCallbacks.getService().getRemoteService().setAccountOrder(mAccountsAdapter.generateAccountOrder());
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
};
private Callbacks mCallbacks = sDummyCallbacks;
private Account ip2ip;
private static Callbacks sDummyCallbacks = new Callbacks() {
@Override
public ISipService getService() {
return null;
}
};
private AccountsLoader accountsLoader;
public interface Callbacks {
public ISipService getService();
}
private LocalService.Callbacks mCallbacks = LocalService.DUMMY_CALLBACKS;
//private Account ip2ip;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks)) {
if (!(activity instanceof LocalService.Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
mCallbacks = (LocalService.Callbacks) activity;
}
@Override
public void onDetach() {
super.onDetach();
mCallbacks = sDummyCallbacks;
mCallbacks = LocalService.DUMMY_CALLBACKS;
}
@Override
......@@ -133,13 +117,23 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
super.onCreate(savedInstanceState);
Log.i(TAG, "Create Account Management Fragment");
mAccountsAdapter = new AccountsAdapter(getActivity(), new ArrayList<Account>());
mIP2IPAdapter = new AccountsAdapter(getActivity(), new ArrayList<Account>());
mAccountsAdapter = new AccountsAdapter(getActivity());
mIP2IPAdapter = new AccountsAdapter(getActivity());
this.setHasOptionsMenu(true);
mShortAnimationDuration = getResources().getInteger(android.R.integer.config_mediumAnimTime);
Log.i(TAG, "anim time: " + mShortAnimationDuration);
getLoaderManager().initLoader(LoaderConstants.ACCOUNTS_LOADER, null, this);
//getLoaderManager().initLoader(LoaderConstants.ACCOUNTS_LOADER, null, this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(LocalService.ACTION_ACCOUNT_UPDATE);
getActivity().registerReceiver(mReceiver, intentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().unregisterReceiver(mReceiver);
}
@Override
......@@ -170,8 +164,7 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
launchAccountEditActivity(ip2ip);
launchAccountEditActivity(mIP2IPAdapter.accounts.get(0));
}
});
......@@ -185,7 +178,8 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
public void onResume() {
super.onResume();
accountsLoader.onContentChanged();
//accountsLoader.onContentChanged();
refreshAccountList();
((HomeActivity) getActivity()).setToolbarState(true, R.string.menu_item_accounts);
FloatingActionButton btn = ((HomeActivity) getActivity()).getActionButton();
btn.setImageResource(R.drawable.ic_add_white_24dp);
......@@ -196,6 +190,7 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
startActivityForResult(intent, ACCOUNT_CREATE_REQUEST);
}
});
crossfade();
}
@Override
......@@ -220,29 +215,17 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
private void launchAccountEditActivity(Account acc) {
Log.i(TAG, "Launch account edit activity");
Intent intent = new Intent().setClass(getActivity(), AccountEditionActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("account", acc);
intent.putExtras(bundle);
Intent intent = new Intent()
.setClass(getActivity(), AccountEditionActivity.class)
.setAction(Intent.ACTION_EDIT)
.setData(Uri.withAppendedPath(AccountEditionActivity.CONTENT_URI, acc.getAccountID()));
startActivityForResult(intent, ACCOUNT_EDIT_REQUEST);
}
@Override
public void accountsChanged() {
accountsLoader.onContentChanged();
}
@Override
public void accountStateChanged(String accoundID, String state, int code) {
mAccountsAdapter.updateAccount(accoundID, state, code);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
accountsLoader.onContentChanged();
refreshAccountList();
}
/**
......@@ -254,13 +237,12 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
// private static final String TAG = AccountSelectionAdapter.class.getSimpleName();
ArrayList<Account> accounts;
Context mContext;
private final ArrayList<Account> accounts = new ArrayList<>();
private final Context mContext;
public AccountsAdapter(Context cont, ArrayList<Account> newList) {
public AccountsAdapter(Context c) {
super();
accounts = newList;
mContext = cont;
mContext = c;
}
public void insert(Account item, int to) {
......@@ -335,7 +317,7 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
public void onClick(View v) {
item.setEnabled(!item.isEnabled());
try {
mCallbacks.getService().setAccountDetails(item.getAccountID(), item.getDetails());
mCallbacks.getService().getRemoteService().setAccountDetails(item.getAccountID(), item.getDetails());
} catch (RemoteException e) {
e.printStackTrace();
}
......@@ -381,39 +363,27 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
}
public void addAll(ArrayList<Account> results) {
public void addAll(List<Account> results) {
Log.i(TAG, "AccountsAdapter addAll " + results.size());
accounts.addAll(results);
/*for (final Account a : results) {
final String acc_id = a.getAccountID();
getLoaderManager().initLoader((int)(Long.parseLong(acc_id.substring(0, 8), 16) & 0x00000000FFFFFFFFL), null, new LoaderManager.LoaderCallbacks<Map<String, String>>() {
@Override
public Loader<Map<String, String>> onCreateLoader(int id, Bundle args) {
Log.i(TAG, "AccountsAdapter addAll onCreateLoader " + id + " " + acc_id);
return new AccountsStateLoader(getActivity(), mCallbacks.getService(), acc_id);
}
@Override
public void onLoadFinished(Loader<Map<String, String>> loader, Map<String, String> data) {
Log.w(TAG, "onLoadFinished");
a.setRegistered_state(data.get(AccountDetailAdvanced.CONFIG_ACCOUNT_REGISTRATION_STATUS), Integer.getInteger(data.get(AccountDetailAdvanced.CONFIG_ACCOUNT_REGISTRATION_STATE_CODE)));
notifyDataSetChanged();
}
@Override
public void onLoaderReset(Loader<Map<String, String>> loader) {
}
});
}*/
public void replaceAll(List<Account> results) {
Log.i(TAG, "AccountsAdapter replaceAll " + results.size());
accounts.clear();
accounts.addAll(results);
notifyDataSetChanged();
}
/**
* Modify state of specific account
* Modify State of specific account
*/
public void updateAccount(String accoundID, String state, int code) {
Log.i(TAG, "updateAccount:" + state);
for (Account a : accounts) {
if (a.getAccountID().contentEquals(accoundID)) {
a.setRegistered_state(state, code);
a.setRegistrationState(state, code);
notifyDataSetChanged();
return;
}
......@@ -453,33 +423,24 @@ public class AccountsManagementFragment extends AccountWrapperFragment implement
});
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public AsyncTaskLoader<Bundle> onCreateLoader(int arg0, Bundle arg1) {
accountsLoader = new AccountsLoader(getActivity(), mCallbacks.getService());
return accountsLoader;
public void onReceive(Context context, Intent intent) {
if (intent.getAction().contentEquals(LocalService.ACTION_ACCOUNT_UPDATE)) {
refreshAccountList();
}
}
};
@Override
public void onLoadFinished(Loader<Bundle> bundleLoader, Bundle results) {
mAccountsAdapter.removeAll();
ArrayList<Account> tmp = results.getParcelableArrayList(AccountsStateLoader.ACCOUNTS);
ip2ip = results.getParcelable(AccountsStateLoader.ACCOUNT_IP2IP);
mAccountsAdapter.addAll(tmp);
mIP2IPAdapter.removeAll();
mIP2IPAdapter.insert(ip2ip, 0);
private void refreshAccountList() {
Log.i(TAG, "refreshAccountList");
mAccountsAdapter.replaceAll(mCallbacks.getService().getAccounts());
if (mAccountsAdapter.isEmpty()) {
mDnDListView.setEmptyView(getView().findViewById(R.id.empty_account_list));
}
for (Account acc : tmp) {
}
crossfade();
mIP2IPAdapter.replaceAll(mCallbacks.getService().getIP2IPAccount());
Log.i(TAG, "refreshAccountList DONE");
mAccountsAdapter.notifyDataSetChanged();
mIP2IPAdapter.notifyDataSetChanged();
}
@Override
public void onLoaderReset(Loader<Bundle> bundleLoader) {
}
}
......@@ -42,6 +42,7 @@ import cx.ring.model.account.AccountDetailAdvanced;
import cx.ring.model.account.Account;
import cx.ring.model.Codec;
import cx.ring.service.ISipService;
import cx.ring.service.LocalService;
import cx.ring.views.dragsortlv.DragSortListView;
import android.app.Activity;
......@@ -73,26 +74,23 @@ public class AudioManagementFragment extends PreferenceFragment {
ArrayList<Codec> codecs;
private DragSortListView mCodecList;
CodecAdapter listAdapter;
private static Callbacks sDummyCallbacks = new Callbacks() {
private static final Callbacks sDummyCallbacks = new Callbacks() {
@Override
public ISipService getService() {
public ISipService getRemoteService() {
return null;
}
@Override
public LocalService getService() {
return null;
}
@Override
public Account getAccount() {
return null;
}
};
public interface Callbacks {
public ISipService getService();
public Account getAccount();
public interface Callbacks extends LocalService.Callbacks {
Account getAccount();
}
@Override
......@@ -104,7 +102,7 @@ public class AudioManagementFragment extends PreferenceFragment {
mCallbacks = (Callbacks) activity;
try {
codecs = (ArrayList<Codec>) mCallbacks.getService().getAudioCodecList(mCallbacks.getAccount().getAccountID());
codecs = (ArrayList<Codec>) mCallbacks.getRemoteService().getAudioCodecList(mCallbacks.getAccount().getAccountID());
//mCallbacks.getService().getRingtoneList();
} catch (RemoteException e) {
e.printStackTrace();
......@@ -125,7 +123,7 @@ public class AudioManagementFragment extends PreferenceFragment {
listAdapter.remove(item);
listAdapter.insert(item, to);
try {
mCallbacks.getService().setActiveCodecList(getActiveCodecList(), mCallbacks.getAccount().getAccountID());
mCallbacks.getRemoteService().setActiveCodecList(getActiveCodecList(), mCallbacks.getAccount().getAccountID());
} catch (RemoteException e) {
e.printStackTrace();
}
......@@ -193,7 +191,7 @@ public class AudioManagementFragment extends PreferenceFragment {
listAdapter.getItem(pos).toggleState();
listAdapter.notifyDataSetChanged();
try {
mCallbacks.getService().setActiveCodecList(getActiveCodecList(), mCallbacks.getAccount().getAccountID());
mCallbacks.getRemoteService().setActiveCodecList(getActiveCodecList(), mCallbacks.getAccount().getAccountID());
} catch (RemoteException e) {
e.printStackTrace();
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment