Loading src/java/com/android/internal/telephony/BaseCommands.java +0 −4 Original line number Original line Diff line number Diff line Loading @@ -782,7 +782,6 @@ public abstract class BaseCommands implements CommandsInterface { if (mState.isAvailable() && !oldState.isAvailable()) { if (mState.isAvailable() && !oldState.isAvailable()) { mAvailRegistrants.notifyRegistrants(); mAvailRegistrants.notifyRegistrants(); onRadioAvailable(); } } if (!mState.isAvailable() && oldState.isAvailable()) { if (!mState.isAvailable() && oldState.isAvailable()) { Loading @@ -801,9 +800,6 @@ public abstract class BaseCommands implements CommandsInterface { } } } } protected void onRadioAvailable() { } /** /** * {@inheritDoc} * {@inheritDoc} */ */ Loading src/java/com/android/internal/telephony/CommandsInterface.java +18 −1 Original line number Original line Diff line number Diff line Loading @@ -2044,13 +2044,30 @@ public interface CommandsInterface { */ */ public void unregisterForPcoData(Handler h); public void unregisterForPcoData(Handler h); /** * Send the updated device state * * @param stateType Device state type * @param state True if enabled, otherwise disabled * @param result callback message contains the information of SUCCESS/FAILURE */ void sendDeviceState(int stateType, boolean state, Message result); /** * Send the device state to the modem * * @param filter unsolicited response filter. See DeviceStateMonitor.UnsolicitedResponseFilter * @param result callback message contains the information of SUCCESS/FAILURE */ void setUnsolResponseFilter(int filter, Message result); /** /** * Set SIM card power up or down * Set SIM card power up or down * * * @param powerUp True if powering up the sim card * @param powerUp True if powering up the sim card * @param result callback message contains the information of SUCCESS/FAILURE * @param result callback message contains the information of SUCCESS/FAILURE */ */ public void setSimCardPower(boolean powerUp, Message result); void setSimCardPower(boolean powerUp, Message result); default public List<ClientRequestStats> getClientRequestStats() { default public List<ClientRequestStats> getClientRequestStats() { return null; return null; Loading src/java/com/android/internal/telephony/DeviceStateMonitor.java 0 → 100644 +425 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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.internal.telephony; import static android.hardware.radio.V1_0.DeviceStateType.CHARGING_STATE; import static android.hardware.radio.V1_0.DeviceStateType.LOW_DATA_EXPECTED; import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.hardware.display.DisplayManager; import android.hardware.radio.V1_0.IndicationFilter; import android.net.ConnectivityManager; import android.os.BatteryManager; import android.os.Handler; import android.os.Message; import android.os.PowerManager; import android.telephony.Rlog; import android.util.LocalLog; import android.view.Display; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; /** * The device state monitor monitors the device state such as charging state, power saving sate, * and then passes down the information to the radio modem for the modem to perform its own * proprietary power saving strategy. Device state monitor also turns off the unsolicited * response from the modem when the device does not need to receive it, for example, device's * screen is off and does not have activities like tethering, remote display, etc...This effectively * prevents the CPU from waking up by those unnecessary unsolicited responses such as signal * strength update. */ public class DeviceStateMonitor extends Handler { protected static final boolean DBG = false; /* STOPSHIP if true */ protected static final String TAG = DeviceStateMonitor.class.getSimpleName(); private static final int EVENT_RIL_CONNECTED = 0; private static final int EVENT_SCREEN_STATE_CHANGED = 1; private static final int EVENT_POWER_SAVE_MODE_CHANGED = 2; private static final int EVENT_CHARGING_STATE_CHANGED = 3; private static final int EVENT_TETHERING_STATE_CHANGED = 4; private final Phone mPhone; private final LocalLog mLocalLog = new LocalLog(100); /** * Flag for wifi/usb/bluetooth tethering turned on or not */ private boolean mIsTetheringOn; /** * Screen state provided by Display Manager. True indicates screen on, otherwise off. */ // TODO: Support remote display and Android Auto in the future. private boolean mIsScreenStateOn; /** * Indicating the device is plugged in and is supplying sufficient power that the battery level * is going up (or the battery is fully charged). See BatteryManager.isCharging() for the * details */ private boolean mIsCharging; /** * Flag for device power save mode. See PowerManager.isPowerSaveMode() for the details. * Note that it is not possible both mIsCharging and mIsPowerSaveOn are true at the same time. * The system will automatically end power save mode when the device starts charging. */ private boolean mIsPowerSaveOn; /** * Low data expected mode. True indicates low data traffic is expected, for example, when the * device is idle (e.g. screen is off and not doing tethering in the background). Note this * doesn't mean no data is expected. */ private boolean mIsLowDataExpected; /** * The unsolicited response filter. See IndicationFilter defined in types.hal for the definition * of each bit. */ private int mUnsolicitedResponseFilter = IndicationFilter.ALL; /** * The built-in primary display. Used for retrieving the screen state. */ private final Display mDefaultDisplay; private final DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() { @Override public void onDisplayAdded(int displayId) { } @Override public void onDisplayRemoved(int displayId) { } @Override public void onDisplayChanged(int displayId) { if (displayId == Display.DEFAULT_DISPLAY) { boolean screenOn = isScreenOn(); Message msg = obtainMessage(EVENT_SCREEN_STATE_CHANGED); msg.arg1 = screenOn ? 1 : 0; log("Screen " + (screenOn ? "on" : "off"), true); sendMessage(msg); } } }; /** * Device state broadcast receiver */ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { log("received: " + intent, true); Message msg; switch (intent.getAction()) { case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED: msg = obtainMessage(EVENT_POWER_SAVE_MODE_CHANGED); msg.arg1 = isPowerSaveModeOn() ? 1 : 0; log("Power Save mode " + ((msg.arg1 == 1) ? "on" : "off"), true); break; case BatteryManager.ACTION_CHARGING: msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED); msg.arg1 = 1; // charging break; case BatteryManager.ACTION_DISCHARGING: msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED); msg.arg1 = 0; // not charging break; case ConnectivityManager.ACTION_TETHER_STATE_CHANGED: ArrayList<String> activeTetherIfaces = intent.getStringArrayListExtra( ConnectivityManager.EXTRA_ACTIVE_TETHER); boolean isTetheringOn = activeTetherIfaces != null && activeTetherIfaces.size() > 0; log("Tethering " + (isTetheringOn ? "on" : "off"), true); msg = obtainMessage(EVENT_TETHERING_STATE_CHANGED); msg.arg1 = isTetheringOn ? 1 : 0; break; default: log("Unexpected broadcast intent: " + intent, false); return; } sendMessage(msg); } }; /** * Device state monitor constructor. Note that each phone object should have its own device * state monitor, meaning there will be two device monitors on the multi-sim device. * * @param phone Phone object */ public DeviceStateMonitor(Phone phone) { mPhone = phone; DisplayManager dm = (DisplayManager) phone.getContext().getSystemService( Context.DISPLAY_SERVICE); mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY); dm.registerDisplayListener(mDisplayListener, null); mIsPowerSaveOn = isPowerSaveModeOn(); mIsCharging = isDeviceCharging(); mIsScreenStateOn = isScreenOn(); // Assuming tethering is always off after boot up. mIsTetheringOn = false; mIsLowDataExpected = false; log("DeviceStateMonitor mIsPowerSaveOn=" + mIsPowerSaveOn + ",mIsScreenStateOn=" + mIsScreenStateOn + ",mIsCharging=" + mIsCharging, false); final IntentFilter filter = new IntentFilter(); filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); filter.addAction(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); filter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone); mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null); } /** * @return True if low data is expected */ private boolean isLowDataExpected() { return mIsPowerSaveOn || (!mIsCharging && !mIsTetheringOn && !mIsScreenStateOn); } /** * @return True if signal strength update should be turned off. */ private boolean shouldTurnOffSignalStrength() { return mIsPowerSaveOn || (!mIsCharging && !mIsScreenStateOn); } /** * @return True if full network update should be turned off. Only significant changes will * trigger the network update unsolicited response. */ private boolean shouldTurnOffFullNetworkUpdate() { return mIsPowerSaveOn || (!mIsCharging && !mIsScreenStateOn && !mIsTetheringOn); } /** * @return True if data dormancy status update should be turned off. */ private boolean shouldTurnOffDormancyUpdate() { return mIsPowerSaveOn || (!mIsCharging && !mIsTetheringOn && !mIsScreenStateOn); } /** * Message handler * * @param msg The message */ @Override public void handleMessage(Message msg) { log("handleMessage msg=" + msg, false); switch (msg.what) { case EVENT_RIL_CONNECTED: onRilConnected(); break; default: updateDeviceState(msg.what, msg.arg1 != 0); } } /** * Update the device and send the information to the modem. * * @param eventType Device state event type * @param state True if enabled/on, otherwise disabled/off. */ private void updateDeviceState(int eventType, boolean state) { switch (eventType) { case EVENT_SCREEN_STATE_CHANGED: if (mIsScreenStateOn == state) return; mIsScreenStateOn = state; break; case EVENT_CHARGING_STATE_CHANGED: if (mIsCharging == state) return; mIsCharging = state; sendDeviceState(CHARGING_STATE, mIsCharging); break; case EVENT_TETHERING_STATE_CHANGED: if (mIsTetheringOn == state) return; mIsTetheringOn = state; break; case EVENT_POWER_SAVE_MODE_CHANGED: if (mIsPowerSaveOn == state) return; mIsPowerSaveOn = state; sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); break; default: return; } if (mIsLowDataExpected != isLowDataExpected()) { mIsLowDataExpected = !mIsLowDataExpected; sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); } int newFilter = 0; if (!shouldTurnOffSignalStrength()) { newFilter |= IndicationFilter.SIGNAL_STRENGTH; } if (!shouldTurnOffFullNetworkUpdate()) { newFilter |= IndicationFilter.FULL_NETWORK_STATE; } if (!shouldTurnOffDormancyUpdate()) { newFilter |= IndicationFilter.DATA_CALL_DORMANCY_CHANGED; } setUnsolResponseFilter(newFilter, false); } /** * Called when RIL is connected during boot up or reconnected after modem restart. * * When modem crashes, if the user turns the screen off before RIL reconnects, device * state and filter cannot be sent to modem. Resend the state here so that modem * has the correct state (to stop signal strength reporting, etc). */ private void onRilConnected() { log("RIL connected.", true); sendDeviceState(CHARGING_STATE, mIsCharging); sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); setUnsolResponseFilter(mUnsolicitedResponseFilter, true); } /** * Convert the device state type into string * * @param type Device state type * @return The converted string */ private String deviceTypeToString(int type) { switch (type) { case CHARGING_STATE: return "CHARGING_STATE"; case LOW_DATA_EXPECTED: return "LOW_DATA_EXPECTED"; case POWER_SAVE_MODE: return "POWER_SAVE_MODE"; default: return "UNKNOWN"; } } /** * Send the device state to the modem. * * @param type Device state type. See DeviceStateType defined in types.hal. * @param state True if enabled/on, otherwise disabled/off */ private void sendDeviceState(int type, boolean state) { log("send type: " + deviceTypeToString(type) + ", state=" + state, true); mPhone.mCi.sendDeviceState(type, state, null); } /** * Turn on/off the unsolicited response from the modem. * * @param newFilter See UnsolicitedResponseFilter in types.hal for the definition of each bit. * @param force Always set the filter when true. */ private void setUnsolResponseFilter(int newFilter, boolean force) { if (force || newFilter != mUnsolicitedResponseFilter) { log("old filter: " + mUnsolicitedResponseFilter + ", new filter: " + newFilter, true); mPhone.mCi.setUnsolResponseFilter(newFilter, null); mUnsolicitedResponseFilter = newFilter; } } /** * @return True if the device is currently in power save mode. * See {@link android.os.BatteryManager#isPowerSaveMode BatteryManager.isPowerSaveMode()}. */ private boolean isPowerSaveModeOn() { final PowerManager pm = (PowerManager) mPhone.getContext().getSystemService( Context.POWER_SERVICE); return pm.isPowerSaveMode(); } /** * @return Return true if the battery is currently considered to be charging. This means that * the device is plugged in and is supplying sufficient power that the battery level is * going up (or the battery is fully charged). * See {@link android.os.BatteryManager#isCharging BatteryManager.isCharging()}. */ private boolean isDeviceCharging() { final BatteryManager bm = (BatteryManager) mPhone.getContext().getSystemService( Context.BATTERY_SERVICE); return bm.isCharging(); } /** * @return True if the device's state is on. */ private boolean isScreenOn() { // Note that we don't listen to Intent.SCREEN_ON and Intent.SCREEN_OFF because they are no // longer adequate for monitoring the screen state since they are not sent in cases where // the screen is turned off transiently such as due to the proximity sensor. // Anything other than STATE_ON is treated as screen off, such as STATE_DOZE, // STATE_DOZE_SUSPEND, etc... return mDefaultDisplay.getState() == Display.STATE_ON; } /** * @param msg Debug message * @param logIntoLocalLog True if log into the local log */ private void log(String msg, boolean logIntoLocalLog) { if (DBG) Rlog.d(TAG, msg); if (logIntoLocalLog) { mLocalLog.log(msg); } } /** * Print the DeviceStateMonitor into the given stream. * * @param fd The raw file descriptor that the dump is being sent to. * @param pw A PrintWriter to which the dump is to be set. * @param args Additional arguments to the dump request. */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.increaseIndent(); ipw.println("mIsTetheringOn=" + mIsTetheringOn); ipw.println("mIsScreenStateOn=" + mIsScreenStateOn); ipw.println("mIsCharging=" + mIsCharging); ipw.println("mIsPowerSaveOn=" + mIsPowerSaveOn); ipw.println("mIsLowDataExpected=" + mIsLowDataExpected); ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter); ipw.println("Local logs:"); ipw.increaseIndent(); mLocalLog.dump(fd, ipw, args); ipw.decreaseIndent(); ipw.decreaseIndent(); ipw.flush(); } } src/java/com/android/internal/telephony/GsmCdmaPhone.java +19 −16 Original line number Original line Diff line number Diff line Loading @@ -43,29 +43,16 @@ import android.telecom.VideoProfile; import android.telephony.CarrierConfigManager; import android.telephony.CarrierConfigManager; import android.telephony.CellLocation; import android.telephony.CellLocation; import android.telephony.PhoneNumberUtils; import android.telephony.PhoneNumberUtils; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; import android.telephony.cdma.CdmaCellLocation; import android.telephony.cdma.CdmaCellLocation; import android.text.TextUtils; import android.text.TextUtils; import android.telephony.Rlog; import android.util.Log; import android.util.Log; import com.android.ims.ImsManager; import com.android.ims.ImsManager; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION; import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL; import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL; import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY; import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE; import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY; import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL; import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.cdma.CdmaMmiCode; import com.android.internal.telephony.cdma.CdmaMmiCode; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; Loading @@ -77,13 +64,13 @@ import com.android.internal.telephony.uicc.IccCardProxy; import com.android.internal.telephony.uicc.IccException; import com.android.internal.telephony.uicc.IccException; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.IccVmNotSupportedException; import com.android.internal.telephony.uicc.IccVmNotSupportedException; import com.android.internal.telephony.uicc.IsimRecords; import com.android.internal.telephony.uicc.IsimUiccRecords; import com.android.internal.telephony.uicc.RuimRecords; import com.android.internal.telephony.uicc.RuimRecords; import com.android.internal.telephony.uicc.SIMRecords; import com.android.internal.telephony.uicc.SIMRecords; import com.android.internal.telephony.uicc.UiccCard; import com.android.internal.telephony.uicc.UiccCard; import com.android.internal.telephony.uicc.UiccCardApplication; import com.android.internal.telephony.uicc.UiccCardApplication; import com.android.internal.telephony.uicc.UiccController; import com.android.internal.telephony.uicc.UiccController; import com.android.internal.telephony.uicc.IsimRecords; import com.android.internal.telephony.uicc.IsimUiccRecords; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; Loading @@ -92,6 +79,17 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.Pattern; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION; import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL; import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL; import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY; import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE; import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY; import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL; import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE; /** /** * {@hide} * {@hide} Loading Loading @@ -153,6 +151,7 @@ public class GsmCdmaPhone extends Phone { public ServiceStateTracker mSST; public ServiceStateTracker mSST; private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>(); private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>(); private IccPhoneBookInterfaceManager mIccPhoneBookIntManager; private IccPhoneBookInterfaceManager mIccPhoneBookIntManager; private DeviceStateMonitor mDeviceStateMonitor; private int mPrecisePhoneType; private int mPrecisePhoneType; Loading Loading @@ -205,6 +204,7 @@ public class GsmCdmaPhone extends Phone { // DcTracker uses SST so needs to be created after it is instantiated // DcTracker uses SST so needs to be created after it is instantiated mDcTracker = mTelephonyComponentFactory.makeDcTracker(this); mDcTracker = mTelephonyComponentFactory.makeDcTracker(this); mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); mDeviceStateMonitor = mTelephonyComponentFactory.makeDeviceStateMonitor(this); logd("GsmCdmaPhone: constructor: sub = " + mPhoneId); logd("GsmCdmaPhone: constructor: sub = " + mPhoneId); } } Loading Loading @@ -3211,6 +3211,9 @@ public class GsmCdmaPhone extends Phone { } } pw.flush(); pw.flush(); pw.println("++++++++++++++++++++++++++++++++"); pw.println("++++++++++++++++++++++++++++++++"); pw.println("DeviceStateMonitor:"); mDeviceStateMonitor.dump(fd, pw, args); pw.println("++++++++++++++++++++++++++++++++"); } } @Override @Override Loading src/java/com/android/internal/telephony/RIL.java +45 −109 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/java/com/android/internal/telephony/BaseCommands.java +0 −4 Original line number Original line Diff line number Diff line Loading @@ -782,7 +782,6 @@ public abstract class BaseCommands implements CommandsInterface { if (mState.isAvailable() && !oldState.isAvailable()) { if (mState.isAvailable() && !oldState.isAvailable()) { mAvailRegistrants.notifyRegistrants(); mAvailRegistrants.notifyRegistrants(); onRadioAvailable(); } } if (!mState.isAvailable() && oldState.isAvailable()) { if (!mState.isAvailable() && oldState.isAvailable()) { Loading @@ -801,9 +800,6 @@ public abstract class BaseCommands implements CommandsInterface { } } } } protected void onRadioAvailable() { } /** /** * {@inheritDoc} * {@inheritDoc} */ */ Loading
src/java/com/android/internal/telephony/CommandsInterface.java +18 −1 Original line number Original line Diff line number Diff line Loading @@ -2044,13 +2044,30 @@ public interface CommandsInterface { */ */ public void unregisterForPcoData(Handler h); public void unregisterForPcoData(Handler h); /** * Send the updated device state * * @param stateType Device state type * @param state True if enabled, otherwise disabled * @param result callback message contains the information of SUCCESS/FAILURE */ void sendDeviceState(int stateType, boolean state, Message result); /** * Send the device state to the modem * * @param filter unsolicited response filter. See DeviceStateMonitor.UnsolicitedResponseFilter * @param result callback message contains the information of SUCCESS/FAILURE */ void setUnsolResponseFilter(int filter, Message result); /** /** * Set SIM card power up or down * Set SIM card power up or down * * * @param powerUp True if powering up the sim card * @param powerUp True if powering up the sim card * @param result callback message contains the information of SUCCESS/FAILURE * @param result callback message contains the information of SUCCESS/FAILURE */ */ public void setSimCardPower(boolean powerUp, Message result); void setSimCardPower(boolean powerUp, Message result); default public List<ClientRequestStats> getClientRequestStats() { default public List<ClientRequestStats> getClientRequestStats() { return null; return null; Loading
src/java/com/android/internal/telephony/DeviceStateMonitor.java 0 → 100644 +425 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 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.internal.telephony; import static android.hardware.radio.V1_0.DeviceStateType.CHARGING_STATE; import static android.hardware.radio.V1_0.DeviceStateType.LOW_DATA_EXPECTED; import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.hardware.display.DisplayManager; import android.hardware.radio.V1_0.IndicationFilter; import android.net.ConnectivityManager; import android.os.BatteryManager; import android.os.Handler; import android.os.Message; import android.os.PowerManager; import android.telephony.Rlog; import android.util.LocalLog; import android.view.Display; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; /** * The device state monitor monitors the device state such as charging state, power saving sate, * and then passes down the information to the radio modem for the modem to perform its own * proprietary power saving strategy. Device state monitor also turns off the unsolicited * response from the modem when the device does not need to receive it, for example, device's * screen is off and does not have activities like tethering, remote display, etc...This effectively * prevents the CPU from waking up by those unnecessary unsolicited responses such as signal * strength update. */ public class DeviceStateMonitor extends Handler { protected static final boolean DBG = false; /* STOPSHIP if true */ protected static final String TAG = DeviceStateMonitor.class.getSimpleName(); private static final int EVENT_RIL_CONNECTED = 0; private static final int EVENT_SCREEN_STATE_CHANGED = 1; private static final int EVENT_POWER_SAVE_MODE_CHANGED = 2; private static final int EVENT_CHARGING_STATE_CHANGED = 3; private static final int EVENT_TETHERING_STATE_CHANGED = 4; private final Phone mPhone; private final LocalLog mLocalLog = new LocalLog(100); /** * Flag for wifi/usb/bluetooth tethering turned on or not */ private boolean mIsTetheringOn; /** * Screen state provided by Display Manager. True indicates screen on, otherwise off. */ // TODO: Support remote display and Android Auto in the future. private boolean mIsScreenStateOn; /** * Indicating the device is plugged in and is supplying sufficient power that the battery level * is going up (or the battery is fully charged). See BatteryManager.isCharging() for the * details */ private boolean mIsCharging; /** * Flag for device power save mode. See PowerManager.isPowerSaveMode() for the details. * Note that it is not possible both mIsCharging and mIsPowerSaveOn are true at the same time. * The system will automatically end power save mode when the device starts charging. */ private boolean mIsPowerSaveOn; /** * Low data expected mode. True indicates low data traffic is expected, for example, when the * device is idle (e.g. screen is off and not doing tethering in the background). Note this * doesn't mean no data is expected. */ private boolean mIsLowDataExpected; /** * The unsolicited response filter. See IndicationFilter defined in types.hal for the definition * of each bit. */ private int mUnsolicitedResponseFilter = IndicationFilter.ALL; /** * The built-in primary display. Used for retrieving the screen state. */ private final Display mDefaultDisplay; private final DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() { @Override public void onDisplayAdded(int displayId) { } @Override public void onDisplayRemoved(int displayId) { } @Override public void onDisplayChanged(int displayId) { if (displayId == Display.DEFAULT_DISPLAY) { boolean screenOn = isScreenOn(); Message msg = obtainMessage(EVENT_SCREEN_STATE_CHANGED); msg.arg1 = screenOn ? 1 : 0; log("Screen " + (screenOn ? "on" : "off"), true); sendMessage(msg); } } }; /** * Device state broadcast receiver */ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { log("received: " + intent, true); Message msg; switch (intent.getAction()) { case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED: msg = obtainMessage(EVENT_POWER_SAVE_MODE_CHANGED); msg.arg1 = isPowerSaveModeOn() ? 1 : 0; log("Power Save mode " + ((msg.arg1 == 1) ? "on" : "off"), true); break; case BatteryManager.ACTION_CHARGING: msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED); msg.arg1 = 1; // charging break; case BatteryManager.ACTION_DISCHARGING: msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED); msg.arg1 = 0; // not charging break; case ConnectivityManager.ACTION_TETHER_STATE_CHANGED: ArrayList<String> activeTetherIfaces = intent.getStringArrayListExtra( ConnectivityManager.EXTRA_ACTIVE_TETHER); boolean isTetheringOn = activeTetherIfaces != null && activeTetherIfaces.size() > 0; log("Tethering " + (isTetheringOn ? "on" : "off"), true); msg = obtainMessage(EVENT_TETHERING_STATE_CHANGED); msg.arg1 = isTetheringOn ? 1 : 0; break; default: log("Unexpected broadcast intent: " + intent, false); return; } sendMessage(msg); } }; /** * Device state monitor constructor. Note that each phone object should have its own device * state monitor, meaning there will be two device monitors on the multi-sim device. * * @param phone Phone object */ public DeviceStateMonitor(Phone phone) { mPhone = phone; DisplayManager dm = (DisplayManager) phone.getContext().getSystemService( Context.DISPLAY_SERVICE); mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY); dm.registerDisplayListener(mDisplayListener, null); mIsPowerSaveOn = isPowerSaveModeOn(); mIsCharging = isDeviceCharging(); mIsScreenStateOn = isScreenOn(); // Assuming tethering is always off after boot up. mIsTetheringOn = false; mIsLowDataExpected = false; log("DeviceStateMonitor mIsPowerSaveOn=" + mIsPowerSaveOn + ",mIsScreenStateOn=" + mIsScreenStateOn + ",mIsCharging=" + mIsCharging, false); final IntentFilter filter = new IntentFilter(); filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); filter.addAction(BatteryManager.ACTION_CHARGING); filter.addAction(BatteryManager.ACTION_DISCHARGING); filter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone); mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null); } /** * @return True if low data is expected */ private boolean isLowDataExpected() { return mIsPowerSaveOn || (!mIsCharging && !mIsTetheringOn && !mIsScreenStateOn); } /** * @return True if signal strength update should be turned off. */ private boolean shouldTurnOffSignalStrength() { return mIsPowerSaveOn || (!mIsCharging && !mIsScreenStateOn); } /** * @return True if full network update should be turned off. Only significant changes will * trigger the network update unsolicited response. */ private boolean shouldTurnOffFullNetworkUpdate() { return mIsPowerSaveOn || (!mIsCharging && !mIsScreenStateOn && !mIsTetheringOn); } /** * @return True if data dormancy status update should be turned off. */ private boolean shouldTurnOffDormancyUpdate() { return mIsPowerSaveOn || (!mIsCharging && !mIsTetheringOn && !mIsScreenStateOn); } /** * Message handler * * @param msg The message */ @Override public void handleMessage(Message msg) { log("handleMessage msg=" + msg, false); switch (msg.what) { case EVENT_RIL_CONNECTED: onRilConnected(); break; default: updateDeviceState(msg.what, msg.arg1 != 0); } } /** * Update the device and send the information to the modem. * * @param eventType Device state event type * @param state True if enabled/on, otherwise disabled/off. */ private void updateDeviceState(int eventType, boolean state) { switch (eventType) { case EVENT_SCREEN_STATE_CHANGED: if (mIsScreenStateOn == state) return; mIsScreenStateOn = state; break; case EVENT_CHARGING_STATE_CHANGED: if (mIsCharging == state) return; mIsCharging = state; sendDeviceState(CHARGING_STATE, mIsCharging); break; case EVENT_TETHERING_STATE_CHANGED: if (mIsTetheringOn == state) return; mIsTetheringOn = state; break; case EVENT_POWER_SAVE_MODE_CHANGED: if (mIsPowerSaveOn == state) return; mIsPowerSaveOn = state; sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); break; default: return; } if (mIsLowDataExpected != isLowDataExpected()) { mIsLowDataExpected = !mIsLowDataExpected; sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); } int newFilter = 0; if (!shouldTurnOffSignalStrength()) { newFilter |= IndicationFilter.SIGNAL_STRENGTH; } if (!shouldTurnOffFullNetworkUpdate()) { newFilter |= IndicationFilter.FULL_NETWORK_STATE; } if (!shouldTurnOffDormancyUpdate()) { newFilter |= IndicationFilter.DATA_CALL_DORMANCY_CHANGED; } setUnsolResponseFilter(newFilter, false); } /** * Called when RIL is connected during boot up or reconnected after modem restart. * * When modem crashes, if the user turns the screen off before RIL reconnects, device * state and filter cannot be sent to modem. Resend the state here so that modem * has the correct state (to stop signal strength reporting, etc). */ private void onRilConnected() { log("RIL connected.", true); sendDeviceState(CHARGING_STATE, mIsCharging); sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); setUnsolResponseFilter(mUnsolicitedResponseFilter, true); } /** * Convert the device state type into string * * @param type Device state type * @return The converted string */ private String deviceTypeToString(int type) { switch (type) { case CHARGING_STATE: return "CHARGING_STATE"; case LOW_DATA_EXPECTED: return "LOW_DATA_EXPECTED"; case POWER_SAVE_MODE: return "POWER_SAVE_MODE"; default: return "UNKNOWN"; } } /** * Send the device state to the modem. * * @param type Device state type. See DeviceStateType defined in types.hal. * @param state True if enabled/on, otherwise disabled/off */ private void sendDeviceState(int type, boolean state) { log("send type: " + deviceTypeToString(type) + ", state=" + state, true); mPhone.mCi.sendDeviceState(type, state, null); } /** * Turn on/off the unsolicited response from the modem. * * @param newFilter See UnsolicitedResponseFilter in types.hal for the definition of each bit. * @param force Always set the filter when true. */ private void setUnsolResponseFilter(int newFilter, boolean force) { if (force || newFilter != mUnsolicitedResponseFilter) { log("old filter: " + mUnsolicitedResponseFilter + ", new filter: " + newFilter, true); mPhone.mCi.setUnsolResponseFilter(newFilter, null); mUnsolicitedResponseFilter = newFilter; } } /** * @return True if the device is currently in power save mode. * See {@link android.os.BatteryManager#isPowerSaveMode BatteryManager.isPowerSaveMode()}. */ private boolean isPowerSaveModeOn() { final PowerManager pm = (PowerManager) mPhone.getContext().getSystemService( Context.POWER_SERVICE); return pm.isPowerSaveMode(); } /** * @return Return true if the battery is currently considered to be charging. This means that * the device is plugged in and is supplying sufficient power that the battery level is * going up (or the battery is fully charged). * See {@link android.os.BatteryManager#isCharging BatteryManager.isCharging()}. */ private boolean isDeviceCharging() { final BatteryManager bm = (BatteryManager) mPhone.getContext().getSystemService( Context.BATTERY_SERVICE); return bm.isCharging(); } /** * @return True if the device's state is on. */ private boolean isScreenOn() { // Note that we don't listen to Intent.SCREEN_ON and Intent.SCREEN_OFF because they are no // longer adequate for monitoring the screen state since they are not sent in cases where // the screen is turned off transiently such as due to the proximity sensor. // Anything other than STATE_ON is treated as screen off, such as STATE_DOZE, // STATE_DOZE_SUSPEND, etc... return mDefaultDisplay.getState() == Display.STATE_ON; } /** * @param msg Debug message * @param logIntoLocalLog True if log into the local log */ private void log(String msg, boolean logIntoLocalLog) { if (DBG) Rlog.d(TAG, msg); if (logIntoLocalLog) { mLocalLog.log(msg); } } /** * Print the DeviceStateMonitor into the given stream. * * @param fd The raw file descriptor that the dump is being sent to. * @param pw A PrintWriter to which the dump is to be set. * @param args Additional arguments to the dump request. */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.increaseIndent(); ipw.println("mIsTetheringOn=" + mIsTetheringOn); ipw.println("mIsScreenStateOn=" + mIsScreenStateOn); ipw.println("mIsCharging=" + mIsCharging); ipw.println("mIsPowerSaveOn=" + mIsPowerSaveOn); ipw.println("mIsLowDataExpected=" + mIsLowDataExpected); ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter); ipw.println("Local logs:"); ipw.increaseIndent(); mLocalLog.dump(fd, ipw, args); ipw.decreaseIndent(); ipw.decreaseIndent(); ipw.flush(); } }
src/java/com/android/internal/telephony/GsmCdmaPhone.java +19 −16 Original line number Original line Diff line number Diff line Loading @@ -43,29 +43,16 @@ import android.telecom.VideoProfile; import android.telephony.CarrierConfigManager; import android.telephony.CarrierConfigManager; import android.telephony.CellLocation; import android.telephony.CellLocation; import android.telephony.PhoneNumberUtils; import android.telephony.PhoneNumberUtils; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; import android.telephony.cdma.CdmaCellLocation; import android.telephony.cdma.CdmaCellLocation; import android.text.TextUtils; import android.text.TextUtils; import android.telephony.Rlog; import android.util.Log; import android.util.Log; import com.android.ims.ImsManager; import com.android.ims.ImsManager; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION; import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL; import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL; import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY; import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE; import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY; import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL; import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.cdma.CdmaMmiCode; import com.android.internal.telephony.cdma.CdmaMmiCode; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; Loading @@ -77,13 +64,13 @@ import com.android.internal.telephony.uicc.IccCardProxy; import com.android.internal.telephony.uicc.IccException; import com.android.internal.telephony.uicc.IccException; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.IccVmNotSupportedException; import com.android.internal.telephony.uicc.IccVmNotSupportedException; import com.android.internal.telephony.uicc.IsimRecords; import com.android.internal.telephony.uicc.IsimUiccRecords; import com.android.internal.telephony.uicc.RuimRecords; import com.android.internal.telephony.uicc.RuimRecords; import com.android.internal.telephony.uicc.SIMRecords; import com.android.internal.telephony.uicc.SIMRecords; import com.android.internal.telephony.uicc.UiccCard; import com.android.internal.telephony.uicc.UiccCard; import com.android.internal.telephony.uicc.UiccCardApplication; import com.android.internal.telephony.uicc.UiccCardApplication; import com.android.internal.telephony.uicc.UiccController; import com.android.internal.telephony.uicc.UiccController; import com.android.internal.telephony.uicc.IsimRecords; import com.android.internal.telephony.uicc.IsimUiccRecords; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; Loading @@ -92,6 +79,17 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.Pattern; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE; import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION; import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL; import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL; import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY; import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE; import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY; import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL; import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE; /** /** * {@hide} * {@hide} Loading Loading @@ -153,6 +151,7 @@ public class GsmCdmaPhone extends Phone { public ServiceStateTracker mSST; public ServiceStateTracker mSST; private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>(); private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>(); private IccPhoneBookInterfaceManager mIccPhoneBookIntManager; private IccPhoneBookInterfaceManager mIccPhoneBookIntManager; private DeviceStateMonitor mDeviceStateMonitor; private int mPrecisePhoneType; private int mPrecisePhoneType; Loading Loading @@ -205,6 +204,7 @@ public class GsmCdmaPhone extends Phone { // DcTracker uses SST so needs to be created after it is instantiated // DcTracker uses SST so needs to be created after it is instantiated mDcTracker = mTelephonyComponentFactory.makeDcTracker(this); mDcTracker = mTelephonyComponentFactory.makeDcTracker(this); mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); mDeviceStateMonitor = mTelephonyComponentFactory.makeDeviceStateMonitor(this); logd("GsmCdmaPhone: constructor: sub = " + mPhoneId); logd("GsmCdmaPhone: constructor: sub = " + mPhoneId); } } Loading Loading @@ -3211,6 +3211,9 @@ public class GsmCdmaPhone extends Phone { } } pw.flush(); pw.flush(); pw.println("++++++++++++++++++++++++++++++++"); pw.println("++++++++++++++++++++++++++++++++"); pw.println("DeviceStateMonitor:"); mDeviceStateMonitor.dump(fd, pw, args); pw.println("++++++++++++++++++++++++++++++++"); } } @Override @Override Loading
src/java/com/android/internal/telephony/RIL.java +45 −109 File changed.Preview size limit exceeded, changes collapsed. Show changes