1 /*
2  * Copyright (C) 2010 ZXing authors
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.google.zxing.client.android;
18 
19 import android.app.Activity;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 
25 import java.util.concurrent.Executors;
26 import java.util.concurrent.RejectedExecutionException;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.ScheduledFuture;
29 import java.util.concurrent.ThreadFactory;
30 import java.util.concurrent.TimeUnit;
31 
32 /**
33  * Finishes an activity after a period of inactivity if the device is on battery power.
34  */
35 final class InactivityTimer {
36 
37   private static final int INACTIVITY_DELAY_SECONDS = 5 * 60;
38 
39   private final ScheduledExecutorService inactivityTimer =
40       Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
41   private final Activity activity;
42   private ScheduledFuture<?> inactivityFuture = null;
43   private final BroadcastReceiver powerStatusReceiver = new PowerStatusReceiver();
44 
InactivityTimer(Activity activity)45   InactivityTimer(Activity activity) {
46     this.activity = activity;
47     onActivity();
48   }
49 
onActivity()50   void onActivity() {
51     cancel();
52     if (!inactivityTimer.isShutdown()) {
53       try {
54         inactivityFuture = inactivityTimer.schedule(new FinishListener(activity),
55             INACTIVITY_DELAY_SECONDS,
56             TimeUnit.SECONDS);
57       } catch (RejectedExecutionException ree) {
58         // surprising, but could be normal if for some reason the implementation just doesn't
59         // think it can shcedule again. Since this time-out is non-essential, just forget it
60       }
61     }
62   }
63 
onPause()64   public void onPause() {
65     cancel();
66     activity.unregisterReceiver(powerStatusReceiver);
67   }
68 
onResume()69   public void onResume(){
70     activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
71     onActivity();
72   }
73 
cancel()74   private void cancel() {
75     ScheduledFuture<?> future = inactivityFuture;
76     if (future != null) {
77       future.cancel(true);
78       inactivityFuture = null;
79     }
80   }
81 
shutdown()82   void shutdown() {
83     cancel();
84     inactivityTimer.shutdown();
85   }
86 
87   private static final class DaemonThreadFactory implements ThreadFactory {
newThread(Runnable runnable)88     public Thread newThread(Runnable runnable) {
89       Thread thread = new Thread(runnable);
90       thread.setDaemon(true);
91       return thread;
92     }
93   }
94 
95   private final class PowerStatusReceiver extends BroadcastReceiver {
96     @Override
onReceive(Context context, Intent intent)97     public void onReceive(Context context, Intent intent){
98       if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
99         // 0 indicates that we're on battery
100         // In Android 2.0+, use BatteryManager.EXTRA_PLUGGED
101         int batteryPlugged = intent.getIntExtra("plugged", -1);
102         if (batteryPlugged > 0) {
103           InactivityTimer.this.cancel();
104         }
105       }
106     }
107   }
108 
109 }
110