data transfer: implement persistence

Change-Id: Ib57b4ed8aec372b14dea55f30a1e936b05392c8f
diff --git a/ring-android/app/src/main/java/cx/ring/account/AccountEditionActivity.java b/ring-android/app/src/main/java/cx/ring/account/AccountEditionActivity.java
index 3b69c47..a2a4191 100644
--- a/ring-android/app/src/main/java/cx/ring/account/AccountEditionActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/account/AccountEditionActivity.java
@@ -21,7 +21,6 @@
  */
 package cx.ring.account;
 
-import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -208,14 +207,13 @@
 
     @NonNull
     private AlertDialog createDeleteDialog() {
-        Activity ownerActivity = this;
-        AlertDialog alertDialog = new AlertDialog.Builder(ownerActivity)
+        AlertDialog alertDialog = new AlertDialog.Builder(AccountEditionActivity.this)
                 .setMessage(R.string.account_delete_dialog_message)
                 .setTitle(R.string.account_delete_dialog_title)
                 .setPositiveButton(android.R.string.ok, (dialog, whichButton) -> mEditionPresenter.removeAccount())
                 .setNegativeButton(android.R.string.cancel, null)
                 .create();
-        alertDialog.setOwnerActivity(ownerActivity);
+        alertDialog.setOwnerActivity(AccountEditionActivity.this);
         return alertDialog;
     }
 
diff --git a/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java b/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
index 12d033c..487bdee 100644
--- a/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
+++ b/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
@@ -21,6 +21,7 @@
 package cx.ring.adapters;
 
 import android.content.Context;
+import android.content.Intent;
 import android.os.Build;
 import android.support.annotation.Nullable;
 import android.support.v7.widget.RecyclerView;
@@ -43,9 +44,10 @@
 import cx.ring.fragments.ConversationFragment;
 import cx.ring.model.DataTransferEventCode;
 import cx.ring.model.HistoryCall;
-import cx.ring.model.HistoryFileTransfer;
+import cx.ring.model.DataTransfer;
 import cx.ring.model.IConversationElement;
 import cx.ring.model.TextMessage;
+import cx.ring.service.DRingService;
 import cx.ring.utils.CircleTransform;
 import cx.ring.utils.FileUtils;
 import cx.ring.utils.ResourceMapper;
@@ -169,9 +171,9 @@
         if (conversationViewHolder == null || conversationElement == null) {
             return;
         }
-        HistoryFileTransfer file = (HistoryFileTransfer) conversationElement;
+        DataTransfer file = (DataTransfer) conversationElement;
 
-        if (file.getDataTransferEventCode().isError()) {
+        if (file.getEventCode().isError()) {
             conversationViewHolder.icon.setImageResource(R.drawable.ic_warning);
         } else {
             conversationViewHolder.icon.setImageResource(R.drawable.ic_clip_black);
@@ -184,54 +186,36 @@
                 file.getDate());
         conversationViewHolder.mMsgDetailTxt.setText(String.format("%s - %s - %s",
                 timeSeparationString, FileUtils.readableFileSize(file.getTotalSize()),
-                ResourceMapper.getReadableFileTransferStatus(conversationFragment.getActivity(), file.getDataTransferEventCode())));
+                ResourceMapper.getReadableFileTransferStatus(conversationFragment.getActivity(), file.getEventCode())));
         if (file.isOutgoing()) {
             conversationViewHolder.mPhoto.setImageResource(R.drawable.ic_outgoing_black);
         } else {
             conversationViewHolder.mPhoto.setImageResource(R.drawable.ic_incoming_black);
         }
 
