diff --git a/CHANGELOG.md b/CHANGELOG.md index e51604cf2..3a5f5a57a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ Group changes to describe their impact on the project, as follows: Fixed for any bug fixes. Security to invite users to upgrade in case of vulnerabilities. +## [Unreleased] + +### Added +- Added shortcuts to calls history & chat rooms list + ## [4.1.0] - 2019-05-03 ### Added diff --git a/app/contacts.xml b/app/contacts.xml index 7836193c0..766be1f0b 100644 --- a/app/contacts.xml +++ b/app/contacts.xml @@ -7,5 +7,5 @@ android:icon="@drawable/linphone_logo" android:mimeType="vnd.android.cursor.item/vnd.%%PACKAGE_NAME%%.provider.sip_address" android:summaryColumn="data2" /> - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 88a73d217..0e4d44f45 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -134,6 +134,9 @@ android:name=".chat.ChatActivity" android:launchMode="singleTop" android:theme="@style/LinphoneStyleLight"> + + + @@ -172,6 +175,9 @@ android:name=".history.HistoryActivity" android:launchMode="singleTop" android:theme="@style/LinphoneStyleLight"> + + + diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index 625cbadf0..46be11884 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -93,7 +93,7 @@ public class LinphoneManager implements SensorEventListener { private final String mFriendsDatabaseFile; private final String mUserCertsPath; - private final Context mServiceContext; + private final Context mContext; private AndroidAudioManager mAudioManager; private CallManager mCallManager; private final PowerManager mPowerManager; @@ -120,7 +120,7 @@ public class LinphoneManager implements SensorEventListener { public LinphoneManager(Context c) { mExited = false; - mServiceContext = c; + mContext = c; mBasePath = c.getFilesDir().getAbsolutePath(); mLPConfigXsd = mBasePath + "/lpconfig.xsd"; mLinphoneFactoryConfigFile = mBasePath + "/linphonerc"; @@ -260,7 +260,7 @@ public class LinphoneManager implements SensorEventListener { @Override public void run() { AlertDialog.Builder builder = - new AlertDialog.Builder(mServiceContext); + new AlertDialog.Builder(mContext); builder.setMessage( getString(R.string.update_available) + ": " @@ -279,8 +279,7 @@ public class LinphoneManager implements SensorEventListener { Intent.ACTION_VIEW); urlIntent.setData( Uri.parse(urlToUse)); - mServiceContext.startActivity( - urlIntent); + mContext.startActivity(urlIntent); } } }); @@ -416,12 +415,12 @@ public class LinphoneManager implements SensorEventListener { Log.e("[Manager] Destroy Core Runtime Exception: " + e); } finally { try { - mServiceContext.unregisterReceiver(mHookReceiver); + mContext.unregisterReceiver(mHookReceiver); } catch (Exception e) { Log.e("[Manager] unregister receiver exception: " + e); } try { - mServiceContext.unregisterReceiver(mCallReceiver); + mContext.unregisterReceiver(mCallReceiver); } catch (Exception e) { Log.e("[Manager] unregister receiver exception: " + e); } @@ -436,7 +435,7 @@ public class LinphoneManager implements SensorEventListener { // traces alway start with traces enable to not missed first initialization mCore = Factory.instance() - .createCore(mConfigFile, mLinphoneFactoryConfigFile, mServiceContext); + .createCore(mConfigFile, mLinphoneFactoryConfigFile, mContext); mCore.addListener(mCoreListener); if (isPush) { Log.w( @@ -472,12 +471,12 @@ public class LinphoneManager implements SensorEventListener { private synchronized void initLiblinphone(Core core) { mCore = core; - mAudioManager = new AndroidAudioManager(mServiceContext); + mAudioManager = new AndroidAudioManager(mContext); mCore.setZrtpSecretsFile(mBasePath + "/zrtp_secrets"); - String deviceName = mPrefs.getDeviceName(mServiceContext); - String appName = mServiceContext.getResources().getString(R.string.user_agent); + String deviceName = mPrefs.getDeviceName(mContext); + String appName = mContext.getResources().getString(R.string.user_agent); String androidVersion = BuildConfig.VERSION_NAME; String userAgent = appName + "/" + androidVersion + " (" + deviceName + ") LinphoneSDK"; @@ -526,8 +525,8 @@ public class LinphoneManager implements SensorEventListener { } } - if (mServiceContext.getResources().getBoolean(R.bool.enable_push_id)) { - PushNotificationUtils.init(mServiceContext); + if (mContext.getResources().getBoolean(R.bool.enable_push_id)) { + PushNotificationUtils.init(mContext); } IntentFilter mCallIntentFilter = @@ -535,19 +534,19 @@ public class LinphoneManager implements SensorEventListener { mCallIntentFilter.setPriority(99999999); mCallReceiver = new OutgoingCallReceiver(); try { - mServiceContext.registerReceiver(mCallReceiver, mCallIntentFilter); + mContext.registerReceiver(mCallReceiver, mCallIntentFilter); } catch (IllegalArgumentException e) { e.printStackTrace(); } mProximityWakelock = mPowerManager.newWakeLock( PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, - mServiceContext.getPackageName() + ";manager_proximity_sensor"); + mContext.getPackageName() + ";manager_proximity_sensor"); IntentFilter mHookIntentFilter = new IntentFilter("com.base.module.phone.HOOKEVENT"); mHookIntentFilter.setPriority(999); mHookReceiver = new HookReceiver(); - mServiceContext.registerReceiver(mHookReceiver, mHookIntentFilter); + mContext.registerReceiver(mHookReceiver, mHookIntentFilter); resetCameraFromPreferences(); @@ -603,8 +602,7 @@ public class LinphoneManager implements SensorEventListener { long future = new Timestamp( - mServiceContext - .getResources() + mContext.getResources() .getInteger( R.integer.phone_number_linking_popup_time_interval)) .getTime(); @@ -614,7 +612,7 @@ public class LinphoneManager implements SensorEventListener { final Dialog dialog = LinphoneUtils.getDialog( - mServiceContext, + mContext, String.format( getString(R.string.link_account_popup), mCore.getDefaultProxyConfig() @@ -644,9 +642,8 @@ public class LinphoneManager implements SensorEventListener { @Override public void onClick(View view) { Intent assistant = new Intent(); - assistant.setClass( - mServiceContext, PhoneAccountLinkingAssistantActivity.class); - mServiceContext.startActivity(assistant); + assistant.setClass(mContext, PhoneAccountLinkingAssistantActivity.class); + mContext.startActivity(assistant); dialog.dismiss(); } }); @@ -684,8 +681,8 @@ public class LinphoneManager implements SensorEventListener { } private void copyFromPackage(int ressourceId, String target) throws IOException { - FileOutputStream lOutputStream = mServiceContext.openFileOutput(target, 0); - InputStream lInputStream = mServiceContext.getResources().openRawResource(ressourceId); + FileOutputStream lOutputStream = mContext.openFileOutput(target, 0); + InputStream lInputStream = mContext.getResources().openRawResource(ressourceId); int readByte; byte[] buff = new byte[8048]; while ((readByte = lInputStream.read(buff)) != -1) { @@ -855,9 +852,7 @@ public class LinphoneManager implements SensorEventListener { int lastTimestamp = LinphonePreferences.instance().getLastCheckReleaseTimestamp(); int currentTimeStamp = (int) System.currentTimeMillis(); int interval = - mServiceContext - .getResources() - .getInteger(R.integer.time_between_update_check); // 24h + mContext.getResources().getInteger(R.integer.time_between_update_check); // 24h if (lastTimestamp == 0 || currentTimeStamp - lastTimestamp >= interval) { mCore.checkForUpdate(BuildConfig.VERSION_NAME); LinphonePreferences.instance().setLastCheckReleaseTimestamp(currentTimeStamp); @@ -894,7 +889,7 @@ public class LinphoneManager implements SensorEventListener { } private String getString(int key) { - return mServiceContext.getString(key); + return mContext.getString(key); } public boolean hasLastCallSasBeenRejected() { diff --git a/app/src/main/java/org/linphone/LinphoneService.java b/app/src/main/java/org/linphone/LinphoneService.java index e397e8949..0bc1e9464 100644 --- a/app/src/main/java/org/linphone/LinphoneService.java +++ b/app/src/main/java/org/linphone/LinphoneService.java @@ -32,18 +32,16 @@ import android.provider.ContactsContract; import android.view.WindowManager; import org.linphone.call.CallIncomingActivity; import org.linphone.call.CallOutgoingActivity; +import org.linphone.compatibility.Compatibility; import org.linphone.contacts.ContactsManager; import org.linphone.core.Call; import org.linphone.core.Call.State; import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import org.linphone.core.Factory; -import org.linphone.core.GlobalState; import org.linphone.core.LogLevel; import org.linphone.core.LoggingService; import org.linphone.core.LoggingServiceListener; -import org.linphone.core.ProxyConfig; -import org.linphone.core.RegistrationState; import org.linphone.core.tools.Log; import org.linphone.mediastream.Version; import org.linphone.notifications.NotificationsManager; @@ -173,14 +171,6 @@ public final class LinphoneService extends Service { } } } - - @Override - public void onGlobalStateChanged( - Core core, GlobalState state, String message) {} - - @Override - public void onRegistrationStateChanged( - Core core, ProxyConfig cfg, RegistrationState state, String smessage) {} }; } @@ -222,6 +212,8 @@ public final class LinphoneService extends Service { mBluetoothManager = new BluetoothManager(); + Compatibility.createChatShortcuts(this); + return START_STICKY; } diff --git a/app/src/main/java/org/linphone/activities/LinphoneLauncherActivity.java b/app/src/main/java/org/linphone/activities/LinphoneLauncherActivity.java index 99e4c889d..b2c3a73e7 100644 --- a/app/src/main/java/org/linphone/activities/LinphoneLauncherActivity.java +++ b/app/src/main/java/org/linphone/activities/LinphoneLauncherActivity.java @@ -28,6 +28,7 @@ import org.linphone.LinphoneService; import org.linphone.R; import org.linphone.assistant.MenuAssistantActivity; import org.linphone.chat.ChatActivity; +import org.linphone.history.HistoryActivity; import org.linphone.settings.LinphonePreferences; /** Creates LinphoneService and wait until Core is ready to start main Activity */ @@ -66,9 +67,15 @@ public class LinphoneLauncherActivity extends Activity { if (useFirstLoginActivity && LinphonePreferences.instance().isFirstLaunch()) { classToStart = MenuAssistantActivity.class; } else { - if (getIntent().getExtras() != null - && "Chat".equals(getIntent().getExtras().getString("Activity", null))) { - classToStart = ChatActivity.class; + if (getIntent().getExtras() != null) { + String activity = getIntent().getExtras().getString("Activity", null); + if (ChatActivity.NAME.equals(activity)) { + classToStart = ChatActivity.class; + } else if (HistoryActivity.NAME.equals(activity)) { + classToStart = HistoryActivity.class; + } else { + classToStart = DialerActivity.class; + } } else { classToStart = DialerActivity.class; } diff --git a/app/src/main/java/org/linphone/chat/ChatActivity.java b/app/src/main/java/org/linphone/chat/ChatActivity.java index e3624a963..f6971df8c 100644 --- a/app/src/main/java/org/linphone/chat/ChatActivity.java +++ b/app/src/main/java/org/linphone/chat/ChatActivity.java @@ -35,11 +35,13 @@ import org.linphone.core.tools.Log; import org.linphone.utils.FileUtils; public class ChatActivity extends MainActivity { + public static final String NAME = "Chat"; + private String mSharedText, mSharedFiles; @Override protected void onCreate(Bundle savedInstanceState) { - getIntent().putExtra("Activity", "Chat"); + getIntent().putExtra("Activity", NAME); super.onCreate(savedInstanceState); } diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyEightPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyEightPlus.java index 1235608ec..2b275d859 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyEightPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyEightPlus.java @@ -2,7 +2,7 @@ package org.linphone.compatibility; /* ApiTwentyEightPlus.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyFivePlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyFivePlus.java new file mode 100644 index 000000000..af7720f2d --- /dev/null +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyFivePlus.java @@ -0,0 +1,100 @@ +package org.linphone.compatibility; + +/* +ApiTwentyFivePlus.java +Copyright (C) 2019 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 static java.lang.Math.min; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.pm.ShortcutInfo; +import android.content.pm.ShortcutManager; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.core.ChatRoom; +import org.linphone.core.ChatRoomCapabilities; +import org.linphone.utils.LinphoneShortcutManager; + +@TargetApi(25) +class ApiTwentyFivePlus { + + public static void createChatShortcuts(Context context) { + if (!context.getResources().getBoolean(R.bool.create_most_recent_chat_rooms_shortcuts)) + return; + + ShortcutManager shortcutManager = + (ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE); + ArrayList shortcuts = new ArrayList<>(); + + ChatRoom[] rooms = LinphoneManager.getCore().getChatRooms(); + ArrayList notEmptyOneToOneRooms = new ArrayList<>(); + for (ChatRoom room : rooms) { + if (room.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) + && room.getHistorySize() > 0) { + notEmptyOneToOneRooms.add(room); + } + } + Collections.sort( + notEmptyOneToOneRooms, + new Comparator() { + public int compare(ChatRoom cr1, ChatRoom cr2) { + long timeDiff = cr1.getLastUpdateTime() - cr2.getLastUpdateTime(); + if (timeDiff > 0) return -1; + else if (timeDiff == 0) return 0; + return 1; + } + }); + + LinphoneShortcutManager manager = new LinphoneShortcutManager(context); + int maxShortcuts = + min(notEmptyOneToOneRooms.size(), shortcutManager.getMaxShortcutCountPerActivity()); + for (int i = 0; i < maxShortcuts; i++) { + // Android can only have around 4-5 shortcuts at a time + ChatRoom room = notEmptyOneToOneRooms.get(i); + ShortcutInfo shortcut = manager.createChatRoomShortcutInfo(room); + if (shortcut != null) { + shortcuts.add(shortcut); + } + } + + shortcutManager.setDynamicShortcuts(shortcuts); + } + + public static void updateShortcuts(Context context) { + if (!context.getResources().getBoolean(R.bool.create_most_recent_chat_rooms_shortcuts)) + return; + + ShortcutManager shortcutManager = + (ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE); + ArrayList shortcuts = new ArrayList<>(); + LinphoneShortcutManager manager = new LinphoneShortcutManager(context); + + for (ShortcutInfo shortcutInfo : shortcutManager.getDynamicShortcuts()) { + ShortcutInfo shortcut = manager.updateShortcutInfo(shortcutInfo); + if (shortcut != null) { + shortcuts.add(shortcut); + } + } + + shortcutManager.updateShortcuts(shortcuts); + } +} diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java index 7d4c3ddd0..14a2938ee 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java @@ -2,7 +2,7 @@ package org.linphone.compatibility; /* ApiTwentyFourPlus.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyOnePlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyOnePlus.java index b2f69f064..5b5d193fb 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyOnePlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyOnePlus.java @@ -2,7 +2,7 @@ package org.linphone.compatibility; /* ApiTwentyOnePlus.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java index 07ae1c969..44aa50e37 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java @@ -2,7 +2,7 @@ package org.linphone.compatibility; /* ApiTwentySixPlus.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyThreePlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyThreePlus.java index e529643a3..8b647b36e 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyThreePlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyThreePlus.java @@ -2,7 +2,7 @@ package org.linphone.compatibility; /* ApiTwentyThreePlus.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.java b/app/src/main/java/org/linphone/compatibility/Compatibility.java index f6d15dbf6..6b525f3c3 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.java +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.java @@ -1,7 +1,7 @@ package org.linphone.compatibility; /* Compatibility.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 @@ -244,4 +244,16 @@ public class Compatibility { } return true; } + + public static void createChatShortcuts(Context context) { + if (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) { + ApiTwentyFivePlus.createChatShortcuts(context); + } + } + + public static void updateShortcuts(Context context) { + if (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) { + ApiTwentyFivePlus.updateShortcuts(context); + } + } } diff --git a/app/src/main/java/org/linphone/compatibility/CompatibilityScaleGestureDetector.java b/app/src/main/java/org/linphone/compatibility/CompatibilityScaleGestureDetector.java index bcb51dd23..cb8042547 100644 --- a/app/src/main/java/org/linphone/compatibility/CompatibilityScaleGestureDetector.java +++ b/app/src/main/java/org/linphone/compatibility/CompatibilityScaleGestureDetector.java @@ -2,7 +2,7 @@ package org.linphone.compatibility; /* CompatibilityScaleGestureDetector.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/app/src/main/java/org/linphone/compatibility/CompatibilityScaleGestureListener.java b/app/src/main/java/org/linphone/compatibility/CompatibilityScaleGestureListener.java index 8bc83e8fc..1a2a73675 100644 --- a/app/src/main/java/org/linphone/compatibility/CompatibilityScaleGestureListener.java +++ b/app/src/main/java/org/linphone/compatibility/CompatibilityScaleGestureListener.java @@ -2,7 +2,7 @@ package org.linphone.compatibility; /* CompatibilityScaleGestureListener.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.java b/app/src/main/java/org/linphone/contacts/ContactsManager.java index 43b9caa88..ca5047ed9 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.java +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.java @@ -475,5 +475,7 @@ public class ContactsManager extends ContentObserver implements FriendListListen for (ContactsUpdatedListener listener : mContactsUpdatedListeners) { listener.onContactsUpdated(); } + + Compatibility.updateShortcuts(mContext); } } diff --git a/app/src/main/java/org/linphone/history/HistoryActivity.java b/app/src/main/java/org/linphone/history/HistoryActivity.java index 88712156a..5673d5997 100644 --- a/app/src/main/java/org/linphone/history/HistoryActivity.java +++ b/app/src/main/java/org/linphone/history/HistoryActivity.java @@ -32,8 +32,11 @@ import org.linphone.core.Address; import org.linphone.utils.LinphoneUtils; public class HistoryActivity extends MainActivity { + public static final String NAME = "History"; + @Override protected void onCreate(Bundle savedInstanceState) { + getIntent().putExtra("Activity", NAME); super.onCreate(savedInstanceState); } diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.java b/app/src/main/java/org/linphone/notifications/NotificationsManager.java index e311c3c19..adf2a0480 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.java +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.java @@ -118,6 +118,12 @@ public class NotificationsManager { mListener = new CoreListenerStub() { + @Override + public void onMessageSent(Core core, ChatRoom room, ChatMessage message) { + if (room.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { + Compatibility.createChatShortcuts(mContext); + } + } @Override public void onMessageReceived( @@ -191,6 +197,10 @@ public class NotificationsManager { createNotification( cr, contact, from, textMessage, message.getTime(), null, null); } + + if (cr.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { + Compatibility.createChatShortcuts(mContext); + } } }; diff --git a/app/src/main/java/org/linphone/utils/LinphoneShortcutManager.java b/app/src/main/java/org/linphone/utils/LinphoneShortcutManager.java new file mode 100644 index 000000000..8583a3c29 --- /dev/null +++ b/app/src/main/java/org/linphone/utils/LinphoneShortcutManager.java @@ -0,0 +1,131 @@ +package org.linphone.utils; + +/* +LinphoneShortcutManager.java +Copyright (C) 2019 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 android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ShortcutInfo; +import android.graphics.Bitmap; +import android.graphics.drawable.Icon; +import android.util.ArraySet; +import java.util.Set; +import org.linphone.LinphoneService; +import org.linphone.R; +import org.linphone.chat.ChatActivity; +import org.linphone.contacts.ContactsManager; +import org.linphone.contacts.LinphoneContact; +import org.linphone.core.Address; +import org.linphone.core.ChatRoom; +import org.linphone.core.ChatRoomCapabilities; +import org.linphone.core.Factory; +import org.linphone.core.tools.Log; + +@TargetApi(25) +public class LinphoneShortcutManager { + private Context mContext; + private Set mCategories; + + public LinphoneShortcutManager(Context context) { + mContext = context; + mCategories = new ArraySet<>(); + mCategories.add(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION); + } + + public ShortcutInfo createChatRoomShortcutInfo(ChatRoom room) { + Address peerAddress = + room.hasCapability(ChatRoomCapabilities.Basic.toInt()) + ? room.getPeerAddress() + : room.getParticipants()[0].getAddress(); + LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(peerAddress); + String address = peerAddress.asStringUriOnly(); + + Bitmap bm = null; + if (contact != null && contact.getThumbnailUri() != null) { + bm = + ImageUtils.getRoundBitmapFromUri( + LinphoneService.instance(), contact.getThumbnailUri()); + } + Icon icon = + bm == null + ? Icon.createWithResource(mContext, R.drawable.avatar) + : Icon.createWithBitmap(bm); + + String name = + contact == null + ? LinphoneUtils.getAddressDisplayName(peerAddress) + : contact.getFullName(); + + try { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClass(mContext, ChatActivity.class); + intent.addFlags( + Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + intent.putExtra("RemoteSipUri", room.getPeerAddress().asStringUriOnly()); + + return new ShortcutInfo.Builder(mContext, address) + .setShortLabel(name) + .setIcon(icon) + .setCategories(mCategories) + .setIntent(intent) + .build(); + } catch (Exception e) { + Log.e("[Shortcuts Manager] ShortcutInfo.Builder exception: " + e); + } + + return null; + } + + public ShortcutInfo updateShortcutInfo(ShortcutInfo shortcutInfo) { + String address = shortcutInfo.getId(); + Address peerAddress = Factory.instance().createAddress(address); + LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(peerAddress); + + if (contact != null) { + Bitmap bm = null; + if (contact != null && contact.getThumbnailUri() != null) { + bm = + ImageUtils.getRoundBitmapFromUri( + LinphoneService.instance(), contact.getThumbnailUri()); + } + Icon icon = + bm == null + ? Icon.createWithResource(mContext, R.drawable.avatar) + : Icon.createWithBitmap(bm); + + String name = + contact == null + ? LinphoneUtils.getAddressDisplayName(peerAddress) + : contact.getFullName(); + + try { + return new ShortcutInfo.Builder(mContext, address) + .setShortLabel(name) + .setIcon(icon) + .setCategories(mCategories) + .setIntent(shortcutInfo.getIntent()) + .build(); + } catch (Exception e) { + Log.e("[Shortcuts Manager] ShortcutInfo.Builder exception: " + e); + } + } + return shortcutInfo; + } +} diff --git a/app/src/main/res/drawable-xhdpi/avatar.png b/app/src/main/res/drawable-xhdpi/avatar.png index d3a0bf331..6c91dd654 100644 Binary files a/app/src/main/res/drawable-xhdpi/avatar.png and b/app/src/main/res/drawable-xhdpi/avatar.png differ diff --git a/app/src/main/res/values/non_localizable_custom.xml b/app/src/main/res/values/non_localizable_custom.xml index 758fbbbaa..cb3ff8534 100644 --- a/app/src/main/res/values/non_localizable_custom.xml +++ b/app/src/main/res/values/non_localizable_custom.xml @@ -96,6 +96,7 @@ true false true + true false