Merge "Update 'next alarm' tracking"
This commit is contained in:
committed by
Android (Google) Code Review
commit
15f4ac5a94
@@ -890,7 +890,17 @@ public class ZenModeConfig implements Parcelable {
|
||||
}
|
||||
|
||||
public static boolean isValidScheduleConditionId(Uri conditionId) {
|
||||
return tryParseScheduleConditionId(conditionId) != null;
|
||||
ScheduleInfo info;
|
||||
try {
|
||||
info = tryParseScheduleConditionId(conditionId);
|
||||
} catch (NullPointerException | ArrayIndexOutOfBoundsException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info == null || info.days == null || info.days.length == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ScheduleInfo tryParseScheduleConditionId(Uri conditionId) {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.systemui.HardwareUiLayout
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -45,4 +45,4 @@
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</com.android.systemui.HardwareUiLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -19,6 +19,9 @@ package com.android.systemui.volume;
|
||||
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
|
||||
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
|
||||
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
|
||||
import static com.android.systemui.volume.Events.DISMISS_REASON_TOUCH_OUTSIDE;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
@@ -42,6 +45,7 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -67,6 +71,7 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.HardwareBgDrawable;
|
||||
import com.android.systemui.HardwareUiLayout;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
@@ -74,6 +79,7 @@ import com.android.systemui.plugins.VolumeDialog;
|
||||
import com.android.systemui.plugins.VolumeDialogController;
|
||||
import com.android.systemui.plugins.VolumeDialogController.State;
|
||||
import com.android.systemui.plugins.VolumeDialogController.StreamState;
|
||||
import com.android.systemui.util.leak.RotationUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -97,9 +103,13 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
private final VolumeDialogController mController;
|
||||
|
||||
private Window mWindow;
|
||||
private HardwareUiLayout mHardwareLayout;
|
||||
//private HardwareUiLayout mHardwareLayout;
|
||||
private CustomDialog mDialog;
|
||||
private ViewGroup mDialogView;
|
||||
private boolean mEdgeBleed;
|
||||
private boolean mRoundedDivider;
|
||||
private HardwareBgDrawable mBackground;
|
||||
private int mRotation = ROTATION_NONE;
|
||||
private ViewGroup mDialogRowsView;
|
||||
private ViewGroup mDialogContentView;
|
||||
private final List<VolumeRow> mRows = new ArrayList<>();
|
||||
@@ -111,6 +121,8 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
private final Accessibility mAccessibility = new Accessibility();
|
||||
private final ColorStateList mActiveSliderTint;
|
||||
private final ColorStateList mInactiveSliderTint;
|
||||
private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
|
||||
private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
|
||||
|
||||
private boolean mShowing;
|
||||
private boolean mShowA11yStream;
|
||||
@@ -181,8 +193,16 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
mHardwareLayout = HardwareUiLayout.get(mDialogView);
|
||||
mHardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE));
|
||||
|
||||
mEdgeBleed = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
EDGE_BLEED, 0) != 0;
|
||||
mRoundedDivider = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
ROUNDED_DIVIDER, 1) != 0;
|
||||
updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
|
||||
mBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, mContext);
|
||||
mDialogView.setBackground(mBackground);
|
||||
//mHardwareLayout = HardwareUiLayout.get(mDialogView);
|
||||
//mHardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE));
|
||||
|
||||
mDialogContentView = mDialog.findViewById(R.id.volume_dialog_content);
|
||||
mDialogRowsView = mDialogContentView.findViewById(R.id.volume_dialog_rows);
|
||||
@@ -210,6 +230,25 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
updateRowsH(getActiveRow());
|
||||
}
|
||||
|
||||
private int getEdgePadding() {
|
||||
return mContext.getResources().getDimensionPixelSize(R.dimen.edge_margin);
|
||||
}
|
||||
|
||||
private void updateEdgeMargin(int edge) {
|
||||
if (mDialogView != null) {
|
||||
mRotation = RotationUtils.getRotation(mContext);
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mDialogView.getLayoutParams();
|
||||
if (mRotation == ROTATION_LANDSCAPE) {
|
||||
params.topMargin = edge;
|
||||
} else if (mRotation == ROTATION_SEASCAPE) {
|
||||
params.bottomMargin = edge;
|
||||
} else {
|
||||
params.rightMargin = edge;
|
||||
}
|
||||
mDialogView.setLayoutParams(params);
|
||||
}
|
||||
}
|
||||
|
||||
private ColorStateList loadColorStateList(int colorResId) {
|
||||
return ColorStateList.valueOf(mContext.getColor(colorResId));
|
||||
}
|
||||
@@ -389,11 +428,11 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
rescheduleTimeoutH();
|
||||
if (mShowing) return;
|
||||
mShowing = true;
|
||||
mHardwareLayout.setTranslationX(getAnimTranslation());
|
||||
mHardwareLayout.setAlpha(0);
|
||||
mHardwareLayout.animate()
|
||||
mDialogView.setTranslationY(getAnimTranslation());
|
||||
mDialogView.setAlpha(0);
|
||||
mDialogView.animate()
|
||||
.alpha(1)
|
||||
.translationX(0)
|
||||
.translationY(0)
|
||||
.setDuration(300)
|
||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
||||
.withEndAction(() -> {
|
||||
@@ -432,9 +471,9 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mHandler.removeMessages(H.SHOW);
|
||||
if (!mShowing) return;
|
||||
mShowing = false;
|
||||
mHardwareLayout.setTranslationX(0);
|
||||
mHardwareLayout.setAlpha(1);
|
||||
mHardwareLayout.animate()
|
||||
mDialogView.setTranslationX(0);
|
||||
mDialogView.setAlpha(1);
|
||||
mDialogView.animate()
|
||||
.alpha(0)
|
||||
.translationX(getAnimTranslation())
|
||||
.setDuration(300)
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.notification;
|
||||
|
||||
import android.service.notification.ZenModeConfig.ScheduleInfo;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Objects;
|
||||
@@ -41,10 +42,25 @@ public class ScheduleCalendar {
|
||||
}
|
||||
|
||||
public void maybeSetNextAlarm(long now, long nextAlarm) {
|
||||
if (mSchedule != null) {
|
||||
if (mSchedule.exitAtAlarm
|
||||
&& (now > mSchedule.nextAlarm || nextAlarm < mSchedule.nextAlarm)) {
|
||||
mSchedule.nextAlarm = nextAlarm;
|
||||
if (mSchedule != null && mSchedule.exitAtAlarm) {
|
||||
// alarm canceled
|
||||
if (nextAlarm == 0) {
|
||||
mSchedule.nextAlarm = 0;
|
||||
}
|
||||
// only allow alarms in the future
|
||||
if (nextAlarm > now) {
|
||||
// store earliest alarm
|
||||
if (mSchedule.nextAlarm == 0) {
|
||||
mSchedule.nextAlarm = nextAlarm;
|
||||
} else {
|
||||
mSchedule.nextAlarm = Math.min(mSchedule.nextAlarm, nextAlarm);
|
||||
}
|
||||
} else if (mSchedule.nextAlarm < now) {
|
||||
if (ScheduleConditionProvider.DEBUG) {
|
||||
Log.d(ScheduleConditionProvider.TAG,
|
||||
"All alarms are in the past " + mSchedule.nextAlarm);
|
||||
}
|
||||
mSchedule.nextAlarm = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,6 +103,9 @@ public class ScheduleCalendar {
|
||||
}
|
||||
|
||||
public boolean shouldExitForAlarm(long time) {
|
||||
if (mSchedule == null) {
|
||||
return false;
|
||||
}
|
||||
return mSchedule.exitAtAlarm
|
||||
&& mSchedule.nextAlarm != 0
|
||||
&& time >= mSchedule.nextAlarm;
|
||||
|
||||
@@ -37,6 +37,8 @@ import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.notification.NotificationManagerService.DumpFilter;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -62,10 +64,9 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
|
||||
private static final String SEPARATOR = ";";
|
||||
private static final String SCP_SETTING = "snoozed_schedule_condition_provider";
|
||||
|
||||
|
||||
private final Context mContext = this;
|
||||
private final ArrayMap<Uri, ScheduleCalendar> mSubscriptions = new ArrayMap<>();
|
||||
private ArraySet<Uri> mSnoozed = new ArraySet<>();
|
||||
private ArraySet<Uri> mSnoozedForAlarm = new ArraySet<>();
|
||||
|
||||
private AlarmManager mAlarmManager;
|
||||
private boolean mConnected;
|
||||
@@ -102,7 +103,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
|
||||
pw.println(mSubscriptions.get(conditionId).toString());
|
||||
}
|
||||
}
|
||||
pw.println(" snoozed due to alarm: " + TextUtils.join(SEPARATOR, mSnoozed));
|
||||
pw.println(" snoozed due to alarm: " + TextUtils.join(SEPARATOR, mSnoozedForAlarm));
|
||||
dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, now);
|
||||
}
|
||||
|
||||
@@ -129,7 +130,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
|
||||
public void onSubscribe(Uri conditionId) {
|
||||
if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
|
||||
if (!ZenModeConfig.isValidScheduleConditionId(conditionId)) {
|
||||
notifyCondition(createCondition(conditionId, Condition.STATE_FALSE, "badCondition"));
|
||||
notifyCondition(createCondition(conditionId, Condition.STATE_ERROR, "invalidId"));
|
||||
return;
|
||||
}
|
||||
synchronized (mSubscriptions) {
|
||||
@@ -169,32 +170,11 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
|
||||
synchronized (mSubscriptions) {
|
||||
setRegistered(!mSubscriptions.isEmpty());
|
||||
for (Uri conditionId : mSubscriptions.keySet()) {
|
||||
final ScheduleCalendar cal = mSubscriptions.get(conditionId);
|
||||
if (cal != null && cal.isInSchedule(now)) {
|
||||
if (conditionSnoozed(conditionId) || cal.shouldExitForAlarm(now)) {
|
||||
conditionsToNotify.add(createCondition(
|
||||
conditionId, Condition.STATE_FALSE, "alarmCanceled"));
|
||||
addSnoozed(conditionId);
|
||||
} else {
|
||||
conditionsToNotify.add(createCondition(
|
||||
conditionId, Condition.STATE_TRUE, "meetsSchedule"));
|
||||
}
|
||||
cal.maybeSetNextAlarm(now, nextUserAlarmTime);
|
||||
} else {
|
||||
conditionsToNotify.add(createCondition(
|
||||
conditionId, Condition.STATE_FALSE, "!meetsSchedule"));
|
||||
removeSnoozed(conditionId);
|
||||
if (cal != null && nextUserAlarmTime == 0) {
|
||||
cal.maybeSetNextAlarm(now, nextUserAlarmTime);
|
||||
}
|
||||
}
|
||||
if (cal != null) {
|
||||
final long nextChangeTime = cal.getNextChangeTime(now);
|
||||
if (nextChangeTime > 0 && nextChangeTime > now) {
|
||||
if (mNextAlarmTime == 0 || nextChangeTime < mNextAlarmTime) {
|
||||
mNextAlarmTime = nextChangeTime;
|
||||
}
|
||||
}
|
||||
Condition condition =
|
||||
evaluateSubscriptionLocked(conditionId, mSubscriptions.get(conditionId),
|
||||
now, nextUserAlarmTime);
|
||||
if (condition != null) {
|
||||
conditionsToNotify.add(condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,6 +182,39 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
|
||||
updateAlarm(now, mNextAlarmTime);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@GuardedBy("mSubscriptions")
|
||||
Condition evaluateSubscriptionLocked(Uri conditionId, ScheduleCalendar cal,
|
||||
long now, long nextUserAlarmTime) {
|
||||
Condition condition;
|
||||
if (cal == null) {
|
||||
condition = createCondition(conditionId, Condition.STATE_ERROR, "!invalidId");
|
||||
removeSnoozed(conditionId);
|
||||
return condition;
|
||||
}
|
||||
if (cal.isInSchedule(now)) {
|
||||
if (conditionSnoozed(conditionId)) {
|
||||
condition = createCondition(conditionId, Condition.STATE_FALSE, "snoozed");
|
||||
} else if (cal.shouldExitForAlarm(now)) {
|
||||
condition = createCondition(conditionId, Condition.STATE_FALSE, "alarmCanceled");
|
||||
addSnoozed(conditionId);
|
||||
} else {
|
||||
condition = createCondition(conditionId, Condition.STATE_TRUE, "meetsSchedule");
|
||||
}
|
||||
} else {
|
||||
condition = createCondition(conditionId, Condition.STATE_FALSE, "!meetsSchedule");
|
||||
removeSnoozed(conditionId);
|
||||
}
|
||||
cal.maybeSetNextAlarm(now, nextUserAlarmTime);
|
||||
final long nextChangeTime = cal.getNextChangeTime(now);
|
||||
if (nextChangeTime > 0 && nextChangeTime > now) {
|
||||
if (mNextAlarmTime == 0 || nextChangeTime < mNextAlarmTime) {
|
||||
mNextAlarmTime = nextChangeTime;
|
||||
}
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
private void updateAlarm(long now, long time) {
|
||||
final AlarmManager alarms = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
|
||||
final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,
|
||||
@@ -266,27 +279,28 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
|
||||
}
|
||||
|
||||
private boolean conditionSnoozed(Uri conditionId) {
|
||||
synchronized (mSnoozed) {
|
||||
return mSnoozed.contains(conditionId);
|
||||
synchronized (mSnoozedForAlarm) {
|
||||
return mSnoozedForAlarm.contains(conditionId);
|
||||
}
|
||||
}
|
||||
|
||||
private void addSnoozed(Uri conditionId) {
|
||||
synchronized (mSnoozed) {
|
||||
mSnoozed.add(conditionId);
|
||||
@VisibleForTesting
|
||||
void addSnoozed(Uri conditionId) {
|
||||
synchronized (mSnoozedForAlarm) {
|
||||
mSnoozedForAlarm.add(conditionId);
|
||||
saveSnoozedLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeSnoozed(Uri conditionId) {
|
||||
synchronized (mSnoozed) {
|
||||
mSnoozed.remove(conditionId);
|
||||
synchronized (mSnoozedForAlarm) {
|
||||
mSnoozedForAlarm.remove(conditionId);
|
||||
saveSnoozedLocked();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveSnoozedLocked() {
|
||||
final String setting = TextUtils.join(SEPARATOR, mSnoozed);
|
||||
private void saveSnoozedLocked() {
|
||||
final String setting = TextUtils.join(SEPARATOR, mSnoozedForAlarm);
|
||||
final int currentUser = ActivityManager.getCurrentUser();
|
||||
Settings.Secure.putStringForUser(mContext.getContentResolver(),
|
||||
SCP_SETTING,
|
||||
@@ -294,8 +308,8 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
|
||||
currentUser);
|
||||
}
|
||||
|
||||
public void readSnoozed() {
|
||||
synchronized (mSnoozed) {
|
||||
private void readSnoozed() {
|
||||
synchronized (mSnoozedForAlarm) {
|
||||
long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final String setting = Settings.Secure.getStringForUser(
|
||||
@@ -312,7 +326,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
|
||||
if (TextUtils.isEmpty(token)) {
|
||||
continue;
|
||||
}
|
||||
mSnoozed.add(Uri.parse(token));
|
||||
mSnoozedForAlarm.add(Uri.parse(token));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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.android.server.notification;
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Slog;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ScheduleCalendarTest extends NotificationTestCase {
|
||||
|
||||
private ScheduleCalendar mScheduleCalendar;
|
||||
private ZenModeConfig.ScheduleInfo mScheduleInfo;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mScheduleCalendar = new ScheduleCalendar();
|
||||
mScheduleInfo = new ZenModeConfig.ScheduleInfo();
|
||||
mScheduleInfo.days = new int[] {1, 2, 3, 4, 5};
|
||||
mScheduleCalendar.setSchedule(mScheduleInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullScheduleInfo() throws Exception {
|
||||
mScheduleCalendar.setSchedule(null);
|
||||
|
||||
mScheduleCalendar.maybeSetNextAlarm(1000, 1999);
|
||||
assertEquals(0, mScheduleCalendar.getNextChangeTime(1000));
|
||||
assertFalse(mScheduleCalendar.isInSchedule(100));
|
||||
assertFalse(mScheduleCalendar.shouldExitForAlarm(100));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextChangeTime_startToday() throws Exception {
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 1);
|
||||
cal.set(Calendar.MINUTE, 15);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
mScheduleInfo.days = new int[] {getTodayDay()};
|
||||
mScheduleInfo.startHour = cal.get(Calendar.HOUR_OF_DAY) + 1;
|
||||
mScheduleInfo.endHour = cal.get(Calendar.HOUR_OF_DAY) + 3;
|
||||
mScheduleInfo.startMinute = 15;
|
||||
mScheduleInfo.endMinute = 15;
|
||||
mScheduleInfo.exitAtAlarm = false;
|
||||
mScheduleCalendar.setSchedule(mScheduleInfo);
|
||||
|
||||
Calendar expected = new GregorianCalendar();
|
||||
expected.setTimeInMillis(cal.getTimeInMillis());
|
||||
expected.set(Calendar.HOUR_OF_DAY, mScheduleInfo.startHour);
|
||||
|
||||
long actualMs = mScheduleCalendar.getNextChangeTime(cal.getTimeInMillis());
|
||||
GregorianCalendar actual = new GregorianCalendar();
|
||||
actual.setTimeInMillis(actualMs);
|
||||
assertEquals("Expected " + expected + " was " + actual, expected.getTimeInMillis(),
|
||||
actualMs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextChangeTime_endToday() throws Exception {
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 2);
|
||||
cal.set(Calendar.MINUTE, 15);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
mScheduleInfo.days = new int[] {getTodayDay()};
|
||||
mScheduleInfo.startHour = cal.get(Calendar.HOUR_OF_DAY) - 1;
|
||||
mScheduleInfo.endHour = cal.get(Calendar.HOUR_OF_DAY) + 3;
|
||||
mScheduleInfo.startMinute = 15;
|
||||
mScheduleInfo.endMinute = 15;
|
||||
mScheduleInfo.exitAtAlarm = false;
|
||||
|
||||
Calendar expected = new GregorianCalendar();
|
||||
expected.setTimeInMillis(cal.getTimeInMillis());
|
||||
expected.set(Calendar.HOUR_OF_DAY, mScheduleInfo.endHour);
|
||||
expected.set(Calendar.MINUTE, mScheduleInfo.endMinute);
|
||||
|
||||
long actualMs = mScheduleCalendar.getNextChangeTime(cal.getTimeInMillis());
|
||||
GregorianCalendar actual = new GregorianCalendar();
|
||||
actual.setTimeInMillis(actualMs);
|
||||
assertEquals("Expected " + expected + " was " + actual, expected.getTimeInMillis(),
|
||||
actualMs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextChangeTime_startTomorrow() throws Exception {
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 23);
|
||||
cal.set(Calendar.MINUTE, 15);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay() + 1};
|
||||
mScheduleInfo.startHour = 1;
|
||||
mScheduleInfo.endHour = 3;
|
||||
mScheduleInfo.startMinute = 15;
|
||||
mScheduleInfo.endMinute = 15;
|
||||
mScheduleInfo.exitAtAlarm = false;
|
||||
|
||||
Calendar expected = new GregorianCalendar();
|
||||
expected.setTimeInMillis(cal.getTimeInMillis());
|
||||
expected.add(Calendar.DATE, 1);
|
||||
expected.set(Calendar.HOUR_OF_DAY, mScheduleInfo.startHour);
|
||||
expected.set(Calendar.MINUTE, mScheduleInfo.startMinute);
|
||||
|
||||
long actualMs = mScheduleCalendar.getNextChangeTime(cal.getTimeInMillis());
|
||||
GregorianCalendar actual = new GregorianCalendar();
|
||||
actual.setTimeInMillis(actualMs);
|
||||
assertEquals("Expected " + expected + " was " + actual, expected.getTimeInMillis(),
|
||||
actualMs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextChangeTime_endTomorrow() throws Exception {
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 23);
|
||||
cal.set(Calendar.MINUTE, 15);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay() + 1};
|
||||
mScheduleInfo.startHour = 22;
|
||||
mScheduleInfo.endHour = 3;
|
||||
mScheduleInfo.startMinute = 15;
|
||||
mScheduleInfo.endMinute = 15;
|
||||
mScheduleInfo.exitAtAlarm = false;
|
||||
|
||||
Calendar expected = new GregorianCalendar();
|
||||
expected.setTimeInMillis(cal.getTimeInMillis());
|
||||
expected.add(Calendar.DATE, 1);
|
||||
expected.set(Calendar.HOUR_OF_DAY, mScheduleInfo.endHour);
|
||||
expected.set(Calendar.MINUTE, mScheduleInfo.endMinute);
|
||||
|
||||
long actualMs = mScheduleCalendar.getNextChangeTime(cal.getTimeInMillis());
|
||||
GregorianCalendar actual = new GregorianCalendar();
|
||||
actual.setTimeInMillis(actualMs);
|
||||
assertEquals("Expected " + expected + " was " + actual, expected.getTimeInMillis(),
|
||||
actualMs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldExitForAlarm_settingOff() {
|
||||
mScheduleInfo.exitAtAlarm = false;
|
||||
mScheduleInfo.nextAlarm = 1000;
|
||||
|
||||
assertFalse(mScheduleCalendar.shouldExitForAlarm(1000));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldExitForAlarm_beforeAlarm() {
|
||||
mScheduleInfo.exitAtAlarm = true;
|
||||
mScheduleInfo.nextAlarm = 1000;
|
||||
|
||||
assertFalse(mScheduleCalendar.shouldExitForAlarm(999));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldExitForAlarm_noAlarm() {
|
||||
mScheduleInfo.exitAtAlarm = true;
|
||||
mScheduleInfo.nextAlarm = 0;
|
||||
|
||||
assertFalse(mScheduleCalendar.shouldExitForAlarm(999));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldExitForAlarm() {
|
||||
mScheduleInfo.exitAtAlarm = true;
|
||||
mScheduleInfo.nextAlarm = 1000;
|
||||
|
||||
assertTrue(mScheduleCalendar.shouldExitForAlarm(1000));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaybeSetNextAlarm_settingOff() {
|
||||
mScheduleInfo.exitAtAlarm = false;
|
||||
mScheduleInfo.nextAlarm = 0;
|
||||
|
||||
mScheduleCalendar.maybeSetNextAlarm(1000, 2000);
|
||||
|
||||
assertEquals(0, mScheduleInfo.nextAlarm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaybeSetNextAlarm_settingOn() {
|
||||
mScheduleInfo.exitAtAlarm = true;
|
||||
mScheduleInfo.nextAlarm = 0;
|
||||
|
||||
mScheduleCalendar.maybeSetNextAlarm(1000, 2000);
|
||||
|
||||
assertEquals(2000, mScheduleInfo.nextAlarm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaybeSetNextAlarm_alarmCanceled() {
|
||||
mScheduleInfo.exitAtAlarm = true;
|
||||
mScheduleInfo.nextAlarm = 10000;
|
||||
|
||||
mScheduleCalendar.maybeSetNextAlarm(1000, 0);
|
||||
|
||||
assertEquals(0, mScheduleInfo.nextAlarm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaybeSetNextAlarm_earlierAlarm() {
|
||||
mScheduleInfo.exitAtAlarm = true;
|
||||
mScheduleInfo.nextAlarm = 2000;
|
||||
|
||||
mScheduleCalendar.maybeSetNextAlarm(1000, 1500);
|
||||
|
||||
assertEquals(1500, mScheduleInfo.nextAlarm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaybeSetNextAlarm_laterAlarm() {
|
||||
mScheduleInfo.exitAtAlarm = true;
|
||||
mScheduleInfo.nextAlarm = 2000;
|
||||
|
||||
mScheduleCalendar.maybeSetNextAlarm(1000, 3000);
|
||||
|
||||
assertEquals(2000, mScheduleInfo.nextAlarm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaybeSetNextAlarm_expiredAlarm() {
|
||||
mScheduleInfo.exitAtAlarm = true;
|
||||
mScheduleInfo.nextAlarm = 998;
|
||||
|
||||
mScheduleCalendar.maybeSetNextAlarm(1000, 999);
|
||||
|
||||
assertEquals(0, mScheduleInfo.nextAlarm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsInSchedule_inScheduleOvernight() {
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 23);
|
||||
cal.set(Calendar.MINUTE, 15);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
mScheduleInfo.days = new int[] {getTodayDay()};
|
||||
mScheduleInfo.startHour = 22;
|
||||
mScheduleInfo.endHour = 3;
|
||||
mScheduleInfo.startMinute = 15;
|
||||
mScheduleInfo.endMinute = 15;
|
||||
|
||||
assertTrue(mScheduleCalendar.isInSchedule(cal.getTimeInMillis()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsInSchedule_inScheduleSingleDay() {
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 14);
|
||||
cal.set(Calendar.MINUTE, 15);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
mScheduleInfo.days = new int[] {getTodayDay()};
|
||||
mScheduleInfo.startHour = 12;
|
||||
mScheduleInfo.endHour = 3;
|
||||
mScheduleInfo.startMinute = 16;
|
||||
mScheduleInfo.endMinute = 15;
|
||||
|
||||
assertTrue(mScheduleCalendar.isInSchedule(cal.getTimeInMillis()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsInSchedule_notToday() {
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 14);
|
||||
cal.set(Calendar.MINUTE, 15);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
|
||||
mScheduleInfo.days = new int[] {Calendar.FRIDAY, Calendar.SUNDAY};
|
||||
mScheduleInfo.startHour = 12;
|
||||
mScheduleInfo.startMinute = 16;
|
||||
mScheduleInfo.endHour = 15;
|
||||
mScheduleInfo.endMinute = 15;
|
||||
|
||||
assertFalse(mScheduleCalendar.isInSchedule(cal.getTimeInMillis()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsInSchedule_startingSoon() {
|
||||
Calendar cal = new GregorianCalendar();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 14);
|
||||
cal.set(Calendar.MINUTE, 15);
|
||||
cal.set(Calendar.SECOND, 59);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
mScheduleInfo.days = new int[] {getTodayDay()};
|
||||
mScheduleInfo.startHour = 14;
|
||||
mScheduleInfo.endHour = 3;
|
||||
mScheduleInfo.startMinute = 16;
|
||||
mScheduleInfo.endMinute = 15;
|
||||
|
||||
assertFalse(mScheduleCalendar.isInSchedule(cal.getTimeInMillis()));
|
||||
}
|
||||
|
||||
private int getTodayDay() {
|
||||
return new GregorianCalendar().get(Calendar.DAY_OF_WEEK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
package com.android.server.notification;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Looper;
|
||||
import android.service.notification.Condition;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.test.ServiceTestCase;
|
||||
import android.testing.TestableContext;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
public class ScheduleConditionProviderTest extends ServiceTestCase<ScheduleConditionProvider> {
|
||||
|
||||
ScheduleConditionProvider mService;
|
||||
|
||||
@Rule
|
||||
public final TestableContext mContext =
|
||||
new TestableContext(InstrumentationRegistry.getContext(), null);
|
||||
|
||||
public ScheduleConditionProviderTest() {
|
||||
super(ScheduleConditionProvider.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Looper.prepare();
|
||||
|
||||
Intent startIntent =
|
||||
new Intent("com.android.server.notification.ScheduleConditionProvider");
|
||||
startIntent.setPackage("android");
|
||||
bindService(startIntent);
|
||||
mService = spy(getService());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidConditionId_incomplete() throws Exception {
|
||||
Uri badConditionId = Uri.EMPTY;
|
||||
assertFalse(mService.isValidConditionId(badConditionId));
|
||||
assertEquals(Condition.STATE_ERROR,
|
||||
mService.evaluateSubscriptionLocked(badConditionId, null, 0, 1000).state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidConditionId() throws Exception {
|
||||
ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
|
||||
info.days = new int[] {1, 2, 4};
|
||||
info.startHour = 8;
|
||||
info.startMinute = 56;
|
||||
info.nextAlarm = 1000;
|
||||
info.exitAtAlarm = true;
|
||||
info.endHour = 12;
|
||||
info.endMinute = 9;
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
assertTrue(mService.isValidConditionId(conditionId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_noAlarmExit_InSchedule() {
|
||||
Calendar now = getNow();
|
||||
|
||||
// Schedule - 1 hour long; starts now
|
||||
ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
|
||||
info.days = new int[] {Calendar.FRIDAY};
|
||||
info.startHour = now.get(Calendar.HOUR_OF_DAY);
|
||||
info.startMinute = now.get(Calendar.MINUTE);
|
||||
info.nextAlarm = 0;
|
||||
info.exitAtAlarm = false;
|
||||
info.endHour = now.get(Calendar.HOUR_OF_DAY) + 1;
|
||||
info.endMinute = info.startMinute;
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
assertTrue(cal.isInSchedule(now.getTimeInMillis()));
|
||||
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
|
||||
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_noAlarmExit_InScheduleSnoozed() {
|
||||
Calendar now = getNow();
|
||||
|
||||
// Schedule - 1 hour long; starts now
|
||||
ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
|
||||
info.days = new int[] {Calendar.FRIDAY};
|
||||
info.startHour = now.get(Calendar.HOUR_OF_DAY);
|
||||
info.startMinute = now.get(Calendar.MINUTE);
|
||||
info.nextAlarm = 0;
|
||||
info.exitAtAlarm = false;
|
||||
info.endHour = now.get(Calendar.HOUR_OF_DAY) + 1;
|
||||
info.endMinute = info.startMinute;
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
assertTrue(cal.isInSchedule(now.getTimeInMillis()));
|
||||
|
||||
mService.addSnoozed(conditionId);
|
||||
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
|
||||
|
||||
assertEquals(Condition.STATE_FALSE, condition.state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_noAlarmExit_beforeSchedule() {
|
||||
Calendar now = new GregorianCalendar();
|
||||
now.set(Calendar.HOUR_OF_DAY, 14);
|
||||
now.set(Calendar.MINUTE, 15);
|
||||
now.set(Calendar.SECOND, 59);
|
||||
now.set(Calendar.MILLISECOND, 0);
|
||||
now.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
|
||||
|
||||
// Schedule - 1 hour long; starts in 1 second
|
||||
ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
|
||||
info.days = new int[] {Calendar.FRIDAY};
|
||||
info.startHour = now.get(Calendar.HOUR_OF_DAY);
|
||||
info.startMinute = now.get(Calendar.MINUTE) + 1;
|
||||
info.nextAlarm = 0;
|
||||
info.exitAtAlarm = false;
|
||||
info.endHour = now.get(Calendar.HOUR_OF_DAY) + 1;
|
||||
info.endMinute = info.startMinute;
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
|
||||
|
||||
assertEquals(Condition.STATE_FALSE, condition.state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_noAlarmExit_endSchedule() {
|
||||
Calendar now = getNow();
|
||||
|
||||
// Schedule - 1 hour long; ends now
|
||||
ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
|
||||
info.days = new int[] {Calendar.FRIDAY};
|
||||
info.startHour = now.get(Calendar.HOUR_OF_DAY) - 1;
|
||||
info.startMinute = now.get(Calendar.MINUTE);
|
||||
info.nextAlarm = 0;
|
||||
info.exitAtAlarm = false;
|
||||
info.endHour = now.get(Calendar.HOUR_OF_DAY);
|
||||
info.endMinute = now.get(Calendar.MINUTE);
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
|
||||
|
||||
assertEquals(Condition.STATE_FALSE, condition.state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_alarmSetBeforeInSchedule() {
|
||||
Calendar now = getNow();
|
||||
|
||||
// Schedule - 1 hour long; starts now, ends with alarm
|
||||
ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
|
||||
// an hour before start, update with an alarm that will fire during the schedule
|
||||
mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() - 1000, now.getTimeInMillis() + 1000);
|
||||
|
||||
// at start, should be in dnd
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 1000);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// at alarm fire time, should exit dnd
|
||||
assertTrue(cal.isInSchedule(now.getTimeInMillis() + 1000));
|
||||
assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
|
||||
cal.shouldExitForAlarm(now.getTimeInMillis() + 1000));
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 1000, 0);
|
||||
assertEquals(Condition.STATE_FALSE, condition.state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_alarmSetInSchedule() {
|
||||
Calendar now = getNow();
|
||||
|
||||
// Schedule - 1 hour long; starts now, ends with alarm
|
||||
ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
|
||||
// at start, should be in dnd
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), 0);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// in schedule, update with alarm time, should be in dnd
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 500, now.getTimeInMillis() + 1000);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// at alarm fire time, should exit dnd
|
||||
assertTrue(cal.isInSchedule(now.getTimeInMillis() + 1000));
|
||||
assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
|
||||
cal.shouldExitForAlarm(now.getTimeInMillis() + 1000));
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 1000, 0);
|
||||
assertEquals(Condition.STATE_FALSE, condition.state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_earlierAlarmSet() {
|
||||
Calendar now = getNow();
|
||||
|
||||
// Schedule - 1 hour long; starts now, ends with alarm
|
||||
ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
|
||||
// at start, should be in dnd, alarm in 2000 ms
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 2000);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// in schedule, update with earlier alarm time, should be in dnd
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 500, now.getTimeInMillis() + 1000);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// at earliest alarm fire time, should exit dnd
|
||||
assertTrue(cal.isInSchedule(now.getTimeInMillis() + 1000));
|
||||
assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
|
||||
cal.shouldExitForAlarm(now.getTimeInMillis() + 1000));
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 1000, 0);
|
||||
assertEquals(Condition.STATE_FALSE, condition.state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_laterAlarmSet() {
|
||||
Calendar now = getNow();
|
||||
|
||||
// Schedule - 1 hour long; starts now, ends with alarm
|
||||
ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
|
||||
// at start, should be in dnd, alarm in 500 ms
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 500);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// in schedule, update with later alarm time, should be in dnd
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 250, now.getTimeInMillis() + 1000);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// at earliest alarm fire time, should exit dnd
|
||||
assertTrue(cal.isInSchedule(now.getTimeInMillis() + 500));
|
||||
assertTrue("" + info.nextAlarm + " " + now.getTimeInMillis(),
|
||||
cal.shouldExitForAlarm(now.getTimeInMillis() + 500));
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 500, 0);
|
||||
assertEquals(Condition.STATE_FALSE, condition.state);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluateSubscription_alarmCanceled() {
|
||||
Calendar now = getNow();
|
||||
|
||||
// Schedule - 1 hour long; starts now, ends with alarm
|
||||
ZenModeConfig.ScheduleInfo info = getScheduleEndsInHour(now);
|
||||
Uri conditionId = ZenModeConfig.toScheduleConditionId(info);
|
||||
ScheduleCalendar cal = new ScheduleCalendar();
|
||||
cal.setSchedule(info);
|
||||
|
||||
// at start, should be in dnd, alarm in 500 ms
|
||||
Condition condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis(), now.getTimeInMillis() + 500);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// in schedule, cancel alarm
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 250, 0);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// at previous alarm time, should not exit DND
|
||||
assertTrue(cal.isInSchedule(now.getTimeInMillis() + 500));
|
||||
assertFalse(cal.shouldExitForAlarm(now.getTimeInMillis() + 500));
|
||||
condition = mService.evaluateSubscriptionLocked(
|
||||
conditionId, cal, now.getTimeInMillis() + 500, 0);
|
||||
assertEquals(Condition.STATE_TRUE, condition.state);
|
||||
|
||||
// end of schedule, exit DND
|
||||
now.add(Calendar.HOUR_OF_DAY, 1);
|
||||
condition = mService.evaluateSubscriptionLocked(conditionId, cal, now.getTimeInMillis(), 0);
|
||||
assertEquals(Condition.STATE_FALSE, condition.state);
|
||||
}
|
||||
|
||||
private Calendar getNow() {
|
||||
Calendar now = new GregorianCalendar();
|
||||
now.set(Calendar.HOUR_OF_DAY, 14);
|
||||
now.set(Calendar.MINUTE, 16);
|
||||
now.set(Calendar.SECOND, 0);
|
||||
now.set(Calendar.MILLISECOND, 0);
|
||||
now.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
|
||||
return now;
|
||||
}
|
||||
|
||||
private ZenModeConfig.ScheduleInfo getScheduleEndsInHour(Calendar now) {
|
||||
ZenModeConfig.ScheduleInfo info = new ZenModeConfig.ScheduleInfo();
|
||||
info.days = new int[] {Calendar.FRIDAY};
|
||||
info.startHour = now.get(Calendar.HOUR_OF_DAY);
|
||||
info.startMinute = now.get(Calendar.MINUTE);
|
||||
info.exitAtAlarm = true;
|
||||
info.endHour = now.get(Calendar.HOUR_OF_DAY) + 1;
|
||||
info.endMinute = now.get(Calendar.MINUTE);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user