diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 909529b19..b1904f9ca 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -207,8 +207,8 @@ - - + + diff --git a/README b/README index 1693d40d6..e2269f90d 100644 --- a/README +++ b/README @@ -7,8 +7,8 @@ COMPILATION INSTRUCTIONS To build liblinphone for Android, you must: ------------------------------------------- -0) download the Android sdk with platform-tools and tools updated to latest revision (at least API 16 is needed), then add both 'tools' and 'platform-tools' folders in your path. -1) download the Android ndk (version r11) from google and add it to your path (no symlink !!!). +0) download the Android sdk (API 23 at least) with platform-tools and tools updated to latest revision, then add both 'tools' and 'platform-tools' folders in your path. +1) download the Android ndk (version r11c or 12b) from google and add it to your path (no symlink !!!). 2) install yasm, nasm, ant, python, cmake and vim-common On 64 bits linux systems you'll need the ia32-libs package With the latest Debian (multiarch), you need this: @@ -27,11 +27,12 @@ To build liblinphone for Android, you must: $ make mediastreamer2-sdk 8) (Optional) To generate a signed apk to publish on the Google Play, run $ make release -Make sure you filled the ant.properties values for version.name, key.store and key.alias in order to correctly sign the generated apk. -You also may want to create a file name ant_password.properties with the following: -key.store.password=[your_password] -key.alias.password=[your_password] -If you don't, the passwords will be asked at the signing phase. + Make sure you filled the ant.properties values for version.name, key.store and key.alias in order to correctly sign the generated apk. + You also may want to create a file name ant_password.properties with the following: + key.store.password=[your_password] + key.alias.password=[your_password] + If you don't, the passwords will be asked at the signing phase. +9) (Optional) Once you compiled the libraries succesfully with 'make', you can reduce the compilation time using 'make quick': it will only generate a new APK from java files. To run the tutorials: -------------------- diff --git a/liblinphone_tester/custom_rules.xml b/liblinphone_tester/custom_rules.xml index da0216dc5..8a36b3884 100644 --- a/liblinphone_tester/custom_rules.xml +++ b/liblinphone_tester/custom_rules.xml @@ -48,7 +48,7 @@ - + diff --git a/res/layout/contact_edit.xml b/res/layout/contact_edit.xml index da442c190..933c88ab2 100644 --- a/res/layout/contact_edit.xml +++ b/res/layout/contact_edit.xml @@ -136,6 +136,7 @@ android:inputType="textPersonName|textCapWords"/> false false + true + false true diff --git a/res/values/non_localizable_strings.xml b/res/values/non_localizable_strings.xml index f4e25d109..c114a813e 100644 --- a/res/values/non_localizable_strings.xml +++ b/res/values/non_localizable_strings.xml @@ -205,4 +205,5 @@ pref_use_lime_encryption_key pref_device_ringtone_key pref_auto_answer_key + pref_android_app_settings_key diff --git a/res/values/strings.xml b/res/values/strings.xml index a7edab164..901b491e3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -313,6 +313,7 @@ Start at boot time Incoming call hangup (in seconds) Remote provisioning + Android app settings Primary account Display name Username diff --git a/res/xml/contacts.xml b/res/xml/contacts.xml index 6b5d8e180..db84bc8c9 100644 --- a/res/xml/contacts.xml +++ b/res/xml/contacts.xml @@ -3,7 +3,7 @@ - + + + diff --git a/src/org/linphone/AboutFragment.java b/src/org/linphone/AboutFragment.java index 933e9914f..e5cabadc5 100644 --- a/src/org/linphone/AboutFragment.java +++ b/src/org/linphone/AboutFragment.java @@ -69,11 +69,11 @@ public class AboutFragment extends Fragment implements OnClickListener { sendLogButton = view.findViewById(R.id.send_log); sendLogButton.setOnClickListener(this); - sendLogButton.setVisibility(org.linphone.LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE); + sendLogButton.setVisibility(LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE); resetLogButton = view.findViewById(R.id.reset_log); resetLogButton.setOnClickListener(this); - resetLogButton.setVisibility(org.linphone.LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE); + resetLogButton.setVisibility(LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE); mListener = new LinphoneCoreListenerBase() { @Override @@ -145,7 +145,7 @@ public class AboutFragment extends Fragment implements OnClickListener { lc.addListener(mListener); } - if (org.linphone.LinphoneActivity.isInstanciated()) { + if (LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().selectMenu(FragmentsAvailable.ABOUT); } @@ -154,8 +154,8 @@ public class AboutFragment extends Fragment implements OnClickListener { @Override public void onClick(View v) { - if (org.linphone.LinphoneActivity.isInstanciated()) { - LinphoneCore lc = org.linphone.LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (LinphoneActivity.isInstanciated()) { + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); if (v == sendLogButton) { if (lc != null) { lc.uploadLogCollection(); @@ -174,6 +174,4 @@ public class AboutFragment extends Fragment implements OnClickListener { public void onDestroy() { super.onDestroy(); } - - } diff --git a/src/org/linphone/AccountPreferencesFragment.java b/src/org/linphone/AccountPreferencesFragment.java index 0ba776a1f..9e6c98417 100644 --- a/src/org/linphone/AccountPreferencesFragment.java +++ b/src/org/linphone/AccountPreferencesFragment.java @@ -53,8 +53,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment { mPrefs = LinphonePreferences.instance(); } - public void onCreate(Bundle savedInstanceState) - { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); PreferenceScreen screen = getPreferenceScreen(); @@ -69,7 +68,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment { getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); } - public static boolean isEditTextEmpty(String s){ + public static boolean isEditTextEmpty(String s) { return s.equals(""); // really empty. } diff --git a/src/org/linphone/BluetoothManager.java b/src/org/linphone/BluetoothManager.java index 34982c4e0..c3d0523ec 100644 --- a/src/org/linphone/BluetoothManager.java +++ b/src/org/linphone/BluetoothManager.java @@ -19,7 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import java.util.List; -import org.linphone.compatibility.Compatibility; import org.linphone.mediastream.Log; import android.annotation.TargetApi; @@ -68,31 +67,31 @@ public class BluetoothManager extends BroadcastReceiver { public BluetoothManager() { isBluetoothConnected = false; if (!ensureInit()) { - Log.w("BluetoothManager tried to init but LinphoneService not ready yet..."); + Log.w("[Bluetooth] Manager tried to init but LinphoneService not ready yet..."); } instance = this; } public void initBluetooth() { if (!ensureInit()) { - Log.w("BluetoothManager tried to init bluetooth but LinphoneService not ready yet..."); + Log.w("[Bluetooth] Manager tried to init bluetooth but LinphoneService not ready yet..."); return; } IntentFilter filter = new IntentFilter(); filter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." + BluetoothAssignedNumbers.PLANTRONICS); - filter.addAction(Compatibility.getAudioManagerEventForBluetoothConnectionStateChangedEvent()); + filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT); mContext.registerReceiver(this, filter); - Log.d("Bluetooth receiver started"); + Log.d("[Bluetooth] Receiver started"); startBluetooth(); } private void startBluetooth() { if (isBluetoothConnected) { - Log.e("Bluetooth already started"); + Log.e("[Bluetooth] Already started, skipping..."); return; } @@ -100,14 +99,14 @@ public class BluetoothManager extends BroadcastReceiver { if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) { if (mProfileListener != null) { - Log.w("Bluetooth headset profile was already opened, let's close it"); + Log.w("[Bluetooth] Headset profile was already opened, let's close it"); mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset); } mProfileListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { if (profile == BluetoothProfile.HEADSET) { - Log.d("Bluetooth headset connected"); + Log.d("[Bluetooth] Headset connected"); mBluetoothHeadset = (BluetoothHeadset) proxy; isBluetoothConnected = true; } @@ -116,17 +115,17 @@ public class BluetoothManager extends BroadcastReceiver { if (profile == BluetoothProfile.HEADSET) { mBluetoothHeadset = null; isBluetoothConnected = false; - Log.d("Bluetooth headset disconnected"); + Log.d("[Bluetooth] Headset disconnected"); LinphoneManager.getInstance().routeAudioToReceiver(); } } }; boolean success = mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET); if (!success) { - Log.e("Bluetooth getProfileProxy failed !"); + Log.e("[Bluetooth] getProfileProxy failed !"); } } else { - Log.w("Bluetooth interface disabled on device"); + Log.w("[Bluetooth] Interface disabled on device"); } } @@ -153,7 +152,7 @@ public class BluetoothManager extends BroadcastReceiver { if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mAudioManager != null && mAudioManager.isBluetoothScoAvailableOffCall()) { if (isBluetoothHeadsetAvailable()) { if (mAudioManager != null && !mAudioManager.isBluetoothScoOn()) { - Log.d("Bluetooth sco off, let's start it"); + Log.d("[Bluetooth] SCO off, let's start it"); mAudioManager.setBluetoothScoOn(true); mAudioManager.startBluetoothSco(); } @@ -180,12 +179,12 @@ public class BluetoothManager extends BroadcastReceiver { } if (ok) { if (retries > 0) { - Log.d("Bluetooth route ok after " + retries + " retries"); + Log.d("[Bluetooth] Audio route ok after " + retries + " retries"); } else { - Log.d("Bluetooth route ok"); + Log.d("[Bluetooth] Audio route ok"); } } else { - Log.d("Bluetooth still not ok..."); + Log.d("[Bluetooth] Audio route still not ok..."); } return ok; @@ -212,7 +211,7 @@ public class BluetoothManager extends BroadcastReceiver { break; } } - Log.d(isHeadsetConnected ? "Headset found, bluetooth audio route available" : "No headset found, bluetooth audio route unavailable"); + Log.d(isHeadsetConnected ? "[Bluetooth] Headset found, bluetooth audio route available" : "[Bluetooth] No headset found, bluetooth audio route unavailable"); } return isHeadsetConnected; } @@ -237,12 +236,12 @@ public class BluetoothManager extends BroadcastReceiver { mAudioManager.stopBluetoothSco(); mAudioManager.setBluetoothScoOn(false); } - Log.w("Bluetooth sco disconnected!"); + Log.w("[Bluetooth] SCO disconnected!"); } } public void stopBluetooth() { - Log.w("Stopping bluetooth..."); + Log.w("[Bluetooth] Stopping..."); isBluetoothConnected = false; disableBluetoothSCO(); @@ -253,7 +252,7 @@ public class BluetoothManager extends BroadcastReceiver { } mBluetoothDevice = null; - Log.w("Bluetooth stopped!"); + Log.w("[Bluetooth] Stopped!"); if (LinphoneManager.isInstanciated()) { LinphoneManager.getInstance().routeAudioToReceiver(); @@ -266,7 +265,7 @@ public class BluetoothManager extends BroadcastReceiver { try { mContext.unregisterReceiver(this); - Log.d("Bluetooth receiver stopped"); + Log.d("[Bluetooth] Receiver stopped"); } catch (Exception e) {} } catch (Exception e) { Log.e(e); @@ -278,30 +277,30 @@ public class BluetoothManager extends BroadcastReceiver { return; String action = intent.getAction(); - if (Compatibility.getAudioManagerEventForBluetoothConnectionStateChangedEvent().equals(action)) { + if (AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED.equals(action)) { int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 0); if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) { - Log.d("Bluetooth sco state => connected"); + Log.d("[Bluetooth] SCO state: connected"); // LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH); isScoConnected = true; } else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) { - Log.d("Bluetooth sco state => disconnected"); + Log.d("[Bluetooth] SCO state: disconnected"); // LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER); isScoConnected = false; } else { - Log.d("Bluetooth sco state => " + state); + Log.d("[Bluetooth] SCO state: " + state); } } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED); if (state == 0) { - Log.d("Bluetooth state => disconnected"); + Log.d("[Bluetooth] State: disconnected"); stopBluetooth(); } else if (state == 2) { - Log.d("Bluetooth state => connected"); + Log.d("[Bluetooth] State: connected"); startBluetooth(); } else { - Log.d("Bluetooth state => " + state); + Log.d("[Bluetooth] State: " + state); } } else if (intent.getAction().equals(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT)) { @@ -314,7 +313,7 @@ public class BluetoothManager extends BroadcastReceiver { if (eventName.equals("BUTTON") && args.length >= 3) { Integer buttonID = (Integer) args[1]; Integer mode = (Integer) args[2]; - Log.d("Bluetooth event: " + command + " : " + eventName + ", id = " + buttonID + " (" + mode + ")"); + Log.d("[Bluetooth] Event: " + command + " : " + eventName + ", id = " + buttonID + " (" + mode + ")"); } } } diff --git a/src/org/linphone/CallActivity.java b/src/org/linphone/CallActivity.java index b9274d53d..da94060e8 100644 --- a/src/org/linphone/CallActivity.java +++ b/src/org/linphone/CallActivity.java @@ -119,6 +119,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve private boolean isConferenceRunning = false; private LinphoneCoreListenerBase mListener; private DrawerLayout sideMenu; + private boolean mProximitySensingEnabled; public static CallActivity instance() { return instance; @@ -800,8 +801,22 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve } } + private void enableProximitySensing(boolean enable){ + if (enable){ + if (!mProximitySensingEnabled){ + mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + mProximitySensingEnabled = true; + } + }else{ + if (mProximitySensingEnabled){ + mSensorManager.unregisterListener(this); + mProximitySensingEnabled = false; + } + } + } + private void showAudioView() { - mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + enableProximitySensing(true); replaceFragmentVideoByAudio(); displayAudioCall(); showStatusBar(); @@ -816,7 +831,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve } refreshInCallActions(); - mSensorManager.unregisterListener(this); + enableProximitySensing(false); replaceFragmentAudioByVideo(); hideStatusBar(); } @@ -1173,7 +1188,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve handleViewIntent(); if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) { - mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + enableProximitySensing(true); removeCallbacks(); } } @@ -1223,10 +1238,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve mControlsHandler.removeCallbacks(mControls); } mControls = null; - - if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) { - mSensorManager.unregisterListener(this); - } + enableProximitySensing(false); } @Override @@ -1239,7 +1251,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve mControls = null; mControlsHandler = null; - mSensorManager.unregisterListener(this); + enableProximitySensing(false); unbindDrawables(findViewById(R.id.topLayout)); instance = null; @@ -1510,7 +1522,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve private void displayConference(boolean isInConf){ if(isInConf) { mControlsLayout.setVisibility(View.VISIBLE); - mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + enableProximitySensing(true); mActiveCallHeader.setVisibility(View.GONE); mNoCurrentCall.setVisibility(View.GONE); conferenceList.removeAllViews(); diff --git a/src/org/linphone/ChatFragment.java b/src/org/linphone/ChatFragment.java index 4f8c4323e..42e404914 100644 --- a/src/org/linphone/ChatFragment.java +++ b/src/org/linphone/ChatFragment.java @@ -44,6 +44,8 @@ import android.app.Activity; import android.app.Dialog; import android.app.Fragment; import android.app.ProgressDialog; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; @@ -387,7 +389,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC if(isEditMode) { deleteChatBubble.setVisibility(View.VISIBLE); - if(message.isOutgoing()){ + if (message.isOutgoing()) { RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); layoutParams.setMargins(100, 10, 10, 10); @@ -419,7 +421,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } }); - if(messagesList.isItemChecked(position)) { + if (messagesList.isItemChecked(position)) { deleteChatBubble.setChecked(true); } else { deleteChatBubble.setChecked(false); @@ -427,7 +429,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC rlayout.addView(v); } else { - if(message.isOutgoing()){ + if (message.isOutgoing()) { RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); layoutParams.setMargins(100, 10, 10, 10); @@ -448,7 +450,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); LinphoneAddress lAddress = null; - if(sipUri == null){ + if (sipUri == null) { initNewChatConversation(); } else { try { @@ -477,7 +479,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } private void displayMessageList() { - if(chatRoom != null) { + if (chatRoom != null) { if (adapter != null) { adapter.refreshHistory(); } else { @@ -488,7 +490,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } private void displayChatHeader(LinphoneAddress address) { - if(contact != null) { + if (contact != null) { contactName.setText(contact.getFullName()); } else if(address != null){ contactName.setText(LinphoneUtils.getAddressDisplayName(address)); @@ -618,7 +620,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC String draft = getArguments().getString("messageDraft"); message.setText(draft); - if(!newChatConversation) { + if (!newChatConversation) { initChatRoom(sipUri); searchContactField.setVisibility(View.GONE); resultContactsSearch.setVisibility(View.GONE); @@ -626,10 +628,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } } - private void selectAllList(boolean isSelectAll){ + private void selectAllList(boolean isSelectAll) { int size = messagesList.getAdapter().getCount(); - for(int i=0; i doInBackground(Void... params) { List contacts = new ArrayList(); if (hasContactsAccess()) { - Cursor c = Compatibility.getContactsCursor(contentResolver, null); + Cursor c = getContactsCursor(contentResolver); if (c != null) { while (c.moveToNext()) { String id = c.getString(c.getColumnIndex(Data.CONTACT_ID)); @@ -247,34 +249,37 @@ public class ContactsManager extends ContentObserver { } } - for (LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) { - String refkey = friend.getRefKey(); - if (refkey != null) { - boolean found = false; - for (LinphoneContact contact : contacts) { - if (refkey.equals(contact.getAndroidId())) { - // Native matching contact found, link the friend to it - contact.setFriend(friend); - found = true; - break; + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc != null) { + for (LinphoneFriend friend : lc.getFriendList()) { + String refkey = friend.getRefKey(); + if (refkey != null) { + boolean found = false; + for (LinphoneContact contact : contacts) { + if (refkey.equals(contact.getAndroidId())) { + // Native matching contact found, link the friend to it + contact.setFriend(friend); + found = true; + break; + } } - } - if (!found) { - if (hasContactAccess) { - // If refkey != null and hasContactAccess but there isn't a native contact with this value, then this contact has been deleted. Let's do the same with the LinphoneFriend - LinphoneManager.getLc().removeFriend(friend); - } else { - // Refkey not null but no contact access => can't link it to native contact so display it on is own - LinphoneContact contact = new LinphoneContact(); - contact.setFriend(friend); - contacts.add(contact); + if (!found) { + if (hasContactAccess) { + // If refkey != null and hasContactAccess but there isn't a native contact with this value, then this contact has been deleted. Let's do the same with the LinphoneFriend + lc.removeFriend(friend); + } else { + // Refkey not null but no contact access => can't link it to native contact so display it on is own + LinphoneContact contact = new LinphoneContact(); + contact.setFriend(friend); + contacts.add(contact); + } } + } else { + // No refkey so it's a standalone contact + LinphoneContact contact = new LinphoneContact(); + contact.setFriend(friend); + contacts.add(contact); } - } else { - // No refkey so it's a standalone contact - LinphoneContact contact = new LinphoneContact(); - contact.setFriend(friend); - contacts.add(contact); } } @@ -364,4 +369,38 @@ public class ContactsManager extends ContentObserver { public String getString(int resourceID) { return context.getString(resourceID); } + + private Cursor getContactsCursor(ContentResolver cr) { + String req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE + + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL " + + " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL))"; + String[] projection = new String[] { Data.CONTACT_ID, Data.DISPLAY_NAME }; + String query = Data.DISPLAY_NAME + " IS NOT NULL AND (" + req + ")"; + + Cursor cursor = cr.query(Data.CONTENT_URI, projection, query, null, " lower(" + Data.DISPLAY_NAME + ") COLLATE UNICODE ASC"); + if (cursor == null) { + return cursor; + } + + MatrixCursor result = new MatrixCursor(cursor.getColumnNames()); + Set groupBy = new HashSet(); + while (cursor.moveToNext()) { + String name = cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME)); + if (!groupBy.contains(name)) { + groupBy.add(name); + Object[] newRow = new Object[cursor.getColumnCount()]; + + int contactID = cursor.getColumnIndex(Data.CONTACT_ID); + int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME); + + newRow[contactID] = cursor.getString(contactID); + newRow[displayName] = cursor.getString(displayName); + + result.addRow(newRow); + } + } + cursor.close(); + return result; + } } diff --git a/src/org/linphone/KeepAliveHandler.java b/src/org/linphone/KeepAliveHandler.java deleted file mode 100644 index 9812248f6..000000000 --- a/src/org/linphone/KeepAliveHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.linphone; -/* -KeepAliveHandler.java -Copyright (C) 2013 Belledonne Communications, Grenoble, France - -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 2 -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import org.linphone.core.LinphoneCoreFactory; -import org.linphone.mediastream.Log; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class KeepAliveHandler extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); - LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); - LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); - - Log.i("Keep alive handler invoked"); - if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) { - //first refresh registers - LinphoneManager.getLc().refreshRegisters(); - //make sure iterate will have enough time, device will not sleep until exit from this method - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - //Log.e("Cannot sleep for 2s", e); //TODO FIXME Crash since the log rework - } - } - } -} diff --git a/src/org/linphone/KeepAliveReceiver.java b/src/org/linphone/KeepAliveReceiver.java index 7c104f578..bc78137e4 100644 --- a/src/org/linphone/KeepAliveReceiver.java +++ b/src/org/linphone/KeepAliveReceiver.java @@ -18,12 +18,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.linphone; +import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCoreFactory; import org.linphone.mediastream.Log; +import android.app.AlarmManager; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; - +import android.os.SystemClock; /* * Purpose of this receiver is to disable keep alives when screen is off @@ -32,13 +36,37 @@ public class KeepAliveReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!LinphoneService.isReady()) { - Log.i("Keep alive broadcast received while Linphone service not ready"); return; } else { - if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) { - LinphoneManager.getLc().enableKeepAlive(true); - } else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) { - LinphoneManager.getLc().enableKeepAlive(false); + boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); + LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); + LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc == null) return; + + String action = intent.getAction(); + if (action == null) { + Log.i("[KeepAlive] Refresh registers"); + lc.refreshRegisters(); + //make sure iterate will have enough time, device will not sleep until exit from this method + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + Log.e("Cannot sleep for 2s", e); + } finally { + //make sure the application will at least wakes up every 10 mn + Intent newIntent = new Intent(context, KeepAliveReceiver.class); + PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, PendingIntent.FLAG_ONE_SHOT); + ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP + , SystemClock.elapsedRealtime() + 600000 + , keepAlivePendingIntent); + } + } else if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) { + Log.i("[KeepAlive] Screen is on, enable"); + lc.enableKeepAlive(true); + } else if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) { + Log.i("[KeepAlive] Screen is off, disable"); + lc.enableKeepAlive(false); } } } diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index ed0158aac..3736384aa 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -1166,6 +1166,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta checkAndRequestPermission(Manifest.permission.READ_CONTACTS, PERMISSIONS_REQUEST_CONTACTS); } + private boolean willContactsPermissionBeAsked() { + return LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.READ_CONTACTS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS); + } + public void checkAndRequestWriteContactsPermission() { checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0); } @@ -1274,6 +1278,9 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta ContactsManager.getInstance().enableContactsAccess(); ContactsManager.getInstance().fetchContactsAsync(); fetchedContactsOnce = true; + } else if (contacts != PackageManager.PERMISSION_GRANTED && !willContactsPermissionBeAsked()) { + ContactsManager.getInstance().fetchContactsAsync(); + fetchedContactsOnce = true; } else { checkAndRequestReadContactsPermission(); } diff --git a/src/org/linphone/LinphoneContact.java b/src/org/linphone/LinphoneContact.java index 1b350dd1a..6d7670f22 100644 --- a/src/org/linphone/LinphoneContact.java +++ b/src/org/linphone/LinphoneContact.java @@ -419,6 +419,7 @@ public class LinphoneContact implements Serializable, Comparable mPendingChatFileMessage; @@ -210,11 +206,8 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag private final String mErrorToneFile; private final String mUserCertificatePath; private ByteArrayInputStream mUploadingImageStream; - private Timer mTimer; - private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver(); - private void routeAudioToSpeakerHelper(boolean speakerOn) { Log.w("Routing audio to " + (speakerOn ? "speaker" : "earpiece") + ", disabling bluetooth audio route"); BluetoothManager.getInstance().disableBluetoothSCO(); @@ -661,11 +654,12 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag public void restartLinphoneCore() { destroyLinphoneCore(); startLibLinphone(mServiceContext); - - IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); - lFilter.addAction(Intent.ACTION_SCREEN_OFF); - mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter); - + /* + You cannot receive this through components declared in manifests, only + by explicitly registering for it with Context.registerReceiver(). This is a protected intent that can only + be sent by the system. + */ + mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter); sExited = false; } @@ -698,6 +692,32 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag Log.e(e, "Cannot start linphone"); } } + + private void initPushNotificationsService() { + try { + Class GCMRegistrar = Class.forName("com.google.android.gcm.GCMRegistrar"); + GCMRegistrar.getMethod("checkDevice", Context.class).invoke(null, mServiceContext); + try { + GCMRegistrar.getMethod("checkManifest", Context.class).invoke(null, mServiceContext); + } catch (IllegalStateException e) { + Log.e("[Push Notification] No receiver found", e); + } + final String regId = (String)GCMRegistrar.getMethod("getRegistrationId", Context.class).invoke(null, mServiceContext); + String newPushSenderID = mServiceContext.getString(R.string.push_sender_id); + String currentPushSenderID = LinphonePreferences.instance().getPushNotificationRegistrationID(); + if (regId.equals("") || currentPushSenderID == null || !currentPushSenderID.equals(newPushSenderID)) { + GCMRegistrar.getMethod("register", Context.class, String[].class).invoke(null, mServiceContext, new String[]{newPushSenderID}); + Log.i("[Push Notification] Storing current sender id = " + newPushSenderID); + } else { + Log.i("[Push Notification] Already registered with id = " + regId); + LinphonePreferences.instance().setPushNotificationRegistrationID(regId); + } + } catch (java.lang.UnsupportedOperationException e) { + Log.i("[Push Notification] Not activated"); + } catch (Exception e1) { + Log.i("[Push Notification] Assuming GCM jar is not provided."); + } + } private synchronized void initLiblinphone(LinphoneCore lc) throws LinphoneCoreException { mLc = lc; @@ -752,12 +772,18 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag mLc.migrateCallLogs(); if (mServiceContext.getResources().getBoolean(R.bool.enable_push_id)) { - Compatibility.initPushNotificationService(mServiceContext); + initPushNotificationsService(); } - IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); - lFilter.addAction(Intent.ACTION_SCREEN_OFF); - mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter); + /* + You cannot receive this through components declared in manifests, only + by explicitly registering for it with Context.registerReceiver(). This is a protected intent that can only + be sent by the system. + */ + mKeepAliveIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); + mKeepAliveIntentFilter.addAction(Intent.ACTION_SCREEN_OFF); + mKeepAliveReceiver = new KeepAliveReceiver(); + mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter); updateNetworkReachability(); @@ -1024,7 +1050,16 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag } return null; } - + + public void setAudioManagerInCallMode() { + if (mAudioManager.getMode() == AudioManager.MODE_IN_COMMUNICATION) { + Log.w("[AudioManager] already in MODE_IN_COMMUNICATION, skipping..."); + return; + } + Log.d("[AudioManager] Mode: MODE_IN_COMMUNICATION"); + mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + } + @SuppressLint("Wakelock") public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) { Log.i("New call state [",state,"]"); @@ -1060,7 +1095,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag if (state == State.Connected) { if (mLc.getCallsNb() == 1) { requestAudioFocus(); - Compatibility.setAudioManagerInCallMode(mAudioManager); + setAudioManagerInCallMode(); } if (Hacks.needSoftvolume()) { @@ -1070,7 +1105,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag } if (state == State.OutgoingEarlyMedia) { - Compatibility.setAudioManagerInCallMode(mAudioManager); + setAudioManagerInCallMode(); } if (state == State.CallReleased || state == State.Error) { @@ -1150,7 +1185,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag public void startEcCalibration(LinphoneCoreListener l) throws LinphoneCoreException { routeAudioToSpeaker(); - Compatibility.setAudioManagerInCallMode((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE)); + setAudioManagerInCallMode(); Log.i("Set audio mode on 'Voice Communication'"); int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL); int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL); @@ -1161,7 +1196,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag public int startEchoTester() throws LinphoneCoreException { routeAudioToSpeaker(); - Compatibility.setAudioManagerInCallMode((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE)); + setAudioManagerInCallMode(); Log.i("Set audio mode on 'Voice Communication'"); int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL); int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL); @@ -1368,93 +1403,10 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag mAudioManager.adjustStreamVolume(LINPHONE_VOLUME_STREAM, i < 0 ? AudioManager.ADJUST_LOWER : AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI); } - public static Boolean isProximitySensorNearby(final SensorEvent event) { - float threshold = 4.001f; // <= 4 cm is near - - final float distanceInCm = event.values[0]; - final float maxDistance = event.sensor.getMaximumRange(); - Log.d("Proximity sensor report [",distanceInCm,"] , for max range [",maxDistance,"]"); - - if (maxDistance <= threshold) { - // Case binary 0/1 and short sensors - threshold = maxDistance; - } - - return distanceInCm < threshold; - } - - private static boolean sLastProximitySensorValueNearby; - private static Set sProximityDependentActivities = new HashSet(); - private static SensorEventListener sProximitySensorListener = new SensorEventListener() { - @Override - public void onSensorChanged(SensorEvent event) { - if (event.timestamp == 0) return; //just ignoring for nexus 1 - sLastProximitySensorValueNearby = isProximitySensorNearby(event); - proximityNearbyChanged(); - } - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) {} - }; - - - private static void simulateProximitySensorNearby(Activity activity, boolean nearby) { - final Window window = activity.getWindow(); - WindowManager.LayoutParams params = window.getAttributes(); - View view = ((ViewGroup) window.getDecorView().findViewById(android.R.id.content)).getChildAt(0); - if (nearby) { - params.screenBrightness = 0.1f; - view.setVisibility(View.INVISIBLE); - Compatibility.hideNavigationBar(activity); - } else { - params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; - view.setVisibility(View.VISIBLE); - Compatibility.showNavigationBar(activity); - } - window.setAttributes(params); - } - - private static void proximityNearbyChanged() { - boolean nearby = sLastProximitySensorValueNearby; - for (Activity activity : sProximityDependentActivities) { - simulateProximitySensorNearby(activity, nearby); - } - } - - public static synchronized void startProximitySensorForActivity(Activity activity) { - if (sProximityDependentActivities.contains(activity)) { - Log.i("proximity sensor already active for " + activity.getLocalClassName()); - return; - } - if (sProximityDependentActivities.isEmpty()) { - SensorManager sm = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE); - Sensor s = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY); - if (s != null) { - sm.registerListener(sProximitySensorListener,s,SensorManager.SENSOR_DELAY_UI); - Log.i("Proximity sensor detected, registering"); - } - } else if (sLastProximitySensorValueNearby){ - simulateProximitySensorNearby(activity, true); - } - - sProximityDependentActivities.add(activity); - } - - public static synchronized void stopProximitySensorForActivity(Activity activity) { - sProximityDependentActivities.remove(activity); - simulateProximitySensorNearby(activity, false); - if (sProximityDependentActivities.isEmpty()) { - SensorManager sm = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE); - sm.unregisterListener(sProximitySensorListener); - sLastProximitySensorValueNearby = false; - } - } - - public static synchronized LinphoneCore getLcIfManagerNotDestroyedOrNull() { if (sExited || instance == null) { // Can occur if the UI thread play a posted event but in the meantime the LinphoneManager was destroyed // Ex: stop call and quickly terminate application. - Log.w("Trying to get linphone core while LinphoneManager already destroyed or not created"); return null; } return getLc(); diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 46c5fd742..813df0236 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -114,7 +114,6 @@ public final class LinphoneService extends Service { private Notification mCustomNotif; private int mMsgNotifCount; private PendingIntent mNotifContentIntent; - private PendingIntent mkeepAlivePendingIntent; private String mNotificationTitle; private boolean mDisableRegistrationStatus; private LinphoneCoreListenerBase mListener; @@ -287,12 +286,11 @@ public final class LinphoneService extends Service { } //make sure the application will at least wakes up every 10 mn - Intent intent = new Intent(this, KeepAliveHandler.class); - mkeepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); - ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP - , SystemClock.elapsedRealtime()+600000 - , 600000 - , mkeepAlivePendingIntent); + Intent intent = new Intent(this, KeepAliveReceiver.class); + PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); + ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP + , SystemClock.elapsedRealtime() + 600000 + , keepAlivePendingIntent); mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); } @@ -622,6 +620,7 @@ public final class LinphoneService extends Service { } instance = null; + getContentResolver().unregisterContentObserver(ContactsManager.getInstance()); LinphoneManager.destroy(); // Make sure our notification is gone. @@ -629,8 +628,6 @@ public final class LinphoneService extends Service { mNM.cancel(INCALL_NOTIF_ID); mNM.cancel(MESSAGE_NOTIF_ID); - ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).cancel(mkeepAlivePendingIntent); - getContentResolver().unregisterContentObserver(ContactsManager.getInstance()); super.onDestroy(); } diff --git a/src/org/linphone/LinphoneUtils.java b/src/org/linphone/LinphoneUtils.java index 510f7fdfa..76b8afcce 100644 --- a/src/org/linphone/LinphoneUtils.java +++ b/src/org/linphone/LinphoneUtils.java @@ -431,7 +431,7 @@ public final class LinphoneUtils { StringBuilder sb = new StringBuilder(); try { - p = Runtime.getRuntime().exec(new String[] { "logcat", "-d", "|", "grep", "`adb shell ps | grep org.linphone | cut -c10-15`" }); + p = Runtime.getRuntime().exec(new String[] { "logcat", "-d", "|", "grep", "`adb shell ps | grep " + context.getPackageName() + " | cut -c10-15`" }); br = new BufferedReader(new InputStreamReader(p.getInputStream()), 2048); String line; diff --git a/src/org/linphone/OpenGLESDisplay.java b/src/org/linphone/OpenGLESDisplay.java deleted file mode 100644 index 358667874..000000000 --- a/src/org/linphone/OpenGLESDisplay.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.linphone; - -public class OpenGLESDisplay { - public static native void init(int ptr, int width, int height); - public static native void render(int ptr); -} diff --git a/src/org/linphone/SettingsFragment.java b/src/org/linphone/SettingsFragment.java index b9683e1d4..9defc8318 100644 --- a/src/org/linphone/SettingsFragment.java +++ b/src/org/linphone/SettingsFragment.java @@ -35,8 +35,8 @@ import org.linphone.core.PayloadType; import org.linphone.mediastream.Log; import org.linphone.mediastream.Version; import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; -import org.linphone.tools.OpenH264DownloadHelper; import org.linphone.purchase.InAppPurchaseActivity; +import org.linphone.tools.OpenH264DownloadHelper; import org.linphone.ui.LedPreference; import org.linphone.ui.PreferencesListFragment; @@ -44,11 +44,14 @@ import android.app.AlertDialog; import android.app.FragmentManager; import android.content.DialogInterface; import android.Manifest; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.media.AudioManager; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.preference.CheckBoxPreference; @@ -59,6 +62,7 @@ import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; +import android.provider.Settings; /** * @author Sylvain Berfini @@ -713,7 +717,7 @@ public class SettingsFragment extends PreferencesListFragment { public boolean onPreferenceChange(Preference preference, Object newValue) { boolean enable = (Boolean) newValue; try { - if (enable && Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86") + if (enable && Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86") && pt.getMime().equals("H264") && !mCodecDownloader.isCodecFound()) { mCodecDownloader.setOpenH264HelperListener(LinphoneManager.getInstance().getOpenH264HelperListener()); mCodecDownloader.setUserData(0,LinphoneManager.getInstance().getContext()); @@ -721,18 +725,17 @@ public class SettingsFragment extends PreferencesListFragment { AlertDialog.Builder builder = new AlertDialog.Builder(LinphoneManager.getInstance().getContext()); builder.setCancelable(false); - AlertDialog.Builder show = builder.setMessage("Do you agree to download " - + mCodecDownloader.getLicenseMessage()).setPositiveButton("Yes", new DialogInterface.OnClickListener(){ + builder.setMessage("Do you agree to download " + mCodecDownloader.getLicenseMessage()).setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_POSITIVE) mCodecDownloader.downloadCodec(); } }); - builder.setNegativeButton("No", new DialogInterface.OnClickListener(){ + builder.setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEGATIVE){ + if (which == DialogInterface.BUTTON_NEGATIVE) { // Disable H264 } } @@ -1025,7 +1028,6 @@ public class SettingsFragment extends PreferencesListFragment { // Disable UPnP if ICE si enabled, or disable ICE if UPnP is enabled CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key)); CheckBoxPreference turn = (CheckBoxPreference) findPreference(getString(R.string.pref_turn_enable_key)); - CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); ice.setChecked(mPrefs.isIceEnabled()); turn.setChecked(mPrefs.isTurnEnabled()); @@ -1067,8 +1069,6 @@ public class SettingsFragment extends PreferencesListFragment { findPreference(getString(R.string.pref_ice_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); - boolean value = (Boolean) newValue; mPrefs.setIceEnabled((Boolean) newValue); return true; } @@ -1077,8 +1077,6 @@ public class SettingsFragment extends PreferencesListFragment { findPreference(getString(R.string.pref_turn_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); - boolean value = (Boolean) newValue; mPrefs.setTurnEnabled((Boolean) newValue); return true; } @@ -1087,7 +1085,6 @@ public class SettingsFragment extends PreferencesListFragment { findPreference(getString(R.string.pref_upnp_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key)); boolean value = (Boolean) newValue; mPrefs.setUpnpEnabled(value); return true; @@ -1197,6 +1194,24 @@ public class SettingsFragment extends PreferencesListFragment { return true; } }); + + findPreference(getString(R.string.pref_android_app_settings_key)).setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + synchronized (SettingsFragment.this) { + Context context = SettingsFragment.this.getActivity(); + Intent i = new Intent(); + i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + i.addCategory(Intent.CATEGORY_DEFAULT); + i.setData(Uri.parse("package:" + context.getPackageName())); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); + i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + context.startActivity(i); + } + return true; + } + }); findPreference(getString(R.string.pref_display_name_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override diff --git a/src/org/linphone/assistant/CodecDownloaderFragment.java b/src/org/linphone/assistant/CodecDownloaderFragment.java index 496dc3892..deb58390a 100644 --- a/src/org/linphone/assistant/CodecDownloaderFragment.java +++ b/src/org/linphone/assistant/CodecDownloaderFragment.java @@ -19,6 +19,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.core.LinphoneCoreException; +import org.linphone.core.OpenH264DownloadHelperListener; +import org.linphone.core.PayloadType; +import org.linphone.tools.OpenH264DownloadHelper; + import android.app.Fragment; import android.os.Bundle; import android.os.Handler; @@ -29,15 +36,6 @@ import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; -import org.linphone.LinphoneActivity; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.LinphoneCoreFactory; -import org.linphone.core.OpenH264DownloadHelperListener; -import org.linphone.core.LinphoneCoreException; -import org.linphone.core.PayloadType; -import org.linphone.tools.OpenH264DownloadHelper; - /** * @author Erwan CROZE */ diff --git a/src/org/linphone/assistant/LinphoneLoginFragment.java b/src/org/linphone/assistant/LinphoneLoginFragment.java index e606e00c5..e889336b1 100644 --- a/src/org/linphone/assistant/LinphoneLoginFragment.java +++ b/src/org/linphone/assistant/LinphoneLoginFragment.java @@ -18,11 +18,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import org.linphone.R; +import org.linphone.compatibility.Compatibility; import android.app.Fragment; import android.os.Bundle; import android.text.Editable; -import android.text.Html; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; @@ -53,7 +53,7 @@ public class LinphoneLoginFragment extends Fragment implements OnClickListener, password = (EditText) view.findViewById(R.id.assistant_password); password.addTextChangedListener(this); forgotPassword = (TextView) view.findViewById(R.id.forgot_password); - forgotPassword.setText(Html.fromHtml(""+ getString(R.string.forgot_password) + "")); + forgotPassword.setText(Compatibility.fromHtml(""+ getString(R.string.forgot_password) + "")); forgotPassword.setMovementMethod(LinkMovementMethod.getInstance()); displayName = (EditText) view.findViewById(R.id.assistant_display_name); apply = (Button) view.findViewById(R.id.assistant_apply); diff --git a/src/org/linphone/compatibility/ApiEightPlus.java b/src/org/linphone/compatibility/ApiEightPlus.java deleted file mode 100644 index 30f5a78fb..000000000 --- a/src/org/linphone/compatibility/ApiEightPlus.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.linphone.compatibility; - -import org.linphone.LinphonePreferences; -import org.linphone.R; -import org.linphone.mediastream.Log; - -import android.annotation.TargetApi; -import android.content.Context; -import android.media.AudioManager; - -/* -ApiEightPlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France - -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 2 -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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/** - * @author Sylvain Berfini - */ - -@TargetApi(8) -public class ApiEightPlus { - - public static void initPushNotificationService(Context context) { - try { - Class GCMRegistrar = Class.forName("com.google.android.gcm.GCMRegistrar"); - // Starting the push notification service - GCMRegistrar.getMethod("checkDevice", Context.class).invoke(null, context); - try { - GCMRegistrar.getMethod("checkManifest", Context.class).invoke(null, context); - } catch (IllegalStateException e){ - Log.e("Push notification: No receiver found",e); - } - final String regId = (String)GCMRegistrar.getMethod("getRegistrationId", Context.class).invoke(null, context); - String newPushSenderID = context.getString(R.string.push_sender_id); - String currentPushSenderID = LinphonePreferences.instance().getPushNotificationRegistrationID(); - if (regId.equals("") || currentPushSenderID == null || !currentPushSenderID.equals(newPushSenderID)) { - GCMRegistrar.getMethod("register", Context.class, String[].class).invoke(null, context, new String[]{newPushSenderID}); - Log.d("Push Notification: storing current sender id = " + newPushSenderID); - } else { - Log.d("Push Notification: already registered with id = " + regId); - LinphonePreferences.instance().setPushNotificationRegistrationID(regId); - } - } catch (java.lang.UnsupportedOperationException e) { - Log.i("Push Notification: not activated"); - } catch (Exception e1) { - //assume the jar is not provided - Log.i("Push Notification: assuming GCM jar is not provided."); - } - } - - @SuppressWarnings("deprecation") - public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() { - return AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED; - } -} \ No newline at end of file diff --git a/src/org/linphone/compatibility/ApiElevenPlus.java b/src/org/linphone/compatibility/ApiElevenPlus.java index d763c5221..7b30e5581 100644 --- a/src/org/linphone/compatibility/ApiElevenPlus.java +++ b/src/org/linphone/compatibility/ApiElevenPlus.java @@ -3,19 +3,15 @@ package org.linphone.compatibility; import java.util.ArrayList; import org.linphone.R; -import org.linphone.mediastream.Log; import android.annotation.TargetApi; import android.app.Notification; import android.app.PendingIntent; -import android.content.ClipData; -import android.content.ClipboardManager; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; -import android.media.AudioManager; import android.net.Uri; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.SipAddress; @@ -119,21 +115,6 @@ public class ApiElevenPlus { return notif; } - - public static void copyTextToClipboard(Context context, String msg) { - ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = android.content.ClipData.newPlainText("Message", msg); - clipboard.setPrimaryClip(clip); - } - - public static void setAudioManagerInCallMode(AudioManager manager) { - if (manager.getMode() == AudioManager.MODE_IN_COMMUNICATION) { - Log.w("---AudioManager: already in MODE_IN_COMMUNICATION, skipping..."); - return; - } - Log.d("---AudioManager: set mode to MODE_IN_COMMUNICATION"); - manager.setMode(AudioManager.MODE_IN_COMMUNICATION); - } public static Intent prepareAddContactIntent(String displayName, String sipUri) { Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI); diff --git a/src/org/linphone/compatibility/ApiFivePlus.java b/src/org/linphone/compatibility/ApiFivePlus.java deleted file mode 100644 index 7adc28c1e..000000000 --- a/src/org/linphone/compatibility/ApiFivePlus.java +++ /dev/null @@ -1,406 +0,0 @@ -package org.linphone.compatibility; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.linphone.LinphoneContact; -import org.linphone.R; -import org.linphone.core.LinphoneAddress; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.ContentProviderOperation; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.media.AudioManager; -import android.net.Uri; -import android.preference.CheckBoxPreference; -import android.preference.Preference; -import android.provider.ContactsContract; -import android.provider.ContactsContract.CommonDataKinds; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.Data; -import android.support.v4.app.NotificationCompat; -import android.text.ClipboardManager; -import android.text.TextUtils; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; - -/* -ApiFivePlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France - -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 2 -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -/** - * @author Sylvain Berfini - */ -@SuppressWarnings("deprecation") -@TargetApi(5) -public class ApiFivePlus { - public static void overridePendingTransition(Activity activity, int idAnimIn, int idAnimOut) { - activity.overridePendingTransition(idAnimIn, idAnimOut); - } - - public static Intent prepareAddContactIntent(String displayName, String sipUri) { - Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI); - intent.putExtra(ContactsContract.Intents.Insert.NAME, displayName); - - // VoIP field not available, we store the address in the IM field - intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, sipUri); - intent.putExtra(ContactsContract.Intents.Insert.IM_PROTOCOL, "sip"); - - return intent; - } - - public static Intent prepareEditContactIntent(int id) { - Intent intent = new Intent(Intent.ACTION_EDIT, Contacts.CONTENT_URI); - Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id); - intent.setData(contactUri); - - return intent; - } - - public static Intent prepareEditContactIntentWithSipAddress(int id, String sipUri) { - Intent intent = new Intent(Intent.ACTION_EDIT, Contacts.CONTENT_URI); - Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id); - intent.setData(contactUri); - - // VoIP field not available, we store the address in the IM field - intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, sipUri); - intent.putExtra(ContactsContract.Intents.Insert.IM_PROTOCOL, "sip"); - - return intent; - } - - public static List extractContactNumbersAndAddresses(String id, ContentResolver cr) { - List list = new ArrayList(); - - Uri uri = Data.CONTENT_URI; - String[] projection = {ContactsContract.CommonDataKinds.Im.DATA}; - - // IM addresses - String selection = new StringBuilder() - .append(Data.CONTACT_ID).append(" = ? AND ") - .append(Data.MIMETYPE).append(" = '") - .append(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) - .append("' AND lower(") - .append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL) - .append(") = 'sip'") - .toString(); - Cursor c = cr.query(uri, projection, selection, new String[]{id}, null); - if (c != null) { - int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA); - while (c.moveToNext()) { - list.add("sip:" + c.getString(nbId)); - } - c.close(); - } - - // Phone Numbers - c = cr.query(Phone.CONTENT_URI, new String[]{Phone.NUMBER}, Phone.CONTACT_ID + " = " + id, null, null); - if (c != null) { - while (c.moveToNext()) { - String number = c.getString(c.getColumnIndex(Phone.NUMBER)); - list.add(number); - } - c.close(); - } - - return list; - } - - public static Cursor getContactsCursor(ContentResolver cr, List ids) { - String req = Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE - + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL"; - - req += " OR (" + Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE - + "' AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip')"; - - if(ids != null){ - String s = TextUtils.join(",", ids); - req += " OR (" + Data.CONTACT_ID + " IN (" + s + "))"; - } - - return getGeneralContactCursor(cr, req, true); - } - - public static Cursor getSIPContactsCursor(ContentResolver cr, List ids) { - String req = null; - req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE - + "' AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip'"; - - if(ids != null){ - String s = TextUtils.join(",", ids); - req += " OR (" + Data.CONTACT_ID + " IN (" + s + "))"; - } - - return getGeneralContactCursor(cr, req, true); - } - - private static Cursor getSIPContactCursor(ContentResolver cr, String id) { - String req = null; - req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE - + " AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip' AND " - + android.provider.ContactsContract.CommonDataKinds.Im.DATA + " LIKE '" + id + "'"; - - return getGeneralContactCursor(cr, req, false); - } - - public static Cursor getGeneralContactCursor(ContentResolver cr, String select, boolean shouldGroupBy) { - String[] projection = new String[] { Data.CONTACT_ID, Data.DISPLAY_NAME }; - String query; - - query = Data.DISPLAY_NAME + " IS NOT NULL AND (" + select + ")"; - - Cursor cursor = cr.query(Data.CONTENT_URI, projection, query, null, " lower(" + Data.DISPLAY_NAME + ") COLLATE UNICODE ASC"); - - if (!shouldGroupBy || cursor == null) { - return cursor; - } - - MatrixCursor result = new MatrixCursor(cursor.getColumnNames()); - Set groupBy = new HashSet(); - while (cursor.moveToNext()) { - String name = cursor.getString(getCursorDisplayNameColumnIndex(cursor)); - if (!groupBy.contains(name)) { - groupBy.add(name); - Object[] newRow = new Object[cursor.getColumnCount()]; - - int contactID = cursor.getColumnIndex(Data.CONTACT_ID); - int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME); - - newRow[contactID] = cursor.getString(contactID); - newRow[displayName] = cursor.getString(displayName); - - result.addRow(newRow); - } - } - cursor.close(); - return result; - } - - public static int getCursorDisplayNameColumnIndex(Cursor cursor) { - return cursor.getColumnIndex(Data.DISPLAY_NAME); - } - - public static LinphoneContact getContact(ContentResolver cr, Cursor cursor, int position) { - try { - if(cursor != null) { - cursor.moveToFirst(); - boolean success = cursor.move(position); - if (!success) - return null; - - String id = cursor.getString(cursor.getColumnIndex(Data.CONTACT_ID)); - String name = getContactDisplayName(cursor); - Uri thumbnail = getContactPictureUri(id); - Uri photo = getContactPhotoUri(id); - InputStream input = getContactPictureInputStream(cr, id); - - LinphoneContact contact = new LinphoneContact(); - contact.setAndroidId(id); - contact.setFullName(name); - if (input != null) { - contact.setPhotoUri(photo); - contact.setThumbnailUri(thumbnail); - } - - return contact; - } else { - return null; - } - } catch (Exception e) { - - } - return null; - } - - public static InputStream getContactPictureInputStream(ContentResolver cr, String id) { - Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id)); - return Contacts.openContactPhotoInputStream(cr, person); - } - - private static String getContactDisplayName(Cursor cursor) { - return cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME)); - } - - private static Uri getContactPictureUri(String id) { - Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id)); - return Uri.withAppendedPath(person, Contacts.Photo.CONTENT_DIRECTORY); - } - - private static Uri getContactPhotoUri(String id) { - Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id)); - return Uri.withAppendedPath(person, Contacts.Photo.DISPLAY_PHOTO); - } - - public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) { - String username = address.getUserName(); - String domain = address.getDomain(); - String sipUri = username + "@" + domain; - - Cursor cursor = getSIPContactCursor(cr, sipUri); - if(cursor != null) { - LinphoneContact contact = getContact(cr, cursor, 0); - if (contact != null && contact.getNumbersOrAddresses().contains(sipUri)) { - address.setDisplayName(contact.getFullName()); - cursor.close(); - return contact.getPhotoUri(); - } - cursor.close(); - } - return null; - } - - public static String refreshContactName(ContentResolver cr, String id) { - Cursor cursor = getGeneralContactCursor(cr, Data.CONTACT_ID + " = '" + id + "'", false); - if (cursor != null && cursor.moveToFirst()) { - String contactDisplayName = getContactDisplayName(cursor); - cursor.close(); - return contactDisplayName; - } - return null; - } - - public static Notification createMessageNotification(Context context, String title, String msg, PendingIntent intent) { - Notification notif = new Notification(); - notif.icon = R.drawable.topbar_chat_notification; - notif.iconLevel = 0; - notif.when = System.currentTimeMillis(); - notif.flags &= Notification.FLAG_ONGOING_EVENT; - - notif.defaults |= Notification.DEFAULT_VIBRATE; - notif.defaults |= Notification.DEFAULT_SOUND; - notif.defaults |= Notification.DEFAULT_LIGHTS; - - return notif; - } - - public static Notification createInCallNotification(Context context, String title, String msg, int iconID, PendingIntent intent) { - NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context) - .setSmallIcon(iconID) - .setContentTitle(title) - .setContentText(msg) - .setContentIntent(intent); - - return notifBuilder.build(); - } - - public static void setPreferenceChecked(Preference preference, boolean checked) { - ((CheckBoxPreference) preference).setChecked(checked); - } - - public static boolean isPreferenceChecked(Preference preference) { - return ((CheckBoxPreference) preference).isChecked(); - } - - public static void copyTextToClipboard(Context context, String msg) { - ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(msg); - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Im.DATA, sipAddress) - .withValue(ContactsContract.CommonDataKinds.Im.TYPE, ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM) - .withValue(ContactsContract.CommonDataKinds.Im.LABEL, context.getString(R.string.addressbook_label)) - .build() - ); - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Im.DATA, sipAddress) - .withValue(ContactsContract.CommonDataKinds.Im.TYPE, ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM) - .withValue(ContactsContract.CommonDataKinds.Im.LABEL, context.getString(R.string.addressbook_label)) - .build() - ); - } - - public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.Im.DATA + "=?"; - String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; - - ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Im.DATA, newSipAddress) - .build() - ); - } - - public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.Im.DATA + "=?"; - String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; - - ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .build() - ); - } - - public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { - viewTreeObserver.removeGlobalOnLayoutListener(keyboardListener); - } - - public static void setAudioManagerInCallMode(AudioManager manager) { - /* Do not use MODE_IN_CALL, because it is reserved to GSM. This is causing conflicts on audio system resulting in silenced audio.*/ - //manager.setMode(AudioManager.MODE_IN_CALL); - } - - public static Notification createNotification(Context context, String title, String message, int icon, int level, PendingIntent intent, boolean isOngoingEvent) { - NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context) - .setSmallIcon(icon, level) - .setContentTitle(title) - .setContentText(message) - .setContentIntent(intent); - - return notifBuilder.build(); - } - - public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { - NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context) - .setSmallIcon(R.drawable.linphone_logo) - .setContentTitle(title) - .setContentText(text) - .setContentIntent(intent); - - Notification notif = notifBuilder.build(); - notif.defaults |= Notification.DEFAULT_VIBRATE; - notif.defaults |= Notification.DEFAULT_SOUND; - notif.defaults |= Notification.DEFAULT_LIGHTS; - - return notif; - } -} diff --git a/src/org/linphone/compatibility/ApiFourteenPlus.java b/src/org/linphone/compatibility/ApiFourteenPlus.java deleted file mode 100644 index df480ad78..000000000 --- a/src/org/linphone/compatibility/ApiFourteenPlus.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.linphone.compatibility; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.media.AudioManager; -import android.preference.Preference; -import android.preference.TwoStatePreference; -import android.view.View; - -/* -ApiFourteenPlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France - -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 2 -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -/** - * @author Sylvain Berfini - */ -@TargetApi(14) -public class ApiFourteenPlus { - - public static void setPreferenceChecked(Preference preference, boolean checked) { - ((TwoStatePreference) preference).setChecked(checked); - } - - public static boolean isPreferenceChecked(Preference preference) { - return ((TwoStatePreference) preference).isChecked(); - } - - public static void hideNavigationBar(Activity activity) { - activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); - } - - public static void showNavigationBar(Activity activity) { - activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); - } - - public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() { - return AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED; - } -} diff --git a/src/org/linphone/compatibility/ApiNinePlus.java b/src/org/linphone/compatibility/ApiNinePlus.java deleted file mode 100644 index 313ee4d1a..000000000 --- a/src/org/linphone/compatibility/ApiNinePlus.java +++ /dev/null @@ -1,195 +0,0 @@ -package org.linphone.compatibility; - -import java.util.ArrayList; -import java.util.List; - -import org.linphone.LinphoneContact; -import org.linphone.R; -import org.linphone.core.LinphoneAddress; - -import android.annotation.TargetApi; -import android.content.ContentProviderOperation; -import android.content.ContentResolver; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.provider.ContactsContract; -import android.provider.ContactsContract.CommonDataKinds; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.Data; -import android.text.TextUtils; - -/* -ApiNinePlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France - -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 2 -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -/** - * @author Sylvain Berfini - */ -@TargetApi(9) -public class ApiNinePlus { - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.DATA, sipAddress) - .withValue(CommonDataKinds.SipAddress.TYPE, CommonDataKinds.SipAddress.TYPE_CUSTOM) - .withValue(CommonDataKinds.SipAddress.LABEL, context.getString(R.string.addressbook_label)) - .build() - ); - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID) - .withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.DATA, sipAddress) - .withValue(CommonDataKinds.SipAddress.TYPE, CommonDataKinds.SipAddress.TYPE_CUSTOM) - .withValue(CommonDataKinds.SipAddress.LABEL, context.getString(R.string.addressbook_label)) - .build() - ); - } - - public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?"; - String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; - - ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newSipAddress) - .build() - ); - } - - public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=? "; - String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; - - ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .build() - ); - } - - public static List extractContactNumbersAndAddresses(String id, ContentResolver cr) { - List list = new ArrayList(); - - Uri uri = Data.CONTENT_URI; - String[] projection; - - // SIP addresses - String selection2 = new StringBuilder() - .append(Data.CONTACT_ID) - .append(" = ? AND ") - .append(Data.MIMETYPE) - .append(" = '") - .append(ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .append("'") - .toString(); - projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS}; - Cursor c = cr.query(uri, projection, selection2, new String[]{id}, null); - if (c != null) { - int nbid = c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS); - while (c.moveToNext()) { - list.add("sip:" + c.getString(nbid)); - } - c.close(); - } - - // Phone Numbers - c = cr.query(Phone.CONTENT_URI, new String[] { Phone.NUMBER }, Phone.CONTACT_ID + " = " + id, null, null); - if (c != null) { - while (c.moveToNext()) { - String number = c.getString(c.getColumnIndex(Phone.NUMBER)); - list.add(number); - } - c.close(); - } - - return list; - } - - public static Cursor getContactsCursor(ContentResolver cr, String search, List ids) { - String req; - if(ids != null && ids.size() > 0) { - req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE - + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL " - + " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE - + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL)" - + " OR (" + Data.CONTACT_ID + " IN (" + TextUtils.join(" , ", ids) + ")))"; - } else { - req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE - + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL " - + " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE - + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL))"; - } - - if (search != null) { - req += " AND " + Data.DISPLAY_NAME + " LIKE '%" + search + "%'"; - } - - return ApiFivePlus.getGeneralContactCursor(cr, req, true); - } - - public static Cursor getSIPContactsCursor(ContentResolver cr, String search, List ids) { - - String req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE - + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL) "; - - if(ids != null && ids.size() > 0) { - req += " OR (" + Data.CONTACT_ID + " IN (" + TextUtils.join(" , ", ids) + "))"; - } - - if (search != null) { - req += " AND " + Data.DISPLAY_NAME + " LIKE '%" + search + "%'"; - } - - return ApiFivePlus.getGeneralContactCursor(cr, req, true); - } - - private static Cursor getSIPContactCursor(ContentResolver cr, String id) { - String req = null; - req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE - + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " LIKE '" + id + "'"; - - return ApiFivePlus.getGeneralContactCursor(cr, req, false); - } - - public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) { - String username = address.getUserName(); - String domain = address.getDomain(); - String sipUri = username + "@" + domain; - - Cursor cursor = getSIPContactCursor(cr, sipUri); - LinphoneContact contact = ApiFivePlus.getContact(cr, cursor, 0); - if (contact != null && contact.getNumbersOrAddresses().contains(sipUri)) { - address.setDisplayName(contact.getFullName()); - cursor.close(); - return contact.getPhotoUri(); - } - - cursor.close(); - return null; - } -} diff --git a/src/org/linphone/compatibility/ApiSixteenPlus.java b/src/org/linphone/compatibility/ApiSixteenPlus.java index 148756063..f7fff7d2f 100644 --- a/src/org/linphone/compatibility/ApiSixteenPlus.java +++ b/src/org/linphone/compatibility/ApiSixteenPlus.java @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @TargetApi(16) public class ApiSixteenPlus { + @SuppressWarnings("deprecation") public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { diff --git a/src/org/linphone/compatibility/ApiTwentyOnePlus.java b/src/org/linphone/compatibility/ApiTwentyOnePlus.java index b75b72ef2..66d0a37b6 100644 --- a/src/org/linphone/compatibility/ApiTwentyOnePlus.java +++ b/src/org/linphone/compatibility/ApiTwentyOnePlus.java @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @TargetApi(21) public class ApiTwentyOnePlus { + @SuppressWarnings("deprecation") public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index 10846675d..cad5a21a0 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -17,191 +17,54 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import org.linphone.LinphoneContact; -import org.linphone.core.LinphoneAddress; import org.linphone.mediastream.Version; -import android.app.Activity; import android.app.Notification; import android.app.PendingIntent; -import android.content.ContentProviderOperation; -import android.content.ContentResolver; import android.content.Context; -import android.content.Intent; -import android.database.Cursor; import android.graphics.Bitmap; -import android.media.AudioManager; -import android.net.Uri; import android.os.PowerManager; -import android.preference.Preference; import android.provider.Settings; +import android.text.Html; +import android.text.Spanned; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; /** * @author Sylvain Berfini */ public class Compatibility { - public static void overridePendingTransition(Activity activity, int idAnimIn, int idAnimOut) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - ApiFivePlus.overridePendingTransition(activity, idAnimIn, idAnimOut); - } - } - - public static Intent prepareAddContactIntent(String displayName, String sipUri) { - if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - return ApiElevenPlus.prepareAddContactIntent(displayName, sipUri); - } else { - return ApiFivePlus.prepareAddContactIntent(displayName, sipUri); - } - } - - public static Intent prepareEditContactIntent(int id) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.prepareEditContactIntent(id); - } - return null; - } - - public static Intent prepareEditContactIntentWithSipAddress(int id, String sipAddress) { - if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - return ApiElevenPlus.prepareEditContactIntentWithSipAddress(id, sipAddress); - } else { - return ApiFivePlus.prepareEditContactIntent(id); - } - } - - public static List extractContactNumbersAndAddresses(String id, ContentResolver cr) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.extractContactNumbersAndAddresses(id, cr); - } else { - return ApiFivePlus.extractContactNumbersAndAddresses(id, cr); - } - } - - public static List extractContactImAddresses(String id, ContentResolver cr) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiFivePlus.extractContactNumbersAndAddresses(id, cr); - } else { - return null; - } - } - - public static Cursor getContactsCursor(ContentResolver cr, List contactsId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.getContactsCursor(cr, null, contactsId); - } else { - return ApiFivePlus.getContactsCursor(cr, contactsId); - } - } - - public static Cursor getContactsCursor(ContentResolver cr, String search, List contactsId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.getContactsCursor(cr, search, contactsId); - } else { - return ApiFivePlus.getContactsCursor(cr, contactsId); - } - } - - public static Cursor getSIPContactsCursor(ContentResolver cr, List contactsId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.getSIPContactsCursor(cr, null, contactsId); - } else { - return ApiFivePlus.getSIPContactsCursor(cr, contactsId); - } - } - - public static Cursor getSIPContactsCursor(ContentResolver cr, String search, List contactsId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.getSIPContactsCursor(cr, search, contactsId); - } else { - return ApiFivePlus.getSIPContactsCursor(cr, contactsId); - } - } - - public static Cursor getImContactsCursor(ContentResolver cr) { - return ApiFivePlus.getSIPContactsCursor(cr,null); - } - - public static int getCursorDisplayNameColumnIndex(Cursor cursor) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.getCursorDisplayNameColumnIndex(cursor); - } - return -1; - } - - public static LinphoneContact getContact(ContentResolver cr, Cursor cursor, int position) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.getContact(cr, cursor, position); - } - return null; - } - - public static InputStream getContactPictureInputStream(ContentResolver cr, String id) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.getContactPictureInputStream(cr, id); - } - return null; - } - - public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.findUriPictureOfContactAndSetDisplayName(address, cr); - } else { - return ApiFivePlus.findUriPictureOfContactAndSetDisplayName(address, cr); - } - } - public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { Notification notif = null; - if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { return ApiTwentyOnePlus.createSimpleNotification(context, title, text, intent); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { notif = ApiSixteenPlus.createSimpleNotification(context, title, text, intent); - } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent); } else { - notif = ApiFivePlus.createSimpleNotification(context, title, text, intent); + notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent); } return notif; } public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { - Notification notif = null; - String title; - if (msgCount == 1) { - title = "Unread message from %s".replace("%s", msgSender); - } else { - title = "%i unread messages".replace("%i", String.valueOf(msgCount)); - } - + Notification notif = null; if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { return ApiTwentyOnePlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { notif = ApiSixteenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); - } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - notif = ApiElevenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); } else { - notif = ApiFivePlus.createMessageNotification(context, title, msg, intent); + notif = ApiElevenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); } return notif; } public static Notification createInCallNotification(Context context, String title, String msg, int iconID, Bitmap contactIcon, String contactName, PendingIntent intent) { Notification notif = null; - if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { return ApiTwentyOnePlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { notif = ApiSixteenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); - } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - notif = ApiElevenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); } else { - notif = ApiFivePlus.createInCallNotification(context, title, msg, iconID, intent); + notif = ApiElevenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); } return notif; } @@ -211,20 +74,11 @@ public class Compatibility { return ApiTwentyOnePlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { return ApiSixteenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority); - } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - return ApiElevenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent); } else { - return ApiFivePlus.createNotification(context, title, message, icon, iconLevel, intent, isOngoingEvent); + return ApiElevenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent); } } - public static String refreshContactName(ContentResolver cr, String id) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.refreshContactName(cr, id); - } - return null; - } - public static CompatibilityScaleGestureDetector getScaleGestureDetector(Context context, CompatibilityScaleGestureListener listener) { if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) { CompatibilityScaleGestureDetector csgd = new CompatibilityScaleGestureDetector(context); @@ -233,109 +87,13 @@ public class Compatibility { } return null; } - - - public static void setPreferenceChecked(Preference preference, boolean checked) { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - ApiFourteenPlus.setPreferenceChecked(preference, checked); - } else { - ApiFivePlus.setPreferenceChecked(preference, checked); - } - } - - public static boolean isPreferenceChecked(Preference preference) { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - return ApiFourteenPlus.isPreferenceChecked(preference); - } else { - return ApiFivePlus.isPreferenceChecked(preference); - } - } - - public static void initPushNotificationService(Context context) { - if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) { - ApiEightPlus.initPushNotificationService(context); - } - } - - public static void copyTextToClipboard(Context context, String msg) { - if(Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - ApiElevenPlus.copyTextToClipboard(context, msg); - } else { - ApiFivePlus.copyTextToClipboard(context, msg); - } - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.addSipAddressToContact(context, ops, sipAddress); - } else { - ApiFivePlus.addSipAddressToContact(context, ops, sipAddress); - } - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.addSipAddressToContact(context, ops, sipAddress, rawContactID); - } else { - ApiFivePlus.addSipAddressToContact(context, ops, sipAddress, rawContactID); - } - } - - public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.updateSipAddressForContact(ops, oldSipAddress, newSipAddress, contactID); - } else { - ApiFivePlus.updateSipAddressForContact(ops, oldSipAddress, newSipAddress, contactID); - } - } - - public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); - } else { - ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); - } - } - - public static void deleteImAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { - ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); - } + @SuppressWarnings("deprecation") public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener); } else { - ApiFivePlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener); - } - } - - public static void hideNavigationBar(Activity activity) - { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - ApiFourteenPlus.hideNavigationBar(activity); - } - } - - public static void showNavigationBar(Activity activity) - { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - ApiFourteenPlus.showNavigationBar(activity); - } - } - - public static void setAudioManagerInCallMode(AudioManager manager) { - if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - ApiElevenPlus.setAudioManagerInCallMode(manager); - } else { - ApiFivePlus.setAudioManagerInCallMode(manager); - } - } - - public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - return ApiFourteenPlus.getAudioManagerEventForBluetoothConnectionStateChangedEvent(); - } else { - return ApiEightPlus.getAudioManagerEventForBluetoothConnectionStateChangedEvent(); + viewTreeObserver.removeGlobalOnLayoutListener(keyboardListener); } } @@ -354,4 +112,12 @@ public class Compatibility { return pm.isScreenOn(); } } + + @SuppressWarnings("deprecation") + public static Spanned fromHtml(String text) { + /*if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) { + return Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY); + }*/ + return Html.fromHtml(text); + } } diff --git a/src/org/linphone/gcm/GCMService.java b/src/org/linphone/gcm/GCMService.java index ebeb8f7f6..ebfc1273f 100644 --- a/src/org/linphone/gcm/GCMService.java +++ b/src/org/linphone/gcm/GCMService.java @@ -53,13 +53,13 @@ public class GCMService extends GCMBaseIntentService { @Override protected void onError(Context context, String errorId) { initLogger(context); - Log.e("Error while registering push notification : " + errorId); + Log.e("[Push Notification] Error while registering: " + errorId); } @Override protected void onMessage(Context context, Intent intent) { initLogger(context); - Log.d("Push notification received"); + Log.d("[Push Notification] Received"); if (!LinphoneService.isReady()) { startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class)); @@ -79,7 +79,7 @@ public class GCMService extends GCMBaseIntentService { @Override protected void onRegistered(Context context, String regId) { initLogger(context); - Log.d("Registered push notification : " + regId); + Log.d("[Push Notification] Registered: " + regId); LinphonePreferences.instance().setPushNotificationRegistrationID(regId); } @@ -87,7 +87,7 @@ public class GCMService extends GCMBaseIntentService { @Override protected void onUnregistered(Context context, String regId) { initLogger(context); - Log.w("Unregistered push notification : " + regId); + Log.w("[Push Notification] Unregistered: " + regId); LinphonePreferences.instance().setPushNotificationRegistrationID(null); } diff --git a/src/org/linphone/tutorials/TutorialCardDavSync.java b/src/org/linphone/tutorials/TutorialCardDavSync.java index 2ef341bdd..efcd4bd0d 100644 --- a/src/org/linphone/tutorials/TutorialCardDavSync.java +++ b/src/org/linphone/tutorials/TutorialCardDavSync.java @@ -162,8 +162,7 @@ public class TutorialCardDavSync extends Activity implements OnClickListener, Li } @Override - public void onLinphoneFriendSyncStatusChanged(LinphoneFriendList list, - org.linphone.core.LinphoneFriendList.State status, String message) { + public void onLinphoneFriendSyncStatusChanged(LinphoneFriendList list, LinphoneFriendList.State status, String message) { // TODO Auto-generated method stub String msg = "Sync status changed: " + status.toString() + " (" + message + ")"; myLog(msg); diff --git a/src/org/linphone/ui/BubbleChat.java b/src/org/linphone/ui/BubbleChat.java index d65709eec..47a97e27f 100644 --- a/src/org/linphone/ui/BubbleChat.java +++ b/src/org/linphone/ui/BubbleChat.java @@ -31,6 +31,7 @@ import org.linphone.LinphoneContact; import org.linphone.LinphoneManager; import org.linphone.LinphoneUtils; import org.linphone.R; +import org.linphone.compatibility.Compatibility; import org.linphone.core.LinphoneBuffer; import org.linphone.core.LinphoneChatMessage; import org.linphone.core.LinphoneChatMessage.State; @@ -52,7 +53,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Environment; import android.provider.MediaStore; -import android.text.Html; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -312,7 +312,7 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen text = text.replaceFirst(link, "" + linkWithoutScheme + ""); } - return Html.fromHtml(text); + return Compatibility.fromHtml(text); } public String getTextMessage() { diff --git a/submodules/bctoolbox b/submodules/bctoolbox index 9daabd3db..921a21332 160000 --- a/submodules/bctoolbox +++ b/submodules/bctoolbox @@ -1 +1 @@ -Subproject commit 9daabd3dbfc72d6799f6bd54474a8f262e6716f2 +Subproject commit 921a21332c327ae99900267950be0bfd2d7c6126 diff --git a/submodules/belle-sip b/submodules/belle-sip index 086bb16bd..b553f58c3 160000 --- a/submodules/belle-sip +++ b/submodules/belle-sip @@ -1 +1 @@ -Subproject commit 086bb16bd79180265136ed9d4a89661049c95016 +Subproject commit b553f58c3f23633b9c183af5784b2170b6b4aa91 diff --git a/submodules/cmake-builder b/submodules/cmake-builder index 6d4281181..f4eac4803 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit 6d4281181addb913e851622e6d9b04d093c869d4 +Subproject commit f4eac4803eee43de3efa96ecca9450ba4f2bc7dc diff --git a/submodules/linphone b/submodules/linphone index 976f38cc0..6f1e96c8f 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 976f38cc0865e106a27b6f74bdfde0fb368624b7 +Subproject commit 6f1e96c8f60576fb1cfe9750612f9fdb7c134c54 diff --git a/tests/custom_rules.xml b/tests/custom_rules.xml index 87abcd905..5e7d620df 100644 --- a/tests/custom_rules.xml +++ b/tests/custom_rules.xml @@ -40,7 +40,7 @@ - +