]> iEval git - fonbot.git/blame - src/ro/ieval/fonbot/FonBotMainService.java
Add request ID
[fonbot.git] / src / ro / ieval / fonbot / FonBotMainService.java
CommitLineData
8dfb76c9
MG
1package ro.ieval.fonbot;
2
3import static ro.ieval.fonbot.R.string.*;
4import static ro.ieval.fonbot.Utils.toNonNull;
5
6import java.util.Collections;
5e3858a3 7import java.util.EnumSet;
8dfb76c9
MG
8import java.util.Set;
9
10import org.eclipse.jdt.annotation.Nullable;
11
12import ro.ieval.fonbot.Utils.OngoingEvent;
13
14import android.app.Notification;
15import android.app.NotificationManager;
16import android.app.PendingIntent;
17import android.app.Service;
18import android.content.Intent;
19import android.content.IntentFilter;
ca40a5cc 20import android.net.ConnectivityManager;
8dfb76c9
MG
21import android.os.IBinder;
22import android.preference.PreferenceManager;
23import android.support.v4.app.NotificationCompat;
24import android.support.v4.content.LocalBroadcastManager;
ca40a5cc 25import android.util.Log;
8dfb76c9
MG
26
27/*
28 * Copyright © 2013 Marius Gavrilescu
29 *
30 * This file is part of FonBot.
31 *
32 * FonBot is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, either version 3 of the License, or
35 * (at your option) any later version.
36 *
37 * FonBot is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with FonBot. If not, see <http://www.gnu.org/licenses/>.
44 */
45
46/**
47 * Main service.
48 *
49 * @author Marius Gavrilescu
50 */
51public final class FonBotMainService extends Service {
52 /**
53 * Binder for the service. It lets clients get a reference to the service.
54 *
55 * @author Marius Gavrilescu <marius@ieval.ro>
56 */
57 public final class Binder extends android.os.Binder{
58 /**
59 * Get a reference to the {@link FonBotMainService}
60 * @return a reference to the {@link FonBotMainService}
61 */
62 public FonBotMainService getService(){
63 return FonBotMainService.this;
64 }
65 }
66
ca40a5cc
MG
67 /**
68 * Runnable that continously long polls the server for commands
69 *
70 * @author Marius Gavrilescu <marius@ieval.ro>
71 */
72 private final class LongPollRunnable implements Runnable{
73 public void run(){
74 final ConnectivityManager man=(ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
75 final HttpCallExecutableRunnable runnable=new HttpCallExecutableRunnable("/get", null, FonBotMainService.this, new PollResultCallback(FonBotMainService.this), false);
76
77 Log.d("LongPollRunnable", "Long polling started");
78 while(man.getActiveNetworkInfo() != null && man.getActiveNetworkInfo().isConnected())
79 try {
80 runnable.run();
81 } catch (final Exception ex){
82 ex.printStackTrace();
83 }
84 Log.d("LongPollRunnable", "Long polling stopped");
85 }
86 }
87
8dfb76c9
MG
88 /**
89 * Broadcast action: add an ongoing event
90 */
91 public static final String ACTION_PUT_ONGOING="ro.ieval.fonbot.FonBotMainService.ACTION_PUT_ONGOING";
92 /**
93 * Broadcast action: remove an ongoing event
94 */
95 public static final String ACTION_DELETE_ONGOING="ro.ieval.fonbot.FonBotMainService.ACTION_DELETE_ONGOING";
6b9507db
MG
96 /** Broadcast action: trigger a server poll */
97 public static final String ACTION_TRIGGER_POLL="ro.ieval.fonbot.FonBotMainService.ACTION_TRIGGER_POLL";
8dfb76c9
MG
98 /**
99 * Extra: ongoing event id
100 *
101 * @see OngoingEvent
102 * @see #ACTION_DELETE_ONGOING
103 * @see #ACTION_PUT_ONGOING
104 */
105 public static final String EXTRA_ONGOING_ID="ro.ieval.fonbot.FonBotMainService.EXTRA_ONGOING_ID";
106 /**
107 * Broadcast sent when the ongoing event list is updated.
108 */
109 public static final String ACTION_ONGOING_UPDATE="ro.ieval.fonbot.FonBotMainService.ACTION_ONGOING_UPDATE";
110 /**
111 * IntentFilter for events caught by the {@link DynamicEventReceiver}
112 */
113 private static final IntentFilter DYNAMIC_BROADCAST_FILTER=new IntentFilter();
114
115 static{
8dfb76c9
MG
116 DYNAMIC_BROADCAST_FILTER.addAction(Intent.ACTION_BATTERY_CHANGED);
117 DYNAMIC_BROADCAST_FILTER.addAction(Intent.ACTION_HEADSET_PLUG);
118 }
119
120 /**
121 * The one instance of {@link DynamicEventReceiver}
122 */
123 private final DynamicEventReceiver receiver=new DynamicEventReceiver();
124 /**
125 * Set of ongoing events.
126 */
5e3858a3 127 private final Set<OngoingEvent> ongoing=EnumSet.noneOf(OngoingEvent.class);
8dfb76c9 128
c4351ec6
MG
129 /** true if running in foreground, false otherwise */
130 private boolean isForeground = false;
131
ca40a5cc
MG
132 /** Thread that runs a {@link LongPollRunnable} */
133 private Thread longPollThread;
134
8dfb76c9
MG
135 /**
136 * Get the set of ongoing events.
137 *
138 * @return a set of ongoing events
139 */
140 public Set<OngoingEvent> getOngoingEvents(){
141 return toNonNull(Collections.unmodifiableSet(ongoing));
142 }
143
144 @Override
145 public @Nullable IBinder onBind(final @Nullable Intent intent) {
146 return new Binder();
147 }
148
149 @Override
150 public void onCreate() {
151 super.onCreate();
152 registerReceiver(receiver, DYNAMIC_BROADCAST_FILTER);
153 }
154
155 @Override
156 public void onDestroy() {
157 super.onDestroy();
158 unregisterReceiver(receiver);
159 }
160
161 @Override
162 public int onStartCommand(final @Nullable Intent intent, final int flags, final int startId) {
c4351ec6 163 boolean updateNotification = false;
8dfb76c9
MG
164 if(intent!=null && intent.getAction()==ACTION_PUT_ONGOING && intent.hasExtra(EXTRA_ONGOING_ID)){
165 ongoing.add(OngoingEvent.values()[intent.getIntExtra(EXTRA_ONGOING_ID, 0)]);
166 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_ONGOING_UPDATE));
c4351ec6 167 updateNotification=true;
8dfb76c9
MG
168 }
169 if(intent!=null && intent.getAction()==ACTION_DELETE_ONGOING && intent.hasExtra(EXTRA_ONGOING_ID)){
170 ongoing.remove(OngoingEvent.values()[intent.getIntExtra(EXTRA_ONGOING_ID, 0)]);
171 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_ONGOING_UPDATE));
c4351ec6 172 updateNotification=true;
8dfb76c9
MG
173 }
174
ca40a5cc
MG
175 if(longPollThread == null || !longPollThread.isAlive()){
176 longPollThread = new Thread(new LongPollRunnable());
177 longPollThread.start();
178 }
6b9507db 179
8dfb76c9
MG
180 final boolean runForeground=PreferenceManager.getDefaultSharedPreferences(this).getBoolean("foreground", false);
181 if(!runForeground)
182 stopForeground(true);
183
c4351ec6
MG
184 final NotificationManager man=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
185 final boolean shouldNotify=runForeground||!ongoing.isEmpty();
186 if(shouldNotify && (updateNotification || runForeground != isForeground)){
8dfb76c9
MG
187 final Intent mainIntent=new Intent(this, FonBotMainActivity.class);
188 mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
189 final NotificationCompat.Builder builder=new NotificationCompat.Builder(this).
190 setContentText(getString(foreground_notification_text)).
191 setContentTitle(getString(foreground_notification_title)).
192 setSmallIcon(android.R.drawable.stat_notify_sync_noanim).
193 setPriority(NotificationCompat.PRIORITY_MIN).
194 setContentIntent(PendingIntent.getActivity(this, 0, mainIntent, 0)).
195 setOngoing(true);
196
c4351ec6 197 if(!ongoing.isEmpty()) {
8dfb76c9
MG
198 final NotificationCompat.InboxStyle inboxBuilder=new NotificationCompat.InboxStyle(builder);
199
200 for(final OngoingEvent event : ongoing)
201 inboxBuilder.addLine(getString(event.resource));
202
8dfb76c9 203 }
c4351ec6 204 final Notification notification=builder.build();
8dfb76c9
MG
205
206 if(runForeground)
c4351ec6
MG
207 startForeground(1337, notification);
208 else
8dfb76c9 209 man.notify(1337, notification);
8dfb76c9
MG
210 }
211
c4351ec6
MG
212 if(!shouldNotify)
213 man.cancel(1337);
214 isForeground=runForeground;
8dfb76c9
MG
215 return START_STICKY;
216 }
217}
This page took 0.04929 seconds and 4 git commands to generate.