/*
* Copyright (C) 2011-14 asksven
*
* 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.asksven.betterbatterystats.services;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import com.asksven.android.common.privateapiproxies.BatteryStatsProxy;
import com.asksven.android.common.privateapiproxies.Misc;
import com.asksven.android.common.privateapiproxies.StatElement;
import com.asksven.android.common.utils.DateUtils;
import com.asksven.betterbatterystats.R;
import com.asksven.betterbatterystats.StatsActivity;
import com.asksven.betterbatterystats.appanalytics.Analytics;
import com.asksven.betterbatterystats.appanalytics.Events;
import com.asksven.betterbatterystats.data.Reference;
import com.asksven.betterbatterystats.data.ReferenceStore;
import com.asksven.betterbatterystats.data.StatsProvider;
import com.asksven.betterbatterystats.widgetproviders.LargeWidgetProvider;
import java.util.ArrayList;
/**
* @author sven
*
*/
public class WatchdogProcessingService extends IntentService
{
private static final String TAG = "WatchdogProcService";
public WatchdogProcessingService()
{
super("WatchdogProcessingService");
}
@Override
public void onHandleIntent(Intent intent)
{
Log.i(TAG, "Called at " + DateUtils.now());
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
try
{
if (true)
{
Analytics.getInstance(this).trackEvent(Events.EVENT_PROCESS_WATCHDOG);
int minScreenOffDurationMin = sharedPrefs.getInt("watchdog_duration_threshold", 10);
int awakeThresholdPct = sharedPrefs.getInt("watchdog_awake_threshold", 30);
long now = System.currentTimeMillis();
Long screenOffTime = sharedPrefs.getLong("screen_went_off_at", now );
Long screenOffDurationMs = now - screenOffTime;
// we process only if screenOffDuration is >= minScreenOffDuration
if (screenOffDurationMs >= ((long)minScreenOffDurationMin*60*1000))
{
//Toast.makeText(this, getString(R.string.message_watchdog_processing), Toast.LENGTH_SHORT).show();
int awakePct = 0;
StatsProvider stats = StatsProvider.getInstance(this);
// make sure to flush cache
BatteryStatsProxy.getInstance(this).invalidate();
// save screen on reference
Intent serviceIntent = new Intent(this.getApplicationContext(), WriteScreenOnReferenceService.class);
this.startService(serviceIntent);
if (stats.hasScreenOffRef())
{
// restore any available since screen reference
Reference refFrom = ReferenceStore.getReferenceByName(Reference.SCREEN_OFF_REF_FILENAME, this);
StatsProvider.getInstance(this).setCurrentReference(0);
//Reference refTo = StatsProvider.getInstance(this).getUncachedPartialReference(0);
Reference refTo = ReferenceStore.getReferenceByName(Reference.CURRENT_REF_FILENAME, this);
ArrayList<StatElement> otherStats = null;
// only process if both references are in the right order
if (refFrom.getCreationTime() < refTo.getCreationTime())
{
otherStats = stats.getOtherUsageStatList(true, refFrom, false, false, refTo);
}
else
{
otherStats = null;
}
long timeAwake = 0;
long timeSince = 0;
if ( (otherStats != null) && ( otherStats.size() > 1) )
{
timeAwake = ((Misc) stats.getElementByKey(otherStats, StatsProvider.LABEL_MISC_AWAKE)).getTimeOn();
timeSince = stats.getBatteryRealtime(StatsProvider.STATS_SCREEN_OFF);
Log.i(TAG, "Other stats found. Since=" + timeSince + ", Awake=" + timeAwake);
}
else
{
// no stats means the phone was awake
timeSince = stats.getBatteryRealtime(StatsProvider.STATS_SCREEN_OFF);
timeAwake = timeSince;
Log.i(TAG, "Other stats do not have any data. Since=" + timeSince + ", Awake=" + timeAwake);
}
if (timeSince > 0)
{
awakePct = (int) ((timeAwake *100 / timeSince));
}
else
{
awakePct = 0;
}
Log.i(TAG, "Awake %=" + awakePct);
// we issue a warning if awakePct > awakeThresholdPct
if (awakePct >= awakeThresholdPct)
{
// Instantiate a Builder object.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
String alertText = "";
try
{
alertText = getString(R.string.message_awake_info, awakePct);
}
catch (Exception e)
{
alertText = getString(R.string.message_awake_alert);
}
builder.setSmallIcon(R.drawable.ic_stat_notification);
builder.setContentTitle(this.getText(R.string.app_name));
builder.setContentText(alertText);
// Creates an Intent for the Activity
Intent i = new Intent(Intent.ACTION_MAIN);
PackageManager manager = this.getPackageManager();
i = manager.getLaunchIntentForPackage(this.getPackageName());
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra(StatsActivity.STAT, 0);
i.putExtra(StatsActivity.STAT_TYPE_FROM, Reference.SCREEN_OFF_REF_FILENAME);
i.putExtra(StatsActivity.STAT_TYPE_TO, Reference.SCREEN_ON_REF_FILENAME);
i.putExtra(StatsActivity.FROM_NOTIFICATION, true);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
// Puts the PendingIntent into the notification builder
builder.setContentIntent(contentIntent);
// Notifications are issued by sending them to the
// NotificationManager system service.
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Builds an anonymous Notification object from the builder, and
// passes it to the NotificationManager
mNotificationManager.notify(EventWatcherService.NOTFICATION_ID, builder.build());
}
}
}
else
{
// delete screen on ref
ReferenceStore.invalidate(Reference.SCREEN_ON_REF_FILENAME, this);
}
// Build the intent to update the widget
Intent intentRefreshWidgets = new Intent(LargeWidgetProvider.WIDGET_UPDATE);
this.sendBroadcast(intentRefreshWidgets);
}
}
catch (Exception e)
{
Log.e(TAG, "An error occured: " + e.getMessage());
}
stopSelf();
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
}