-        if (file.getDataTransferEventCode() == DataTransferEventCode.WAIT_HOST_ACCEPTANCE) {
+        if (file.getEventCode() == DataTransferEventCode.WAIT_HOST_ACCEPTANCE) {
             conversationViewHolder.mAnswerLayout.setVisibility(View.VISIBLE);
             conversationViewHolder.btnAccept.setOnClickListener(v -> {
-
                 if (!presenter.getDeviceRuntimeService().hasWriteExternalStoragePermission()) {
                     conversationFragment.askWriteExternalStoragePermission();
                     return;
                 }
-
-                File cacheDir = conversationFragment.getActivity().getCacheDir();
-                if (!cacheDir.exists()) {
-                    boolean mkdirs = cacheDir.mkdirs();
-                    if (!mkdirs) {
-                        Log.e(TAG, "configureForFileInfoTextMessage: not able to create directory at " + cacheDir.toString());
-                        return;
-                    }
-                }
-
+                Context context = v.getContext();
+                File cacheDir = context.getCacheDir();
                 long spaceLeft = FileUtils.getSpaceLeft(cacheDir.toString());
                 if (spaceLeft == -1L || file.getTotalSize() > spaceLeft) {
                     presenter.noSpaceLeft();
                     return;
                 }
-
-                File cacheFile = new File(cacheDir, file.getDisplayName());
-                if (cacheFile.exists()) {
-                    boolean delete = cacheFile.delete();
-                    if (!delete) {
-                        Log.e(TAG, "configureForFileInfoTextMessage: not able to delete cache file at " + cacheFile.toString());
-                        return;
-                    }
-                }
-
-                Log.d(TAG, "configureForFileInfoTextMessage: cacheFile=" + cacheFile + ",exists=" + cacheFile.exists());
-
-                conversationViewHolder.mAnswerLayout.setVisibility(View.GONE);
-                presenter.acceptDataTransfer(file.getDataTransferId(), cacheFile.toString());
+                context.startService(new Intent(DRingService.ACTION_FILE_ACCEPT)
+                        .setClass(context.getApplicationContext(), DRingService.class)
+                        .putExtra(DRingService.KEY_TRANSFER_ID, file.getDataTransferId()));
             });
             conversationViewHolder.btnRefuse.setOnClickListener(v -> {
-                conversationViewHolder.mAnswerLayout.setVisibility(View.GONE);
-                presenter.cancelDataTransfer(file.getDataTransferId());
+                Context context = v.getContext();
+                context.startService(new Intent(DRingService.ACTION_FILE_CANCEL)
+                        .setClass(context.getApplicationContext(), DRingService.class)
+                        .putExtra(DRingService.KEY_TRANSFER_ID, file.getDataTransferId()));
             });
         } else {
             conversationViewHolder.mAnswerLayout.setVisibility(View.GONE);
@@ -247,6 +231,7 @@
                 continue;
             }
             Character.UnicodeBlock block = Character.UnicodeBlock.of(codePoint);
+
             // Ignore modifier
             if (block == Character.UnicodeBlock.VARIATION_SELECTORS) {
                 continue;
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
index 63c068a..4737406 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/ConversationFragment.java
@@ -144,6 +144,9 @@
 
     @Override
     public void refreshView(final Conversation conversation) {
+        if (conversation == null) {
+            return;
+        }
         getActivity().runOnUiThread(() -> {
             if (mAdapter != null) {
                 mAdapter.updateDataset(conversation.getAggregateHistory());
@@ -256,6 +259,7 @@
 
     @Override
     public void writeCacheFile(String cacheFilename) {
+        // todo use rx + move to presenter
         File cacheFile = new File(getActivity().getCacheDir(), cacheFilename);
         try {
             String finalFilePath = FileUtils.writeCacheFileToExtStorage(getActivity(), android.net.Uri.fromFile(cacheFile), cacheFile.getName());
diff --git a/ring-android/app/src/main/java/cx/ring/history/DatabaseHelper.java b/ring-android/app/src/main/java/cx/ring/history/DatabaseHelper.java
index d65ae24..e845f26 100644
--- a/ring-android/app/src/main/java/cx/ring/history/DatabaseHelper.java
+++ b/ring-android/app/src/main/java/cx/ring/history/DatabaseHelper.java
@@ -33,6 +33,7 @@
 import java.sql.SQLException;
 import java.util.ArrayList;
 
+import cx.ring.model.DataTransfer;
 import cx.ring.model.HistoryCall;
 import cx.ring.model.HistoryText;
 
@@ -49,10 +50,11 @@
     private static final String TAG = DatabaseHelper.class.getSimpleName();
     private static final String DATABASE_NAME = "history.db";
     // any time you make changes to your database objects, you may have to increase the database version
-    private static final int DATABASE_VERSION = 8;
+    private static final int DATABASE_VERSION = 9;
 
     private Dao<HistoryCall, Integer> historyDao = null;
     private Dao<HistoryText, Long> historyTextDao = null;
+    private Dao<DataTransfer, Long> historyDataDao = null;
 
     public DatabaseHelper(Context context) {
         super(context, DATABASE_NAME, null, DATABASE_VERSION);
@@ -67,6 +69,7 @@
         try {
             TableUtils.createTable(connectionSource, HistoryCall.class);
             TableUtils.createTable(connectionSource, HistoryText.class);
+            TableUtils.createTable(connectionSource, DataTransfer.class);
         } catch (SQLException e) {
             Log.e(TAG, "Can't create database", e);
             throw new RuntimeException(e);
@@ -81,8 +84,8 @@
     public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
         Log.i(TAG, "onUpgrade " + oldVersion + " -> " + newVersion);
         try {
-            updateDatabase(oldVersion, db);
-        } catch (SQLiteException exc) {
+            updateDatabase(oldVersion, db, connectionSource);
+        } catch (SQLException exc) {
             exc.printStackTrace();
             clearDatabase(db);
             onCreate(db, connectionSource);
@@ -107,6 +110,13 @@
         return historyTextDao;
     }
 
+    public Dao<DataTransfer, Long> getDataHistoryDao() throws SQLException {
+        if (historyDataDao == null) {
+            historyDataDao = getDao(DataTransfer.class);
+        }
+        return historyDataDao;
+    }
+
     /**
      * Close the database connections and clear any cached DAOs.
      */
@@ -122,9 +132,9 @@
      *
      * @param fromDatabaseVersion the old version of the database
      * @param db                  the SQLiteDatabase to work with
-     * @throws SQLiteException    database has failed to update to the last version
+     * @throws SQLiteException database has failed to update to the last version
      */
-    private void updateDatabase(int fromDatabaseVersion, SQLiteDatabase db) throws SQLiteException {
+    private void updateDatabase(int fromDatabaseVersion, SQLiteDatabase db, ConnectionSource connectionSource) throws SQLException {
         try {
             while (fromDatabaseVersion < DATABASE_VERSION) {
                 switch (fromDatabaseVersion) {
@@ -134,11 +144,14 @@
                     case 7:
                         updateDatabaseFrom7(db);
                         break;
+                    case 8:
+                        updateDatabaseFrom8(connectionSource);
+                        break;
                 }
                 fromDatabaseVersion++;
             }
             Log.d(TAG, "updateDatabase: Database has been updated to the last version.");
-        } catch (SQLiteException exc) {
+        } catch (SQLException exc) {
             Log.e(TAG, "updateDatabase: Database has failed to update to the last version.");
             throw exc;
         }
@@ -222,6 +235,16 @@
         }
     }
 
+    private void updateDatabaseFrom8(ConnectionSource connectionSource) throws SQLException {
+        try {
+            TableUtils.createTable(connectionSource, DataTransfer.class);
+            Log.d(TAG, "Migration from database version 8 to next, done.");
+        } catch (SQLException e) {
+            Log.e(TAG, "Migration from database version 8 to next, failed.", e);
+            throw e;
+        }
+    }
+
     /**
      * Removes all the data from the database, ie all the tables.
      *
diff --git a/ring-android/app/src/main/java/cx/ring/service/DRingService.java b/ring-android/app/src/main/java/cx/ring/service/DRingService.java
index 0680a46..1e4a62c 100644
--- a/ring-android/app/src/main/java/cx/ring/service/DRingService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/DRingService.java
@@ -62,6 +62,7 @@
 import cx.ring.fragments.ConversationFragment;
 import cx.ring.model.Codec;
 import cx.ring.model.Conversation;
+import cx.ring.model.DataTransfer;
 import cx.ring.model.ServiceEvent;
 import cx.ring.model.SipCall;
 import cx.ring.services.AccountService;
@@ -93,6 +94,11 @@
     static public final String ACTION_CONV_READ = BuildConfig.APPLICATION_ID + ".action.CONV_READ";
     static public final String ACTION_CONV_DISMISS = BuildConfig.APPLICATION_ID + ".action.CONV_DISMISS";
     static public final String ACTION_CONV_ACCEPT = BuildConfig.APPLICATION_ID + ".action.CONV_ACCEPT";
+
+    static public final String ACTION_FILE_ACCEPT = BuildConfig.APPLICATION_ID + ".action.FILE_ACCEPT";
+    static public final String ACTION_FILE_CANCEL = BuildConfig.APPLICATION_ID + ".action.FILE_CANCEL";
+    static public final String KEY_TRANSFER_ID = "transferId";
+
     public static final String ACTION_PUSH_RECEIVED = BuildConfig.APPLICATION_ID + ".action.PUSH_RECEIVED";
     public static final String ACTION_PUSH_TOKEN_CHANGED = BuildConfig.APPLICATION_ID + ".push.PUSH_TOKEN_CHANGED";
     public static final String PUSH_RECEIVED_FIELD_FROM = "from";
@@ -638,6 +644,12 @@
                     handleConvAction(action, extras);
                 }
                 break;
+            case ACTION_FILE_ACCEPT:
+            case ACTION_FILE_CANCEL:
+                if (extras != null) {
+                    handleFileAction(action, extras);
+                }
+                break;
             case ACTION_PUSH_TOKEN_CHANGED:
                 if (extras != null) {
                     handlePushTokenChanged(extras);
@@ -653,6 +665,41 @@
         }
     }
 
+    private void handleFileAction(String action, Bundle extras) {
+        Long id = extras.getLong(KEY_TRANSFER_ID);
+        if (action.equals(ACTION_FILE_ACCEPT)) {
+            File cacheDir = getCacheDir();
+            if (!cacheDir.exists()) {
+                boolean mkdirs = cacheDir.mkdirs();
+                if (!mkdirs) {
+                    Log.e(TAG, "handleFileAction: not able to create directory at " + cacheDir.toString());
+                    return;
+                }
+            }
+
+            DataTransfer file = mAccountService.getDataTransfer(id);
+            if (file == null) {
+                Log.e(TAG, "handleFileAction: unknown data transfer " + id);
+                return;
+            }
+
+            File cacheFile = new File(cacheDir, file.getDisplayName());
+            if (cacheFile.exists()) {
+                boolean delete = cacheFile.delete();
+                if (!delete) {
+                    Log.e(TAG, "configureForFileInfoTextMessage: not able to delete cache file at " + cacheFile.toString());
+                    return;
+                }
+            }
+
+            Log.d(TAG, "configureForFileInfoTextMessage: cacheFile=" + cacheFile + ",exists=" + cacheFile.exists());
+
+            mAccountService.acceptFileTransfer(id, cacheFile.getAbsolutePath(), 0);
+        } else if (action.equals(ACTION_FILE_CANCEL)) {
+            mAccountService.cancelDataTransfer(id);
+        }
+    }
+
     private void handlePushReceived(Bundle extras) {
         String from = extras.getString(PUSH_RECEIVED_FIELD_FROM);
         Bundle data = extras.getBundle(PUSH_RECEIVED_FIELD_DATA);
diff --git a/ring-android/app/src/main/java/cx/ring/services/DeviceRuntimeServiceImpl.java b/ring-android/app/src/main/java/cx/ring/services/DeviceRuntimeServiceImpl.java
index e0b3942..6cee188 100644
--- a/ring-android/app/src/main/java/cx/ring/services/DeviceRuntimeServiceImpl.java
+++ b/ring-android/app/src/main/java/cx/ring/services/DeviceRuntimeServiceImpl.java
@@ -83,6 +83,11 @@
         return mContext.getFilesDir();
     }
 
+    @Override
+    public File getCacheDir() {
+        return mContext.getCacheDir();
+    }
+
     private boolean isNetworkConnectedForType(int connectivityManagerType) {
         NetworkInfo info = NetworkUtils.getNetworkInfo(mContext);
         return (info != null && info.isConnected() && info.getType() == connectivityManagerType);
diff --git a/ring-android/app/src/main/java/cx/ring/services/HistoryServiceImpl.java b/ring-android/app/src/main/java/cx/ring/services/HistoryServiceImpl.java
index 7b6a906..2da5363 100644
--- a/ring-android/app/src/main/java/cx/ring/services/HistoryServiceImpl.java
+++ b/ring-android/app/src/main/java/cx/ring/services/HistoryServiceImpl.java
@@ -31,6 +31,7 @@
 import javax.inject.Inject;
 
 import cx.ring.history.DatabaseHelper;
+import cx.ring.model.DataTransfer;
 import cx.ring.model.HistoryCall;
 import cx.ring.model.HistoryText;
 
@@ -73,6 +74,16 @@
         }
     }
 
+    @Override
+    protected Dao<DataTransfer, Long> getDataHistoryDao() {
+        try {
+            return getHelper().getDataHistoryDao();
+        } catch (SQLException e) {
+            cx.ring.utils.Log.e(TAG, "Unable to get a DataHistoryDao");
+            return null;
+        }
+    }
+
     /**
      * Init Helper for our DB
      */
diff --git a/ring-android/app/src/main/java/cx/ring/services/NotificationServiceImpl.java b/ring-android/app/src/main/java/cx/ring/services/NotificationServiceImpl.java
index 49e8f75..beda427 100644
--- a/ring-android/app/src/main/java/cx/ring/services/NotificationServiceImpl.java
+++ b/ring-android/app/src/main/java/cx/ring/services/NotificationServiceImpl.java
@@ -54,14 +54,14 @@
 import cx.ring.R;
 import cx.ring.client.HomeActivity;
 import cx.ring.contactrequests.ContactRequestsFragment;
-import cx.ring.daemon.DataTransferInfo;
+import cx.ring.facades.ConversationFacade;
 import cx.ring.fragments.ConversationFragment;
 import cx.ring.model.Account;
 import cx.ring.model.CallContact;
 import cx.ring.model.Conference;
 import cx.ring.model.Conversation;
+import cx.ring.model.DataTransfer;
 import cx.ring.model.DataTransferEventCode;
-import cx.ring.model.HistoryFileTransfer;
 import cx.ring.model.ServiceEvent;
 import cx.ring.model.SipCall;
 import cx.ring.model.TextMessage;
@@ -391,37 +391,77 @@
     }
 
     @Override
-    public void showFileTransferNotification(Long dataTransferId, String contactAccountId) {
-        if (dataTransferId == null || contactAccountId == null) {
+    public void showFileTransferNotification(DataTransfer info, DataTransferEventCode event, CallContact contact) {
+        if (event == null || info == null) {
             return;
         }
+        long dataTransferId = info.getDataTransferId();
+        int notificationId = getFileTransferNotificationId(dataTransferId);
+        if (event == DataTransferEventCode.FINISHED) {
+            notificationManager.cancel(notificationId);
+            mNotificationBuilders.delete(notificationId);
+            return;
+        }
+        NotificationCompat.Builder messageNotificationBuilder = mNotificationBuilders.get(notificationId);
+        if (messageNotificationBuilder == null) {
+            messageNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_FILE_TRANSFER);
+        }
 
-        String contactUri = new Uri(contactAccountId).getRawUriString();
+        boolean ongoing = event == DataTransferEventCode.CREATED || event == DataTransferEventCode.ONGOING;
+        boolean outgoing = info.isOutgoing();
 
+        String contactUri = new Uri(info.getPeerId()).getRawUriString();
         Intent intentConversation = new Intent(DRingService.ACTION_CONV_ACCEPT)
                 .setClass(mContext, DRingService.class)
                 .putExtra(ConversationFragment.KEY_ACCOUNT_ID, mAccountService.getCurrentAccount().getAccountID())
                 .putExtra(ConversationFragment.KEY_CONTACT_RING_ID, contactUri);
 
-        int notificationId = getFileTransferNotificationId(dataTransferId);
-        NotificationCompat.Builder messageNotificationBuilder = mNotificationBuilders.get(notificationId);
-
-        if (messageNotificationBuilder == null) {
-            messageNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_FILE_TRANSFER);
-        } else {
-            notificationManager.cancel(notificationId);
-        }
-
-        messageNotificationBuilder.setContentTitle(mContext.getString(R.string.notif_incoming_file_transfer_title))
+        String titleMessage = mContext.getString(outgoing ? R.string.notif_outgoing_file_transfer_title : R.string.notif_incoming_file_transfer_title, contact.getDisplayName());
+        byte[] photo = contact.getPhoto();
+        Bitmap photo_bmp = photo == null ? null : BitmapFactory.decodeByteArray(photo, 0, photo.length);
+        messageNotificationBuilder.setContentTitle(titleMessage)
                 .setDefaults(NotificationCompat.DEFAULT_ALL)
-                .setPriority(NotificationCompat.PRIORITY_HIGH)
-                .setAutoCancel(true)
-                .setOngoing(true)
+                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+                .setAutoCancel(false)
+                .setOngoing(ongoing)
                 .setSmallIcon(R.drawable.ic_ring_logo_white)
-                .setCategory(NotificationCompat.CATEGORY_SOCIAL)
-                .setContentText(mContext.getString(R.string.notif_incoming_file_transfer))
+                .setLargeIcon(photo_bmp)
+                .setCategory(NotificationCompat.CATEGORY_PROGRESS)
+                .setContentText(info.getDisplayName() + " state: " + event.name())
                 .setContentIntent(PendingIntent.getService(mContext, random.nextInt(), intentConversation, 0))
                 .setColor(ResourcesCompat.getColor(mContext.getResources(), R.color.color_primary_dark, null));
+        if (event.isOver()) {
+            messageNotificationBuilder.setProgress(0, 0, false);
+        } else if (ongoing) {
+            Log.w(TAG, "messageNotificationBuilder.setProgress " + info.getTotalSize() + " " + info.getBytesProgress());
+            messageNotificationBuilder.setProgress((int)info.getTotalSize(), (int)info.getBytesProgress(), false);
+        } else {
+            messageNotificationBuilder.setProgress(0, 0, true);
+        }
+        messageNotificationBuilder.mActions.clear();
+        if (event == DataTransferEventCode.WAIT_HOST_ACCEPTANCE) {
+            messageNotificationBuilder
+                    .addAction(R.drawable.ic_incoming_black, mContext.getText(R.string.accept),
+                    PendingIntent.getService(mContext, random.nextInt(),
+                            new Intent(DRingService.ACTION_FILE_ACCEPT)
+                                    .setClass(mContext, DRingService.class)
+                                    .putExtra(DRingService.KEY_TRANSFER_ID, dataTransferId),
+                            PendingIntent.FLAG_ONE_SHOT))
+                    .addAction(R.drawable.ic_cancel_black_24dp, mContext.getText(R.string.refuse),
+                            PendingIntent.getService(mContext, random.nextInt(),
+                                    new Intent(DRingService.ACTION_FILE_CANCEL)
+                                            .setClass(mContext, DRingService.class)
+                                            .putExtra(DRingService.KEY_TRANSFER_ID, dataTransferId),
+                                    PendingIntent.FLAG_ONE_SHOT));
+        } else if (!event.isOver()) {
+            messageNotificationBuilder
+                    .addAction(R.drawable.ic_cancel_black_24dp, mContext.getText(android.R.string.cancel),
+                            PendingIntent.getService(mContext, random.nextInt(),
+                                    new Intent(DRingService.ACTION_FILE_CANCEL)
+                                            .setClass(mContext, DRingService.class)
+                                            .putExtra(DRingService.KEY_TRANSFER_ID, dataTransferId),
+                                    PendingIntent.FLAG_ONE_SHOT));
+        }
 
         mNotificationBuilders.put(notificationId, messageNotificationBuilder);
         notificationManager.notify(notificationId, messageNotificationBuilder.build());
@@ -496,37 +536,6 @@
                     break;
                 }
             }
-        } else if (observable instanceof CallService && event != null) {
-            switch (event.getEventType()) {
-                case DATA_TRANSFER: {
-                    Long transferId = event.getEventInput(ServiceEvent.EventInput.TRANSFER_ID, Long.class);
-                    DataTransferEventCode transferEventCode = event.getEventInput(ServiceEvent.EventInput.TRANSFER_EVENT_CODE, DataTransferEventCode.class);
-                    DataTransferInfo dataTransferInfo = new DataTransferInfo();
-                    mCallService.dataTransferInfo(transferId, dataTransferInfo);
-
-                    if (transferEventCode == DataTransferEventCode.CREATED) {
-
-                        HistoryFileTransfer historyFileTransfer = new HistoryFileTransfer(transferId, dataTransferInfo.getDisplayName(),
-                                dataTransferInfo.getFlags() == 0, dataTransferInfo.getTotalSize(),
-                                dataTransferInfo.getBytesProgress(), dataTransferInfo.getPeer(),
-                                dataTransferInfo.getAccountId());
-                        mHistoryService.addFileTransfer(historyFileTransfer);
-
-                        if (dataTransferInfo.getFlags() == 1){
-                            showFileTransferNotification(transferId, dataTransferInfo.getPeer());
-                        }
-                    }
-
-                    if (dataTransferInfo.getFlags() == 1) {
-                        mHistoryService.updateFileTransferStatus(transferId, transferEventCode);
-                    }
-
-                    if (transferEventCode == DataTransferEventCode.FINISHED) {
-                        notificationManager.cancel(getFileTransferNotificationId(transferId));
-                    }
-                    break;
-                }
-            }
         }
     }
 }
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/values/strings.xml b/ring-android/app/src/main/res/values/strings.xml
index 52731f6..2d0def1 100644
--- a/ring-android/app/src/main/res/values/strings.xml
+++ b/ring-android/app/src/main/res/values/strings.xml
@@ -107,8 +107,10 @@
     <string name="notif_channel_requests">Requests</string>
     <string name="notif_channel_file_transfer">File transfer</string>
     <string name="notif_mark_as_read">Mark as read</string>
-    <string name="notif_incoming_file_transfer_title">Incoming file transfer</string>
+    <string name="notif_incoming_file_transfer_title">Incoming file from %1$s</string>
     <string name="notif_incoming_file_transfer">Someone wants to send you a file</string>
+    <string name="notif_outgoing_file_transfer_title">Sending file to %1$s</string>
+    <string name="notif_outgoing_file_transfer">Someone wants to send you a file</string>
     <string name="action_open">Open</string>
 
     <!-- Call Fragment -->