OSDN Git Service

DO NOT MERGE. Check provider access for content changes. am: 9b85862620 -s ours...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / notification / CountdownConditionProvider.java
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.server.notification;
18
19 import android.app.AlarmManager;
20 import android.app.PendingIntent;
21 import android.content.BroadcastReceiver;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.net.Uri;
27 import android.service.notification.Condition;
28 import android.service.notification.IConditionProvider;
29 import android.service.notification.ZenModeConfig;
30 import android.text.format.DateUtils;
31 import android.util.Log;
32 import android.util.Slog;
33
34 import com.android.server.notification.NotificationManagerService.DumpFilter;
35
36 import java.io.PrintWriter;
37
38 /** Built-in zen condition provider for simple time-based conditions */
39 public class CountdownConditionProvider extends SystemConditionProviderService {
40     private static final String TAG = "ConditionProviders.CCP";
41     private static final boolean DEBUG = Log.isLoggable("ConditionProviders", Log.DEBUG);
42
43     public static final ComponentName COMPONENT =
44             new ComponentName("android", CountdownConditionProvider.class.getName());
45
46     private static final String ACTION = CountdownConditionProvider.class.getName();
47     private static final int REQUEST_CODE = 100;
48     private static final String EXTRA_CONDITION_ID = "condition_id";
49
50     private final Context mContext = this;
51     private final Receiver mReceiver = new Receiver();
52
53     private boolean mConnected;
54     private long mTime;
55
56     public CountdownConditionProvider() {
57         if (DEBUG) Slog.d(TAG, "new CountdownConditionProvider()");
58     }
59
60     @Override
61     public ComponentName getComponent() {
62         return COMPONENT;
63     }
64
65     @Override
66     public boolean isValidConditionId(Uri id) {
67         return ZenModeConfig.isValidCountdownConditionId(id);
68     }
69
70     @Override
71     public void attachBase(Context base) {
72         attachBaseContext(base);
73     }
74
75     @Override
76     public void onBootComplete() {
77         // noop
78     }
79
80     @Override
81     public IConditionProvider asInterface() {
82         return (IConditionProvider) onBind(null);
83     }
84
85     @Override
86     public void dump(PrintWriter pw, DumpFilter filter) {
87         pw.println("    CountdownConditionProvider:");
88         pw.print("      mConnected="); pw.println(mConnected);
89         pw.print("      mTime="); pw.println(mTime);
90     }
91
92     @Override
93     public void onConnected() {
94         if (DEBUG) Slog.d(TAG, "onConnected");
95         mContext.registerReceiver(mReceiver, new IntentFilter(ACTION));
96         mConnected = true;
97     }
98
99     @Override
100     public void onDestroy() {
101         super.onDestroy();
102         if (DEBUG) Slog.d(TAG, "onDestroy");
103         if (mConnected) {
104             mContext.unregisterReceiver(mReceiver);
105         }
106         mConnected = false;
107     }
108
109     @Override
110     public void onRequestConditions(int relevance) {
111         // by convention
112     }
113
114     @Override
115     public void onSubscribe(Uri conditionId) {
116         if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
117         mTime = ZenModeConfig.tryParseCountdownConditionId(conditionId);
118         final AlarmManager alarms = (AlarmManager)
119                 mContext.getSystemService(Context.ALARM_SERVICE);
120         final Intent intent = new Intent(ACTION).putExtra(EXTRA_CONDITION_ID, conditionId)
121                 .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
122         final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE,
123                 intent, PendingIntent.FLAG_UPDATE_CURRENT);
124         alarms.cancel(pendingIntent);
125         if (mTime > 0) {
126             final long now = System.currentTimeMillis();
127             final CharSequence span =
128                     DateUtils.getRelativeTimeSpanString(mTime, now, DateUtils.MINUTE_IN_MILLIS);
129             if (mTime <= now) {
130                 // in the past, already false
131                 notifyCondition(newCondition(mTime, Condition.STATE_FALSE));
132             } else {
133                 // in the future, set an alarm
134                 alarms.setExact(AlarmManager.RTC_WAKEUP, mTime, pendingIntent);
135             }
136             if (DEBUG) Slog.d(TAG, String.format(
137                     "%s %s for %s, %s in the future (%s), now=%s",
138                     (mTime <= now ? "Not scheduling" : "Scheduling"),
139                     ACTION, ts(mTime), mTime - now, span, ts(now)));
140         }
141     }
142
143     @Override
144     public void onUnsubscribe(Uri conditionId) {
145         // noop
146     }
147
148     private final class Receiver extends BroadcastReceiver {
149         @Override
150         public void onReceive(Context context, Intent intent) {
151             if (ACTION.equals(intent.getAction())) {
152                 final Uri conditionId = intent.getParcelableExtra(EXTRA_CONDITION_ID);
153                 final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
154                 if (DEBUG) Slog.d(TAG, "Countdown condition fired: " + conditionId);
155                 if (time > 0) {
156                     notifyCondition(newCondition(time, Condition.STATE_FALSE));
157                 }
158             }
159         }
160     }
161
162     private static final Condition newCondition(long time, int state) {
163         return new Condition(ZenModeConfig.toCountdownConditionId(time),
164                 "", "", "", 0, state,Condition.FLAG_RELEVANT_NOW);
165     }
166
167     public static String tryParseDescription(Uri conditionUri) {
168         final long time = ZenModeConfig.tryParseCountdownConditionId(conditionUri);
169         if (time == 0) return null;
170         final long now = System.currentTimeMillis();
171         final CharSequence span =
172                 DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS);
173         return String.format("Scheduled for %s, %s in the future (%s), now=%s",
174                 ts(time), time - now, span, ts(now));
175     }
176
177 }