1 /*
2  * Copyright (C) 2017 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 package androidx.work.impl.constraints.trackers
17 
18 import android.content.Context
19 import android.content.Intent
20 import android.content.IntentFilter
21 import androidx.annotation.RestrictTo
22 import androidx.work.Logger
23 import androidx.work.impl.utils.taskexecutor.TaskExecutor
24 
25 /** Tracks whether or not the device's storage is low. */
26 @Suppress("DEPRECATION")
27 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
28 class StorageNotLowTracker(context: Context, taskExecutor: TaskExecutor) :
29     BroadcastReceiverConstraintTracker<Boolean>(context, taskExecutor) {
30 
readSystemStatenull31     override fun readSystemState(): Boolean {
32         val intent = appContext.registerReceiver(null, intentFilter)
33         return if (intent == null || intent.action == null) {
34             // ACTION_DEVICE_STORAGE_LOW is a sticky broadcast that is removed when sufficient
35             // storage is available again. ACTION_DEVICE_STORAGE_OK is not sticky. So if we
36             // don't receive anything here, we can assume that the storage state is okay.
37             true
38         } else {
39             when (intent.action) {
40                 Intent.ACTION_DEVICE_STORAGE_OK -> true
41                 Intent.ACTION_DEVICE_STORAGE_LOW -> false
42                 else ->
43                     // This should never happen because the intent filter is configured
44                     // correctly.
45                     false
46             }
47         }
48     }
49 
50     override val intentFilter: IntentFilter
51         get() {
52             // In API 26+, DEVICE_STORAGE_OK/LOW are deprecated and are no longer sent to
53             // manifest-defined BroadcastReceivers. Since we are registering our receiver manually,
54             // this
55             // is currently okay. This may change in future versions, so this will need to be
56             // monitored.
57             val intentFilter = IntentFilter()
58             intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK)
59             intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW)
60             return intentFilter
61         }
62 
onBroadcastReceivenull63     override fun onBroadcastReceive(intent: Intent) {
64         if (intent.action == null) {
65             return // Should never happen since the IntentFilter was configured.
66         }
67         Logger.get().debug(TAG, "Received " + intent.action)
68         when (intent.action) {
69             Intent.ACTION_DEVICE_STORAGE_OK -> state = true
70             Intent.ACTION_DEVICE_STORAGE_LOW -> state = false
71         }
72     }
73 }
74 
75 private val TAG = Logger.tagWithPrefix("StorageNotLowTracker")
76