1/*
2 * Copyright (C) 2008 Esmertec AG.
3 * Copyright (C) 2008 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mms.transaction;
19
20import java.io.IOException;
21import java.io.OutputStream;
22
23import org.apache.http.entity.ByteArrayEntity;
24
25import android.content.Context;
26import android.content.Intent;
27
28public class ProgressCallbackEntity extends ByteArrayEntity {
29    private static final int DEFAULT_PIECE_SIZE = 4096;
30
31    public static final String PROGRESS_STATUS_ACTION = "com.android.mms.PROGRESS_STATUS";
32    public static final int PROGRESS_START    = -1;
33    public static final int PROGRESS_ABORT    = -2;
34    public static final int PROGRESS_COMPLETE = 100;
35
36    private final Context mContext;
37    private final byte[] mContent;
38    private final long mToken;
39
40    public ProgressCallbackEntity(Context context, long token, byte[] b) {
41        super(b);
42
43        mContext = context;
44        mContent = b;
45        mToken = token;
46    }
47
48    @Override
49    public void writeTo(final OutputStream outstream) throws IOException {
50        if (outstream == null) {
51            throw new IllegalArgumentException("Output stream may not be null");
52        }
53
54        boolean completed = false;
55        try {
56            broadcastProgressIfNeeded(PROGRESS_START);
57
58            int pos = 0, totalLen = mContent.length;
59            while (pos < totalLen) {
60                int len = totalLen - pos;
61                if (len > DEFAULT_PIECE_SIZE) {
62                    len = DEFAULT_PIECE_SIZE;
63                }
64                outstream.write(mContent, pos, len);
65                outstream.flush();
66
67                pos += len;
68
69                broadcastProgressIfNeeded(100 * pos / totalLen);
70            }
71
72            broadcastProgressIfNeeded(PROGRESS_COMPLETE);
73            completed = true;
74        } finally {
75            if (!completed) {
76                broadcastProgressIfNeeded(PROGRESS_ABORT);
77            }
78        }
79    }
80
81    private void broadcastProgressIfNeeded(int progress) {
82        if (mToken > 0) {
83            Intent intent = new Intent(PROGRESS_STATUS_ACTION);
84            intent.putExtra("progress", progress);
85            intent.putExtra("token", mToken);
86            mContext.sendBroadcast(intent);
87        }
88    }
89}
90