Loading core/java/android/service/notification/ZenModeConfig.java +11 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading packages/SystemUI/res/layout/volume_dialog.xml +2 −2 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -45,4 +45,4 @@ </LinearLayout> </RelativeLayout> </com.android.systemui.HardwareUiLayout> </RelativeLayout> packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +49 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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<>(); Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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)); } Loading Loading @@ -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(() -> { Loading Loading @@ -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) Loading services/core/java/com/android/server/notification/ScheduleCalendar.java +23 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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)) { 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; } } } Loading Loading @@ -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; Loading services/core/java/com/android/server/notification/ScheduleConditionProvider.java +56 −42 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } Loading @@ -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) { Loading Loading @@ -169,37 +170,49 @@ 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")); Condition condition = evaluateSubscriptionLocked(conditionId, mSubscriptions.get(conditionId), now, nextUserAlarmTime); if (condition != null) { conditionsToNotify.add(condition); } } } notifyConditions(conditionsToNotify.toArray(new Condition[conditionsToNotify.size()])); 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 { conditionsToNotify.add(createCondition( conditionId, Condition.STATE_TRUE, "meetsSchedule")); condition = createCondition(conditionId, Condition.STATE_TRUE, "meetsSchedule"); } cal.maybeSetNextAlarm(now, nextUserAlarmTime); } else { conditionsToNotify.add(createCondition( conditionId, Condition.STATE_FALSE, "!meetsSchedule")); condition = createCondition(conditionId, Condition.STATE_FALSE, "!meetsSchedule"); removeSnoozed(conditionId); if (cal != null && nextUserAlarmTime == 0) { cal.maybeSetNextAlarm(now, nextUserAlarmTime); } } if (cal != null) { cal.maybeSetNextAlarm(now, nextUserAlarmTime); final long nextChangeTime = cal.getNextChangeTime(now); if (nextChangeTime > 0 && nextChangeTime > now) { if (mNextAlarmTime == 0 || nextChangeTime < mNextAlarmTime) { mNextAlarmTime = nextChangeTime; } } } } } notifyConditions(conditionsToNotify.toArray(new Condition[conditionsToNotify.size()])); updateAlarm(now, mNextAlarmTime); return condition; } private void updateAlarm(long now, long time) { Loading Loading @@ -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, Loading @@ -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( Loading @@ -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 { Loading Loading
core/java/android/service/notification/ZenModeConfig.java +11 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading
packages/SystemUI/res/layout/volume_dialog.xml +2 −2 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -45,4 +45,4 @@ </LinearLayout> </RelativeLayout> </com.android.systemui.HardwareUiLayout> </RelativeLayout>
packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +49 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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<>(); Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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)); } Loading Loading @@ -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(() -> { Loading Loading @@ -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) Loading
services/core/java/com/android/server/notification/ScheduleCalendar.java +23 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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)) { 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; } } } Loading Loading @@ -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; Loading
services/core/java/com/android/server/notification/ScheduleConditionProvider.java +56 −42 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } Loading @@ -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) { Loading Loading @@ -169,37 +170,49 @@ 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")); Condition condition = evaluateSubscriptionLocked(conditionId, mSubscriptions.get(conditionId), now, nextUserAlarmTime); if (condition != null) { conditionsToNotify.add(condition); } } } notifyConditions(conditionsToNotify.toArray(new Condition[conditionsToNotify.size()])); 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 { conditionsToNotify.add(createCondition( conditionId, Condition.STATE_TRUE, "meetsSchedule")); condition = createCondition(conditionId, Condition.STATE_TRUE, "meetsSchedule"); } cal.maybeSetNextAlarm(now, nextUserAlarmTime); } else { conditionsToNotify.add(createCondition( conditionId, Condition.STATE_FALSE, "!meetsSchedule")); condition = createCondition(conditionId, Condition.STATE_FALSE, "!meetsSchedule"); removeSnoozed(conditionId); if (cal != null && nextUserAlarmTime == 0) { cal.maybeSetNextAlarm(now, nextUserAlarmTime); } } if (cal != null) { cal.maybeSetNextAlarm(now, nextUserAlarmTime); final long nextChangeTime = cal.getNextChangeTime(now); if (nextChangeTime > 0 && nextChangeTime > now) { if (mNextAlarmTime == 0 || nextChangeTime < mNextAlarmTime) { mNextAlarmTime = nextChangeTime; } } } } } notifyConditions(conditionsToNotify.toArray(new Condition[conditionsToNotify.size()])); updateAlarm(now, mNextAlarmTime); return condition; } private void updateAlarm(long now, long time) { Loading Loading @@ -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, Loading @@ -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( Loading @@ -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 { Loading