aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/cyanogenmod/filemanager/service/MoveFileService.java
blob: e86150b44ee6ceb9a3ac68bdac1439e797a35075 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
* Copyright (C) 2015 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.cyanogenmod.filemanager.service;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;

import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.util.CommandHelper;

import java.io.File;

public class MoveFileService extends IntentService {
    private static final String TAG = MoveFileService.class.getSimpleName();

    private static final String FILE_MANAGER_PACKAGE = "com.cyanogenmod.filemanager";
    private static final String FILE_MANAGER_ACTIVITY =
            FILE_MANAGER_PACKAGE + ".activities.MainActivity";
    private static final String EXTRA_NAVIGATE_TO = "extra_navigate_to";

    public static final String EXTRA_SOURCE_FILE_PATH = "extra_source_file_path";
    public static final String EXTRA_DESTINATION_FILE_PATH = "extra_destination_file_path";

    private static final String TAG_SEPARATOR = ":::";

    public MoveFileService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (!intent.hasExtra(EXTRA_SOURCE_FILE_PATH)) {
            Log.w(TAG, "Source file path not provided");
            return;
        }
        if (!intent.hasExtra(EXTRA_DESTINATION_FILE_PATH)) {
            Log.w(TAG, "Destination file path not provided");
            return;
        }
        String srcPath = intent.getStringExtra(EXTRA_SOURCE_FILE_PATH);
        String dstPath = intent.getStringExtra(EXTRA_DESTINATION_FILE_PATH);
        String tag = getTagForNotification(srcPath, dstPath);

        showMovingNotification(tag);
        new MoveFileTask().execute(srcPath, dstPath);
    }

    /**
     * Post the moving file notification
     * @param tag Tag for identifying this notification
     */
    private void showMovingNotification(String tag) {
        NotificationManager nm = NotificationManager.from(this);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle(getString(R.string.moving_file_notification_title));
        builder.setSmallIcon(R.drawable.ic_object_move);
        builder.setProgress(0, 100, true);
        nm.notify(tag, 0, builder.build());
    }

    /**
     * Post the file moved notification with a "show" action
     * @param tag Tag for identifying this notification
     * @param directoryPath Path to the moved file's parent directory
     */
    private void showFileMovedNotification(String tag, String directoryPath) {
        NotificationManager nm = NotificationManager.from(this);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle(getString(R.string.move_complete_notification_title));
        builder.setContentText(getString(R.string.move_complete_notification_description));
        builder.setSmallIcon(R.drawable.ic_object_move);

        // Add the show content intent
        Intent intent = createFileManagerNavigateToIntent(directoryPath);
        PendingIntent pi = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pi);
        nm.notify(tag, 0, builder.build());
    }

    /**
     * Post the move failed notification
     * @param tag Tag for identifying this notification
     * @param textResId String resource ID for the content text
     */
    private void showFileMoveFailedNotification(String tag, int textResId) {
        NotificationManager nm = NotificationManager.from(this);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setSmallIcon(R.drawable.ic_object_move);
        builder.setContentTitle(getString(R.string.moving_file_failed_notification_title));
        if (textResId > 0) builder.setContentText(getString(textResId));

        // TODO: Add the retry action
        nm.notify(tag, 0, builder.build());
    }

    /**
     * Creates the intent used to show the folder containing the moved file
     * @param filePath Absolute path to the moved file
     * @return
     */
    private Intent createFileManagerNavigateToIntent(String filePath) {
        File downloadedFile = new File(filePath);
        String path = downloadedFile.getParent();
        Intent intent = new Intent();
        intent.setComponent(new ComponentName(FILE_MANAGER_PACKAGE, FILE_MANAGER_ACTIVITY));
        intent.putExtra(EXTRA_NAVIGATE_TO, path);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        return intent;
    }

    /**
     * Creates a tag based on the source and destination paths
     * @param srcPath Path to the file to be moved
     * @param dstPath Path to the destination of the moved file
     * @return Tag for use in posting a notification
     */
    private static String getTagForNotification(String srcPath, String dstPath) {
        return srcPath + TAG_SEPARATOR + dstPath;
    }

    /**
     * Extract the source path from the given tag
     * @param tag
     * @return
     */
    private static String getSourcePathFromTag(String tag) {
        if (tag == null) {
            throw new IllegalArgumentException("getSourcePathFromTag: Tag must be non-null");
        }
        return tag.substring(0, tag.indexOf(TAG_SEPARATOR));
    }

    private static String getDestinationPathFromTag(String tag) {
        if (tag == null) {
            throw new IllegalArgumentException("getDestinationPathFromTag: Tag must be non-null");
        }

        return tag.substring(tag.indexOf(TAG_SEPARATOR) + 1);
    }

    class MoveFileTask extends AsyncTask<String, Integer, Boolean> {
        private String mSrcPath;
        private String mDstPath;

        @Override
        protected Boolean doInBackground(String... params) {
            mSrcPath = params[0];
            mDstPath = params[1];
            try {
                CommandHelper.move(MoveFileService.this, mSrcPath, mDstPath, null);
            } catch (Exception e) {
                return Boolean.FALSE;
            }

            return Boolean.TRUE;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if (Boolean.TRUE.equals(result)) {
                showFileMovedNotification(getTagForNotification(mSrcPath, mDstPath), mDstPath);
            } else {
                // TODO: store error type so we can show the appropriate notification
                showFileMoveFailedNotification(getTagForNotification(mSrcPath, mDstPath),
                        R.string.moving_file_failed_generic);
            }
        }
    }
}