Revert "Prevent against future use-up-lots-of-mobile-data bugs"
[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 {
cde38bea 80 runnable.run();
ca40a5cc
MG
81 } catch (final Exception ex){
82 ex.printStackTrace();
c7b1fdf5 83 break;
ca40a5cc
MG
84 }
85 Log.d("LongPollRunnable", "Long polling stopped");
86 }
87 }
88
8dfb76c9
MG
89 /**
90 * Broadcast action: add an ongoing event
91 */
92 public static final String ACTION_PUT_ONGOING="ro.ieval.fonbot.FonBotMainService.ACTION_PUT_ONGOING";
93 /**
94 * Broadcast action: remove an ongoing event
95 */
96 public static final String ACTION_DELETE_ONGOING="ro.ieval.fonbot.FonBotMainService.ACTION_DELETE_ONGOING";
1b6a0480 97
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) {
079ea306 163 final boolean showOngoing=PreferenceManager.getDefaultSharedPreferences(this).getBoolean("ongoing", false);
c4351ec6 164 boolean updateNotification = false;
079ea306 165 if(intent!=null && intent.getAction()==ACTION_PUT_ONGOING && intent.hasExtra(EXTRA_ONGOING_ID) && showOngoing){
8dfb76c9
MG
166 ongoing.add(OngoingEvent.values()[intent.getIntExtra(EXTRA_ONGOING_ID, 0)]);
167 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_ONGOING_UPDATE));
c4351ec6 168 updateNotification=true;
8dfb76c9 169 }
079ea306 170 if(intent!=null && intent.getAction()==ACTION_DELETE_ONGOING && intent.hasExtra(EXTRA_ONGOING_ID) && showOngoing){
8dfb76c9
MG
171 ongoing.remove(OngoingEvent.values()[intent.getIntExtra(EXTRA_ONGOING_ID, 0)]);
172 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_ONGOING_UPDATE));
c4351ec6 173 updateNotification=true;
8dfb76c9
MG
174 }
175
ca40a5cc
MG
176 if(longPollThread == null || !longPollThread.isAlive()){
177 longPollThread = new Thread(new LongPollRunnable());
178 longPollThread.start();
179 }
6b9507db 180
8dfb76c9
MG
181 final boolean runForeground=PreferenceManager.getDefaultSharedPreferences(this).getBoolean("foreground", false);
182 if(!runForeground)
183 stopForeground(true);
184
c4351ec6
MG
185 final NotificationManager man=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
186 final boolean shouldNotify=runForeground||!ongoing.isEmpty();
187 if(shouldNotify && (updateNotification || runForeground != isForeground)){
8dfb76c9
MG
188 final Intent mainIntent=new Intent(this, FonBotMainActivity.class);
189 mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
190 final NotificationCompat.Builder builder=new NotificationCompat.Builder(this).
191 setContentText(getString(foreground_notification_text)).
192 setContentTitle(getString(foreground_notification_title)).
193 setSmallIcon(android.R.drawable.stat_notify_sync_noanim).
194 setPriority(NotificationCompat.PRIORITY_MIN).
195 setContentIntent(PendingIntent.getActivity(this, 0, mainIntent, 0)).
196 setOngoing(true);
197
079ea306 198 if(showOngoing && !ongoing.isEmpty()) {
8dfb76c9
MG
199 final NotificationCompat.InboxStyle inboxBuilder=new NotificationCompat.InboxStyle(builder);
200
201 for(final OngoingEvent event : ongoing)
202 inboxBuilder.addLine(getString(event.resource));
203
8dfb76c9 204 }
c4351ec6 205 final Notification notification=builder.build();
8dfb76c9
MG
206
207 if(runForeground)
c4351ec6
MG
208 startForeground(1337, notification);
209 else
8dfb76c9 210 man.notify(1337, notification);
8dfb76c9
MG
211 }
212
c4351ec6
MG
213 if(!shouldNotify)
214 man.cancel(1337);
215 isForeground=runForeground;
8dfb76c9
MG
216 return START_STICKY;
217 }
218}
This page took 0.025 seconds and 4 git commands to generate.