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