use of uk.co.yahoo.p1rpp.calendartrigger.calendar.CalendarProvider in project CalendarTrigger by rparkins999.
the class MuteService method updateState.
// Determine which event classes have become active
// and which event classes have become inactive
// and consequently what we need to do.
// Incidentally we compute the next alarm time.
@TargetApi(Build.VERSION_CODES.M)
public void updateState(Intent intent) {
// Timestamp used in all requests (so it remains consistent)
long currentTime = System.currentTimeMillis();
long nextTime = currentTime + FIVE_MINUTES;
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int wantedMode = PrefsManager.RINGER_MODE_NONE;
int user = PrefsManager.getUserRinger(this);
int last = PrefsManager.getLastRinger(this);
int current = PrefsManager.getCurrentMode(this);
new MyLog(this, "last mode is " + PrefsManager.getEnglishStateName(this, last) + ", current mode is " + PrefsManager.getEnglishStateName(this, current));
/* This will do the wrong thing if the user changes the mode during the
* one second that we are waiting for Android to set the new mode, but
* there seems to be no workaround because Android is a bit
* unpredictable in this area. Since Android can delay setting the
* mode that we asked for, or even set a different mode, but doesn't
* always do so, we can't tell if a change was done by Android or by the
* user.
*/
if ((last != current) && (last != PrefsManager.RINGER_MODE_NONE) && (!mHandler.hasMessages(what))) {
// user changed ringer mode
user = current;
PrefsManager.setUserRinger(this, user);
new MyLog(this, "Setting user ringer to " + PrefsManager.getEnglishStateName(this, user));
}
long nextAlarmTime = Long.MAX_VALUE;
nextAccelTime = Long.MAX_VALUE;
int classNum;
String startEvent = "";
String startClassName = "";
int startClassNum = 0;
String endEvent = "";
String endClassName = "";
int endClassNum = 0;
String alarmReason = "";
boolean startNotifyWanted = false;
boolean endNotifyWanted = false;
int phoneState = UpdatePhoneState(intent);
boolean anyStepCountActive = false;
boolean anyLocationActive = false;
PackageManager packageManager = getPackageManager();
final boolean haveStepCounter = currentApiVersion >= android.os.Build.VERSION_CODES.KITKAT && packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER);
final boolean havelocation = PackageManager.PERMISSION_GRANTED == PermissionChecker.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
if (PrefsManager.getStepCount(this) >= 0) {
new MyLog(this, "Step counter running");
}
int n = PrefsManager.getNumClasses(this);
CalendarProvider provider = new CalendarProvider(this);
for (classNum = 0; classNum < n; ++classNum) {
if (PrefsManager.isClassUsed(this, classNum)) {
String className = PrefsManager.getClassName(this, classNum);
int ringerAction = PrefsManager.getRingerAction(this, classNum);
CalendarProvider.startAndEnd result = provider.nextActionTimes(this, currentTime, classNum);
// true if user requested immediate event of this class
boolean triggered = PrefsManager.isClassTriggered(this, classNum);
// true if an event of this class should be currently active
boolean active = (result.startTime <= currentTime) && (result.endTime > currentTime);
if (triggered) {
long after = PrefsManager.getAfterMinutes(this, classNum) * 60000;
if (after > 0) {
long triggerEnd = currentTime + after;
if ((active && (triggerEnd > result.endTime)) || ((!active) && (triggerEnd < result.startTime))) {
result.endEventName = "<immediate>";
result.endTime = triggerEnd;
}
PrefsManager.setLastTriggerEnd(this, classNum, result.endTime);
} else if (!active) {
// We will start the event (possibly after a state
// delay) and end it immediately: this is probably not
// a useful case, but we have to handle it correctly.
result.endEventName = "<immediate>";
// We do need this because we may have found an event
// which starts and ends in the future.
result.endTime = currentTime;
}
if (!active) {
result.startEventName = "<immediate>";
result.startTime = currentTime;
}
if (after > 0) {
// need to do this after above test
active = true;
}
}
if (triggered || active) {
if (!PrefsManager.isClassActive(this, classNum)) {
// need to start this class
// True if not ready to start it yet.
boolean notNow = phoneState == PrefsManager.PHONE_CALL_ACTIVE;
if (!notNow) {
notNow = checkOrientationWait(classNum, true);
new MyLog(this, "checkOrientationWait(" + className + ", true) returns " + (notNow ? "true" : "false"));
if (notNow) {
if ((nextAccelTime < nextAlarmTime) && (nextAccelTime > currentTime)) {
nextAlarmTime = nextAccelTime;
alarmReason = " for next orientation check for event ".concat(result.startEventName).concat(" of class ").concat(className);
}
} else {
notNow = checkConnectionWait(classNum, true);
if (notNow) {
if (nextTime < nextAlarmTime) {
nextAlarmTime = nextTime;
alarmReason = (" for next connection check for " + "event ").concat(result.startEventName).concat(" of class ").concat(className);
}
}
}
}
if (notNow) {
// we can't start it yet
triggered = false;
active = false;
result.endTime = Long.MAX_VALUE;
} else {
if (ringerAction > wantedMode) {
if (PrefsManager.getNotifyStart(this, classNum)) {
startNotifyWanted = true;
}
startEvent = result.startEventName;
startClassName = className;
startClassNum = classNum;
PrefsManager.setTargetSteps(this, classNum, 0);
PrefsManager.setLatitude(this, classNum, 360.0);
PrefsManager.setClassActive(this, classNum, true);
}
}
}
}
if (// may have changed
active) {
// class should be currently active
if (ringerAction > wantedMode) {
wantedMode = ringerAction;
}
PrefsManager.setLastActive(this, classNum, result.endEventName);
}
if (!active) {
// class should not be currently active
// check if we're waiting for movement
boolean done = false;
boolean waiting = false;
int lastCounterSteps = PrefsManager.getStepCount(this);
int aftersteps = PrefsManager.getAfterSteps(this, classNum);
if (PrefsManager.isClassActive(this, classNum)) {
done = true;
if (haveStepCounter && (aftersteps > 0)) {
if (lastCounterSteps < 0) {
// need to start up the sensor
if (StartStepCounter(classNum)) {
PrefsManager.setTargetSteps(this, classNum, 0);
anyStepCountActive = true;
waiting = true;
done = false;
}
} else // sensor already running
{
PrefsManager.setTargetSteps(this, classNum, lastCounterSteps + aftersteps);
anyStepCountActive = true;
new MyLog(this, "Setting target steps for class " + className + " to " + String.valueOf(lastCounterSteps) + " + " + String.valueOf(aftersteps));
waiting = true;
done = false;
}
}
if (havelocation && (PrefsManager.getAfterMetres(this, classNum) > 0)) {
// keep it active while waiting for location
startLocationWait(classNum, intent);
anyLocationActive = true;
waiting = true;
done = false;
}
if (checkOrientationWait(classNum, false)) {
if ((nextAccelTime < nextAlarmTime) && (nextAccelTime > currentTime)) {
nextAlarmTime = nextAccelTime;
alarmReason = " for next orientation check for event ".concat(result.endEventName).concat(" of class ").concat(className);
}
waiting = true;
done = false;
} else if (checkConnectionWait(classNum, false)) {
if (nextTime < nextAlarmTime) {
nextAlarmTime = nextTime;
alarmReason = (" for next connection check for " + "event ").concat(result.endEventName).concat(" of class ").concat(className);
}
waiting = true;
done = false;
}
PrefsManager.setClassActive(this, classNum, false);
}
if (PrefsManager.isClassWaiting(this, classNum)) {
done = true;
if ((lastCounterSteps != PrefsManager.STEP_COUNTER_IDLE) && (aftersteps > 0)) {
int steps = PrefsManager.getTargetSteps(this, classNum);
if (steps == 0) {
if (lastCounterSteps >= 0) {
PrefsManager.setTargetSteps(this, classNum, lastCounterSteps + aftersteps);
}
anyStepCountActive = true;
new MyLog(this, "Setting target steps for class " + className + " to " + String.valueOf(lastCounterSteps) + " + " + String.valueOf(aftersteps));
waiting = true;
done = false;
} else if (lastCounterSteps < steps) {
anyStepCountActive = true;
waiting = true;
done = false;
}
}
double latitude = PrefsManager.getLatitude(this, classNum);
if ((latitude != 360.0) && checkLocationWait(classNum, latitude, intent)) {
anyLocationActive = true;
waiting = true;
done = false;
}
if (checkOrientationWait(classNum, false)) {
if ((nextAccelTime < nextAlarmTime) && (nextAccelTime > currentTime)) {
nextAlarmTime = nextAccelTime;
alarmReason = " for next orientation check for event ".concat(result.endEventName).concat(" of class ").concat(className);
}
waiting = true;
done = false;
} else if (checkConnectionWait(classNum, false)) {
if (nextTime < nextAlarmTime) {
nextAlarmTime = nextTime;
alarmReason = (" for next connection check for " + "event ").concat(result.endEventName).concat(" of class ").concat(className);
}
waiting = true;
done = false;
}
} else if (waiting) {
PrefsManager.setClassWaiting(this, classNum, true);
}
if (done) {
if ((PrefsManager.getRestoreRinger(this, classNum)) || (endEvent.isEmpty())) {
if (PrefsManager.getNotifyEnd(this, classNum)) {
endNotifyWanted = true;
endEvent = PrefsManager.getLastActive(this, classNum);
endClassName = className;
endClassNum = classNum;
}
}
PrefsManager.setClassActive(this, classNum, false);
PrefsManager.setClassWaiting(this, classNum, false);
} else if (waiting && (wantedMode < ringerAction)) {
wantedMode = ringerAction;
}
}
if ((result.endTime < nextAlarmTime) && (result.endTime > currentTime)) {
nextAlarmTime = result.endTime;
alarmReason = " for end of event ".concat(result.endEventName).concat(" of class ").concat(className);
}
if ((result.startTime < nextAlarmTime) && (result.startTime > currentTime)) {
nextAlarmTime = result.startTime;
alarmReason = " for start of event ".concat(result.startEventName).concat(" of class ").concat(className);
}
if (triggered) {
PrefsManager.setClassTriggered(this, classNum, false);
}
}
}
if ((PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)) && (PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS)) && (PrefsManager.getNextLocationMode(this))) {
CalendarProvider.StartAndLocation sl = provider.nextLocation(this, currentTime);
if (sl != null) {
ContactCreator cc = new ContactCreator(this);
cc.makeContact("!NextEventLocation", "", sl.location);
long slst = sl.startTime + 60000;
if ((slst < nextAlarmTime) && (slst > currentTime)) {
nextAlarmTime = slst;
alarmReason = " after start of event ".concat(sl.eventName);
}
}
}
String shortText;
String longText;
if (wantedMode < user) {
wantedMode = user;
} else if (wantedMode == PrefsManager.RINGER_MODE_NONE) {
wantedMode = PrefsManager.RINGER_MODE_NORMAL;
}
boolean changed = setCurrentRinger(audio, currentApiVersion, wantedMode, current);
if (changed) {
shortText = PrefsManager.getRingerStateName(this, wantedMode);
} else {
shortText = getString(R.string.ringerModeNone);
}
if (endNotifyWanted) {
longText = shortText + " " + getString(R.string.eventend) + " " + endEvent + " " + getString(R.string.ofclass) + " " + endClassName;
if (PrefsManager.getPlaysoundEnd(this, endClassNum)) {
String path = PrefsManager.getSoundFileEnd(this, endClassNum);
emitNotification(longText, path);
} else if (changed && (wantedMode < current)) {
emitNotification(longText, "");
}
}
if (startNotifyWanted) {
longText = shortText + " " + getString(R.string.eventstart) + " " + startEvent + " " + getString(R.string.ofclass) + " " + startClassName;
if (PrefsManager.getPlaysoundStart(this, startClassNum)) {
String path = PrefsManager.getSoundFileStart(this, startClassNum);
emitNotification(longText, path);
} else if (changed) {
emitNotification(longText, "");
}
}
if (startEvent != "") {
new MyLog(this, "Setting audio mode to " + PrefsManager.getEnglishStateName(this, wantedMode) + " for start of event " + startEvent + " of class " + startClassName);
} else if (endEvent != "") {
new MyLog(this, "Setting audio mode to " + PrefsManager.getEnglishStateName(this, wantedMode) + " for end of event " + endEvent + " of class " + endClassName);
} else if (resetting) {
new MyLog(this, "Setting audio mode to " + PrefsManager.getEnglishStateName(this, wantedMode) + " after reset");
}
resetting = false;
PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, /*requestCode*/
new Intent("CalendarTrigger.Alarm", Uri.EMPTY, this, StartServiceReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// silently fail to do so if the alarm time is too soon
if (PrefsManager.getLastAlarmTime(this) != nextAlarmTime) {
if (nextAlarmTime == Long.MAX_VALUE) {
alarmManager.cancel(pIntent);
new MyLog(this, "Alarm cancelled");
} else {
if (currentApiVersion >= android.os.Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextAlarmTime, pIntent);
} else {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, nextAlarmTime, pIntent);
}
DateFormat df = DateFormat.getDateTimeInstance();
new MyLog(this, "Alarm time set to ".concat(df.format(nextAlarmTime)).concat(alarmReason));
PrefsManager.setLastAlarmTime(this, nextAlarmTime);
}
}
PrefsManager.setLastInvocationTime(this, currentTime);
if (!anyStepCountActive) {
if (PrefsManager.getStepCount(this) != PrefsManager.STEP_COUNTER_IDLE) {
PrefsManager.setStepCount(this, PrefsManager.STEP_COUNTER_IDLE);
SensorManager sensorManager = (SensorManager) getSystemService(Activity.SENSOR_SERVICE);
sensorManager.unregisterListener(this);
new MyLog(this, "Step counter deactivated");
}
}
if (!anyLocationActive) {
if (PrefsManager.getLocationState(this)) {
LocationUpdates(0, PrefsManager.LATITUDE_IDLE);
}
}
unlock();
}
Aggregations