/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.qs.tiles;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.Settings.Global;
import android.service.quicksettings.Tile;
import android.telecom.TelecomManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Switch;
import android.widget.Toast;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.GlobalSetting;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.NetworkController;
import com.mediatek.ims.internal.MtkImsManager;
import com.mediatek.ims.internal.MtkImsManagerEx;
import com.mediatek.internal.telephony.MtkPhoneConstants;
/** Quick settings tile: VoLTE switch **/
public class VoWifiTile extends QSTileImpl {
private final GlobalSetting mSetting;
private boolean mListening;
private boolean mNoSimCard;
private NetworkController mController;
private CellSignalCallback mSignalCallback = new CellSignalCallback();
private final class CellSignalCallback implements NetworkController.SignalCallback {
@Override
public void setNoSims(boolean show, boolean simDetected) {
if (DEBUG) {
Log.d(TAG, "show = " + show + " simDetected = " + simDetected);
}
mNoSimCard = show;
refreshState(null);
}
}
public VoWifiTile(QSHost host) {
super(host);
mController = Dependency.get(NetworkController.class);
mSetting = new GlobalSetting(mContext, mHandler, Global.WFC_IMS_ENABLED) {
@Override
protected void handleValueChanged(int value) {
if (DEBUG) {
Log.d(TAG, "handleValueChanged, value = " + value);
}
handleRefreshState(value);
}
};
}
@Override
public BooleanState newTileState() {
return new BooleanState();
}
@Override
public void handleClick() {
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
if (DEBUG) {
Log.d(TAG, "handleClick, set vowifi switch enable = " + !mState.value);
}
setEnabled(!getVoWiFiState());
}
private void setEnabled(boolean enabled) {
if (canNotSetVoWiFiMode()) {
if (DEBUG) {
Log.d(TAG, "onSwitchChanged can't set vowifi state");
}
Toast.makeText(mContext,
R.string.can_not_switch_vowifi_mode_tips, Toast.LENGTH_SHORT).show();
} else {
if (DEBUG) {
Log.d(TAG, "start to set vowifi ,enable is " + enabled);
}
MtkImsManager.setWfcSetting(mContext,enabled,SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId()));
}
}
@Override
public Intent getLongClickIntent() {
Intent intent = new Intent();
intent.setAction("android.settings.WIFI_CALLING_SETTINGS");
Bundle bundle = new Bundle();
bundle.putBoolean("need_search_icon_in_action_bar", false);
bundle.putInt("subId",SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId()));
return intent;
}
@Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.vowifi_switch);
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
boolean vowifi = getVoWiFiState();
final Drawable mEnable = mContext.getDrawable(R.drawable.vowifi_enable);
final Drawable mDisable = mContext.getDrawable(R.drawable.vowifi_disable);
if (mNoSimCard){
vowifi = false;
}
state.value = vowifi;
state.label = mContext.getString(R.string.vowifi_switch);
state.icon = new DrawableIcon(state.value ? mEnable : mDisable);
if (state.slash == null) {
state.slash = new SlashState();
}
state.slash.isSlashed = !vowifi;
state.state = vowifi ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.contentDescription = state.label;
state.expandedAccessibilityClassName = Switch.class.getName();
}
@Override
public int getMetricsCategory() {
return MetricsEvent.QS_AIRPLANEMODE;
}
@Override
protected String composeChangeAnnouncement() {
if (mState.value) {
return mContext.getString(R.string.accessibility_quick_settings_VoWifi_changed_on);
} else {
return mContext.getString(R.string.accessibility_quick_settings_VoWifi_changed_off);
}
}
public void handleSetListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
if (listening) {
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
mContext.registerReceiver(mReceiver, filter);
mController.addCallback(mSignalCallback);
} else {
mContext.unregisterReceiver(mReceiver);
mController.removeCallback(mSignalCallback);
}
mSetting.setListening(listening);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction()) || TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
if (DEBUG) {
Log.d(TAG, "yanghua onReceive, action = "+ intent.getAction());
}
refreshState();
}
}
};
private boolean canNotSetVoWiFiMode() {
if (DEBUG) {
Log.d(TAG, "canNotSetVoWiFiMode > isInCall = " + isInCall(mContext) +
"; isInSwitchProcess=" + isInSwitchProcess() + "; isAirplaneModeOn=" + isAirplaneModeOn(mContext)
+ "; mNoSimCard =" + mNoSimCard + "; mSimReady=" + isSimReady());
}
return isInCall(mContext) || isInSwitchProcess()
|| isAirplaneModeOn(mContext) || mNoSimCard || !isSimReady() || !isWfcEnable();
}
private boolean getVoWiFiState(){
ImsManager imsManager = ImsManager.getInstance(
mContext, SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId()));
if (null == imsManager){
if (DEBUG) {
Log.d(TAG, "getVoWiFiState imsManager NULL");
}
return false;
}
//Log.d(TAG,"getVoWiFiState isWfcEnable = "+isWfcEnable());
if (!isWfcEnable()){
return false;
}
if (DEBUG) {
Log.d(TAG, "getVoWiFiState " + " isWfcEnabledByUser = " + imsManager.isWfcEnabledByUser() + " isWfcEnabledByPlatform = " + imsManager.isWfcEnabledByPlatform()
+ " isNonTtyOrTtyOnVolteEnabled = " + imsManager.isNonTtyOrTtyOnVolteEnabled());
}
return imsManager.isWfcEnabledByUser()&& imsManager.isWfcEnabledByPlatform()&&imsManager.isNonTtyOrTtyOnVolteEnabled();
}
/**
* Check if user is in Call.
* @param context Settings context
* @return true if call is ongoing.
*/
public static boolean isInCall(Context context) {
TelecomManager manager = (TelecomManager) context.getSystemService(
Context.TELECOM_SERVICE);
boolean inCall = false;
if (manager != null) {
inCall = manager.isInCall();
}
if (DEBUG) {
Log.d("yanghua", "[isInCall] = " + inCall);
}
return inCall;
}
private boolean isSimReady(){
int state = TelephonyManager.from(mContext).getSimCardState();
if (DEBUG) {
Log.d(TAG, "sim card state = " + state);
}
return true;
}
/**
* Get airplane Mode settings value.
* @param context Settings context
* @return true if airplane mode is on.
*/
public static boolean isAirplaneModeOn(Context context) {
return Global.getInt(context.getContentResolver(),
Global.AIRPLANE_MODE_ON, 0) != 0;
}
/**
* Get the IMS_STATE_XXX, so can get whether the state is in changing.
* @return true if the state is in changing, else return false.
*/
private boolean isInSwitchProcess() {
int imsState = MtkPhoneConstants.IMS_STATE_DISABLED;
try {
imsState = MtkImsManagerEx.getInstance().getImsState(
SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId()));
} catch (ImsException e) {
return false;
}
Log.d(TAG, "isInSwitchProcess, imsState=" + imsState);
return imsState == MtkPhoneConstants.IMS_STATE_DISABLING
|| imsState == MtkPhoneConstants.IMS_STATE_ENABLING;
}
private boolean isWfcEnable(){
boolean disable = false;
ImsManager imsManager = ImsManager.getInstance(mContext,SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId()));
if (null==imsManager){
if (DEBUG) {
Log.d(TAG, "isWfcEnable imsManager NUll");
}
return false;
}
disable = !imsManager.isWfcEnabledByPlatform() || !imsManager.isWfcProvisionedOnDevice();
if (DEBUG) {
Log.d(TAG, "isWfcEnable disable = " + disable);
}
return !disable;
}
}
由于国内运营商不支持vowifi,需要国外严重,后续可能会有修改。