data transfer: allow to save, delete files from conversation

Change-Id: I0087aa1e241358b41b79e21327fc2c699a54490b
diff --git a/ring-android/app/src/main/AndroidManifest.xml b/ring-android/app/src/main/AndroidManifest.xml
index 036e25f..e690f49 100644
--- a/ring-android/app/src/main/AndroidManifest.xml
+++ b/ring-android/app/src/main/AndroidManifest.xml
@@ -325,13 +325,8 @@
         <activity
             android:name=".client.MediaViewerActivity"
             android:label="@string/title_media_viewer"
-            android:theme="@style/AppThemeBase.Dark">
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.OPENABLE" />
-                <data android:scheme="content" android:mimeType="image/*"/>
-            </intent-filter>
+            android:theme="@style/AppThemeBase.Dark"
+            android:exported="false">
         </activity>
     </application>
 
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 a0da02c..18dbd6e 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
@@ -20,11 +20,13 @@
  */
 package cx.ring.adapters;
 
+import android.app.DownloadManager;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.content.Intent;
 import android.net.Uri;
+import android.os.Environment;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v4.app.ActivityOptionsCompat;
@@ -33,13 +35,17 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.TypedValue;
+import android.view.ContextMenu;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.Toast;
 
 import com.bumptech.glide.Glide;
 import com.bumptech.glide.load.resource.bitmap.CenterInside;
@@ -87,6 +93,7 @@
     private final int vPaddingEmoticon;
     private final int mPictureMaxSize;
     private final GlideOptions PICTURE_OPTIONS;
+    private RecyclerViewContextMenuInfo mCurrentLongItem = null;
 
     public ConversationAdapter(ConversationFragment conversationFragment, ConversationPresenter presenter) {
         this.conversationFragment = conversationFragment;
@@ -196,6 +203,15 @@
         }
     }
 
+    @Override
+    public void onViewRecycled(ConversationViewHolder holder) {
+        if (holder.itemView != null)
+            holder.itemView.setOnLongClickListener(null);
+        if (holder.mPhoto != null)
+            holder.mPhoto.setOnLongClickListener(null);
+        super.onViewRecycled(holder);
+    }
+
     private static void runJustBeforeBeingDrawn(final ImageView view, final Runnable runnable) {
 
         final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@@ -209,6 +225,62 @@
         view.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
     }
 
+    public static class RecyclerViewContextMenuInfo implements ContextMenu.ContextMenuInfo {
+        public RecyclerViewContextMenuInfo(int position, long id) {
+            this.position = position;
+            this.id = id;
+        }
+        final public int position;
+        final public long id;
+    }
+
+    public RecyclerViewContextMenuInfo getCurrentLongItem() {
+        return mCurrentLongItem;
+    }
+
+    public boolean onContextItemSelected(MenuItem item) {
+        ConversationAdapter.RecyclerViewContextMenuInfo info = getCurrentLongItem();
+        if (info == null) {
+            return false;
+        }
+        IConversationElement conversationElement = mConversationElements.get(info.position);
+        if (conversationElement == null)
+            return false;
+        if (conversationElement.getType() != IConversationElement.CEType.FILE)
+            return false;
+        DataTransfer file = (DataTransfer) conversationElement;
+        Context context = conversationFragment.getActivity();
+        switch (item.getItemId()) {
+            case R.id.conv_action_download: {
+                File downloadDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "Ring");
+                if (!downloadDir.mkdirs()) {
+                    Log.e(TAG, "Directory not created");
+                }
+                File newFile = new File(downloadDir, file.getDisplayName());
+                if (newFile.exists())
+                    newFile.delete();
+                if (presenter.downloadFile(file, newFile)) {
+                    DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
+                    if (downloadManager != null) {
+                        downloadManager.addCompletedDownload(file.getDisplayName(),
+                                file.getDisplayName(),
+                                true,
+                                file.isPicture() ? "image/jpeg" : "text/plain",
+                                newFile.getAbsolutePath(),
+                                newFile.length(),
+                                true);
+                    }
+                }
+                break;
+            }
+            case R.id.conv_action_delete:
+                presenter.deleteFile(file);
+                break;
+        }
+        return true;
+    }
+
+
     private void configureForFileInfoTextMessage(final ConversationViewHolder conversationViewHolder,
                                                  final IConversationElement conversationElement) {
         if (conversationViewHolder == null || conversationElement == null) {
@@ -227,7 +299,23 @@
                     timeSeparationString, FileUtils.readableFileSize(file.getTotalSize()),
                     ResourceMapper.getReadableFileTransferStatus(conversationFragment.getActivity(), file.getEventCode())));
         }
