1/* 2 * Copyright (c) 2015, Motorola Mobility LLC 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * - Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * - Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * - Neither the name of Motorola Mobility nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 26 * DAMAGE. 27 */ 28 29package com.android.service.ims.presence; 30 31import android.app.Service; 32import android.content.BroadcastReceiver; 33import android.content.Context; 34import android.content.Intent; 35import android.content.IntentFilter; 36import android.telephony.CarrierConfigManager; 37import android.os.IBinder; 38import android.os.PersistableBundle; 39import android.os.ServiceManager; 40import android.os.SystemProperties; 41 42import com.android.ims.internal.Logger; 43import com.android.internal.annotations.VisibleForTesting; 44 45/** 46 * Manages the CapabilityPolling class. Starts capability polling when a SIM card is inserted that 47 * supports RCS Presence Capability Polling and stops the service otherwise. 48 */ 49public class PollingService extends Service { 50 51 private Logger logger = Logger.getLogger(this.getClass().getName()); 52 53 private CapabilityPolling mCapabilityPolling = null; 54 55 // not final for testing 56 private BroadcastReceiver mReceiver = new BroadcastReceiver() { 57 58 @Override 59 public void onReceive(Context context, Intent intent) { 60 switch (intent.getAction()) { 61 case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: { 62 checkAndUpdateCapabilityPollStatus(); 63 break; 64 } 65 } 66 } 67 }; 68 69 /** 70 * Constructor 71 */ 72 public PollingService() { 73 logger.debug("PollingService()"); 74 } 75 76 @Override 77 public void onCreate() { 78 logger.debug("onCreate()"); 79 80 registerBroadcastReceiver(); 81 // Check when the service starts in case the SIM info has already been loaded. 82 checkAndUpdateCapabilityPollStatus(); 83 } 84 85 /** 86 * Cleans up when the service is destroyed 87 */ 88 @Override 89 public void onDestroy() { 90 logger.debug("onDestroy()"); 91 92 if (mCapabilityPolling != null) { 93 mCapabilityPolling.stop(); 94 mCapabilityPolling = null; 95 } 96 97 unregisterReceiver(mReceiver); 98 99 super.onDestroy(); 100 } 101 102 @Override 103 public IBinder onBind(Intent intent) { 104 logger.debug("onBind(), intent: " + intent); 105 106 if (!isRcsSupported(this)) { 107 return null; 108 } 109 110 logger.debug("onBind add services here"); 111 return null; 112 } 113 114 @VisibleForTesting 115 public void setBroadcastReceiver(BroadcastReceiver r) { 116 mReceiver = r; 117 } 118 119 private void registerBroadcastReceiver() { 120 IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 121 registerReceiver(mReceiver, filter); 122 } 123 124 private void checkAndUpdateCapabilityPollStatus() { 125 // If the carrier doesn't support RCS Presence, stop polling. 126 if (!isRcsSupportedByCarrier(this)) { 127 logger.info("RCS not supported by carrier. Stopping CapabilityPolling"); 128 if (mCapabilityPolling != null) { 129 mCapabilityPolling.stop(); 130 mCapabilityPolling = null; 131 } 132 return; 133 } 134 // Carrier supports, so start the service if it hasn't already been started. 135 if (mCapabilityPolling == null) { 136 logger.info("Starting CapabilityPolling..."); 137 mCapabilityPolling = CapabilityPolling.getInstance(this); 138 mCapabilityPolling.start(); 139 } 140 } 141 142 static boolean isRcsSupported(Context context) { 143 return isRcsSupportedByDevice() && isRcsSupportedByCarrier(context); 144 } 145 146 private static boolean isRcsSupportedByCarrier(Context context) { 147 CarrierConfigManager configManager = context.getSystemService(CarrierConfigManager.class); 148 if (configManager != null) { 149 PersistableBundle b = configManager.getConfig(); 150 if (b != null) { 151 return b.getBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, false); 152 } 153 } 154 return true; 155 } 156 157 public static boolean isRcsSupportedByDevice() { 158 String rcsSupported = SystemProperties.get("persist.rcs.supported"); 159 return "1".equals(rcsSupported); 160 } 161} 162