• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.android.inputmethod.research;
18 
19 import android.Manifest;
20 import android.app.AlarmManager;
21 import android.app.IntentService;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.content.pm.PackageManager;
26 import android.net.ConnectivityManager;
27 import android.net.NetworkInfo;
28 import android.os.BatteryManager;
29 import android.os.Bundle;
30 import android.util.Log;
31 
32 import com.android.inputmethod.latin.R;
33 
34 import java.io.BufferedReader;
35 import java.io.File;
36 import java.io.FileFilter;
37 import java.io.FileInputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.InputStreamReader;
41 import java.io.OutputStream;
42 import java.net.HttpURLConnection;
43 import java.net.MalformedURLException;
44 import java.net.URL;
45 
46 public final class UploaderService extends IntentService {
47     private static final String TAG = UploaderService.class.getSimpleName();
48     public static final long RUN_INTERVAL = AlarmManager.INTERVAL_HOUR;
49     private static final String EXTRA_UPLOAD_UNCONDITIONALLY = UploaderService.class.getName()
50             + ".extra.UPLOAD_UNCONDITIONALLY";
51     private static final int BUF_SIZE = 1024 * 8;
52     protected static final int TIMEOUT_IN_MS = 1000 * 4;
53 
54     private boolean mCanUpload;
55     private File mFilesDir;
56     private URL mUrl;
57 
UploaderService()58     public UploaderService() {
59         super("Research Uploader Service");
60     }
61 
62     @Override
onCreate()63     public void onCreate() {
64         super.onCreate();
65 
66         mCanUpload = false;
67         mFilesDir = null;
68         mUrl = null;
69 
70         final PackageManager packageManager = getPackageManager();
71         final boolean hasPermission = packageManager.checkPermission(Manifest.permission.INTERNET,
72                 getPackageName()) == PackageManager.PERMISSION_GRANTED;
73         if (!hasPermission) {
74             return;
75         }
76 
77         try {
78             final String urlString = getString(R.string.research_logger_upload_url);
79             if (urlString == null || urlString.equals("")) {
80                 return;
81             }
82             mFilesDir = getFilesDir();
83             mUrl = new URL(urlString);
84             mCanUpload = true;
85         } catch (MalformedURLException e) {
86             e.printStackTrace();
87         }
88     }
89 
90     @Override
onHandleIntent(Intent intent)91     protected void onHandleIntent(Intent intent) {
92         if (!mCanUpload) {
93             return;
94         }
95         boolean isUploadingUnconditionally = false;
96         Bundle bundle = intent.getExtras();
97         if (bundle != null && bundle.containsKey(EXTRA_UPLOAD_UNCONDITIONALLY)) {
98             isUploadingUnconditionally = bundle.getBoolean(EXTRA_UPLOAD_UNCONDITIONALLY);
99         }
100         doUpload(isUploadingUnconditionally);
101     }
102 
isExternallyPowered()103     private boolean isExternallyPowered() {
104         final Intent intent = registerReceiver(null, new IntentFilter(
105                 Intent.ACTION_BATTERY_CHANGED));
106         final int pluggedState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
107         return pluggedState == BatteryManager.BATTERY_PLUGGED_AC
108                 || pluggedState == BatteryManager.BATTERY_PLUGGED_USB;
109     }
110 
hasWifiConnection()111     private boolean hasWifiConnection() {
112         final ConnectivityManager manager =
113                 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
114         final NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
115         return wifiInfo.isConnected();
116     }
117 
doUpload(final boolean isUploadingUnconditionally)118     private void doUpload(final boolean isUploadingUnconditionally) {
119         if (!isUploadingUnconditionally && (!isExternallyPowered() || !hasWifiConnection())) {
120             return;
121         }
122         if (mFilesDir == null) {
123             return;
124         }
125         final File[] files = mFilesDir.listFiles(new FileFilter() {
126             @Override
127             public boolean accept(File pathname) {
128                 return pathname.getName().startsWith(ResearchLogger.FILENAME_PREFIX)
129                         && !pathname.canWrite();
130             }
131         });
132         boolean success = true;
133         if (files.length == 0) {
134             success = false;
135         }
136         for (final File file : files) {
137             if (!uploadFile(file)) {
138                 success = false;
139             }
140         }
141     }
142 
uploadFile(File file)143     private boolean uploadFile(File file) {
144         Log.d(TAG, "attempting upload of " + file.getAbsolutePath());
145         boolean success = false;
146         final int contentLength = (int) file.length();
147         HttpURLConnection connection = null;
148         InputStream fileInputStream = null;
149         try {
150             fileInputStream = new FileInputStream(file);
151             connection = (HttpURLConnection) mUrl.openConnection();
152             connection.setRequestMethod("PUT");
153             connection.setDoOutput(true);
154             connection.setFixedLengthStreamingMode(contentLength);
155             final OutputStream os = connection.getOutputStream();
156             final byte[] buf = new byte[BUF_SIZE];
157             int numBytesRead;
158             while ((numBytesRead = fileInputStream.read(buf)) != -1) {
159                 os.write(buf, 0, numBytesRead);
160             }
161             if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
162                 Log.d(TAG, "upload failed: " + connection.getResponseCode());
163                 InputStream netInputStream = connection.getInputStream();
164                 BufferedReader reader = new BufferedReader(new InputStreamReader(netInputStream));
165                 String line;
166                 while ((line = reader.readLine()) != null) {
167                     Log.d(TAG, "| " + reader.readLine());
168                 }
169                 reader.close();
170                 return success;
171             }
172             file.delete();
173             success = true;
174             Log.d(TAG, "upload successful");
175         } catch (Exception e) {
176             e.printStackTrace();
177         } finally {
178             if (fileInputStream != null) {
179                 try {
180                     fileInputStream.close();
181                 } catch (IOException e) {
182                     e.printStackTrace();
183                 }
184             }
185             if (connection != null) {
186                 connection.disconnect();
187             }
188         }
189         return success;
190     }
191 }
192