-        if (file.showPicture()) {
+
+        boolean showPicture = file.showPicture();
+        View longPressView = showPicture ? conversationViewHolder.mPhoto : conversationViewHolder.itemView;
+        longPressView.setOnCreateContextMenuListener((menu, v, menuInfo) -> {
+            menu.setHeaderTitle(file.getDisplayName());
+            conversationFragment.onCreateContextMenu(menu, v, menuInfo);
+            MenuInflater inflater = conversationFragment.getActivity().getMenuInflater();
+            inflater.inflate(R.menu.conversation_item_actions, menu);
+            if (!file.isComplete())
+                menu.removeItem(R.id.conv_action_download);
+        });
+        longPressView.setOnLongClickListener(v -> {
+            mCurrentLongItem = new RecyclerViewContextMenuInfo(conversationViewHolder.getLayoutPosition(), v.getId());
+            return false;
+        });
+
+        if (showPicture) {
             Context context = conversationViewHolder.mPhoto.getContext();
             File path = presenter.getDeviceRuntimeService().getConversationPath(file.getPeerId(), file.getStoragePath());
 
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 4bc1c17..4adb06d 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
@@ -214,6 +214,13 @@
         }
     }
 
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        if (mAdapter.onContextItemSelected(item))
+            return true;
+        return super.onContextItemSelected(item);
+    }
+
     @OnClick(R.id.msg_send)
     public void sendMessageText() {
         presenter.sendTextMessage(mMsgEditTxt.getText().toString());
diff --git a/ring-android/app/src/main/res/drawable/ic_file_download.xml b/ring-android/app/src/main/res/drawable/ic_file_download.xml
new file mode 100644
index 0000000..bb72b2c
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_file_download.xml
@@ -0,0 +1,8 @@
+<!-- drawable/download.xml -->

+<vector xmlns:android="http://schemas.android.com/apk/res/android"

+    android:height="24dp"

+    android:width="24dp"

+    android:viewportWidth="24"

+    android:viewportHeight="24">

+    <path android:fillColor="#000" android:pathData="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" />

+</vector>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/menu/conversation_item_actions.xml b/ring-android/app/src/main/res/menu/conversation_item_actions.xml
new file mode 100644
index 0000000..8c2180e
--- /dev/null
+++ b/ring-android/app/src/main/res/menu/conversation_item_actions.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <item
+        android:id="@+id/conv_action_download"
+        android:icon="@drawable/ic_file_download"
+        android:title="@string/menu_file_download"
+        app:showAsAction="always" />
+
+    <item
+        android:id="@+id/conv_action_delete"
+        android:icon="@drawable/ic_delete_white"
+        android:title="@string/menu_file_delete"
+        app:showAsAction="always" />
+</menu>
\ 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 e5af8ca..a1d3480 100644
--- a/ring-android/app/src/main/res/values/strings.xml
+++ b/ring-android/app/src/main/res/values/strings.xml
@@ -242,5 +242,7 @@
     <string name="file_saved_in">File saved in %s</string>
     <string name="no_space_left_on_device">No space left on device</string>
     <string name="title_media_viewer">Media viewer</string>
+    <string name="menu_file_download">Download file</string>
+    <string name="menu_file_delete">Delete file</string>
 
 </resources>