/* * CatSaver * Copyright (C) 2015 HiHex Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. * */ package hihex.cs; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.os.Build; import android.os.IBinder; import android.util.DisplayMetrics; import android.widget.Toast; import java.io.IOException; public final class CollectorService extends Service { private Thread mLogCollectorThread; private WebServer mWebServer; private RecIndicator mRecIndicator; private BroadcastReceiver mIpChangeReceiver; private Config mConfig; @Override public IBinder onBind(final Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); // Put the service in "foreground". This makes the system harder to kill it (?). final CharSequence title = getResources().getString(R.string.app_name); final CharSequence detail = getResources().getString(R.string.running_hint); final Intent intent = new Intent(this, MainActivity.class); final Notification.Builder notificationBuilder = new Notification.Builder(this) .setSmallIcon(R.drawable.notification_icon) .setContentTitle(title) .setContentText(detail) .setOngoing(true) .setContentIntent(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); final Notification notification; if (Build.VERSION.SDK_INT >= 16) { notification = notificationBuilder.setPriority(Notification.PRIORITY_LOW).build(); } else { //noinspection deprecation notification = notificationBuilder.getNotification(); } startForeground(1, notification); // Prepare the configuration. final Config config = new Config(this); config.refreshPids(); mConfig = config; // Start the web server @SuppressWarnings("deprecation") final Drawable icon = getResources().getDrawableForDensity(R.mipmap.ic_launcher, DisplayMetrics.DENSITY_LOW); mWebServer = new WebServer(config, icon); try { mWebServer.start(); } catch (final IOException e) { CsLog.e("Cannot start web-server. " + e); } // Show the recording indicator mRecIndicator = new RecIndicator(config); monitorIpAddress(); Events.bus.post(new Events.UpdateIpAddress()); // Start collecting logs for existing processes. config.startRecordingExistingProcesses(); // Start collecting logs final LogRecorder runnable = new LogRecorder(config); mLogCollectorThread = new Thread(runnable, "Log collector"); mLogCollectorThread.start(); Toast.makeText(this, R.string.running_hint, Toast.LENGTH_LONG).show(); } @Override public void onDestroy() { Toast.makeText(this, R.string.stopping_hint, Toast.LENGTH_LONG).show(); mLogCollectorThread = null; mRecIndicator = null; if (mWebServer != null) { mWebServer.stop(); mWebServer = null; } if (mIpChangeReceiver != null) { unregisterReceiver(mIpChangeReceiver); mIpChangeReceiver = null; } super.onDestroy(); } private void monitorIpAddress() { mIpChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Events.bus.post(new Events.UpdateIpAddress()); } }; final IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(mIpChangeReceiver, filter); } }