diff options
| author | Joey Hewitt <joey@joeyhewitt.com> | 2021-01-04 22:46:03 -0700 |
|---|---|---|
| committer | Joey Hewitt <joey@joeyhewitt.com> | 2021-01-04 22:46:03 -0700 |
| commit | 2a117d3c4dc43dc88bc874bd0070a46f2be128e5 (patch) | |
| tree | 2e96dcab072ed924714e7a96e3ecda8e965c6b03 | |
| parent | 02b8d1a84e4089b6b1593295f72310c851121c3d (diff) | |
| download | frameworks_opt_telephony_ril_ofono-2a117d3c4dc43dc88bc874bd0070a46f2be128e5.tar.gz frameworks_opt_telephony_ril_ofono-2a117d3c4dc43dc88bc874bd0070a46f2be128e5.tar.bz2 frameworks_opt_telephony_ril_ofono-2a117d3c4dc43dc88bc874bd0070a46f2be128e5.zip | |
add NITZ time sync support
| -rw-r--r-- | lib/java/ofono/org/ofono/NetworkTime.java | 21 | ||||
| -rw-r--r-- | src/java/net/scintill/ril_ofono/NetworkTimeModule.java | 104 | ||||
| -rw-r--r-- | src/java/net/scintill/ril_ofono/RilOfono.java | 24 | ||||
| -rw-r--r-- | src/java/net/scintill/ril_ofono/RilWrapperBase.java | 17 | ||||
| -rw-r--r-- | src/java/net/scintill/ril_ofono/SaneBaseCommands.java | 6 |
5 files changed, 167 insertions, 5 deletions
diff --git a/lib/java/ofono/org/ofono/NetworkTime.java b/lib/java/ofono/org/ofono/NetworkTime.java new file mode 100644 index 0000000..03f7c62 --- /dev/null +++ b/lib/java/ofono/org/ofono/NetworkTime.java @@ -0,0 +1,21 @@ +package org.ofono; + +import org.freedesktop.dbus.DBusInterface; +import org.freedesktop.dbus.DBusSignal; +import org.freedesktop.dbus.Variant; +import org.freedesktop.dbus.exceptions.DBusException; + +import java.util.Map; + +public interface NetworkTime extends DBusInterface { + class NetworkTimeChanged extends DBusSignal { + public final Map<String, Variant<?>> time; + + public NetworkTimeChanged(String path, Map<String, Variant<?>> time) throws DBusException { + super(path, time); + this.time = time; + } + } + + Map<String,Variant<?>> GetNetworkTime(); +} diff --git a/src/java/net/scintill/ril_ofono/NetworkTimeModule.java b/src/java/net/scintill/ril_ofono/NetworkTimeModule.java new file mode 100644 index 0000000..ad45a3e --- /dev/null +++ b/src/java/net/scintill/ril_ofono/NetworkTimeModule.java @@ -0,0 +1,104 @@ +/* + * Copyright 2021 Joey Hewitt <joey@joeyhewitt.com> + * + * This file is part of ril_ofono. + * + * ril_ofono is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ril_ofono is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ril_ofono. If not, see <http://www.gnu.org/licenses/>. + */ + +package net.scintill.ril_ofono; + +import android.os.SystemProperties; +import android.telephony.Rlog; + +import com.android.internal.telephony.TelephonyProperties; + +import org.freedesktop.dbus.Variant; +import org.ofono.NetworkTime; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Map; + +/*package*/ class NetworkTimeModule { + + private static final String TAG = "RilOfono"; + + private RilOfono.RegistrantList mNITZTimeRegistrants; + private Object mLastTimeReceived; + + public NetworkTimeModule(NetworkTime networkTime, RilOfono.RegistrantList NITZTimeRegistrants) { + mNITZTimeRegistrants = NITZTimeRegistrants; + mLastTimeReceived = convertFromOfonoTime(networkTime.GetNetworkTime()); + sendNotificationOfLastTimeReceived(); + } + + void sendNotificationOfLastTimeReceived() { + if (mLastTimeReceived != null) { + mNITZTimeRegistrants.notifyResult(mLastTimeReceived); + } + } + + /** + * Convert an oFono time property map to the format the RIL expects (see comment inside.) + * oFono provides keys UTC, Timezone, Received, and DST. + * @param timeProps + * @return RIL representation + */ + private Object convertFromOfonoTime(Map<String, Variant<?>> timeProps) { + if (!(timeProps.containsKey("UTC") && timeProps.containsKey("Timezone") && + timeProps.containsKey("Received") && timeProps.containsKey("DST"))) { + return null; + } + + // oFono keys: UTC is since epoch (seconds), Timezone is the timezone + // offset (seconds), DST is the active DST offset (hours), and Received is when it was + // received (in seconds since boot). + long utcMsec = Long.parseLong(timeProps.get("UTC").getValue() + "000"); + int tzOffsetSec = ((Number) timeProps.get("Timezone").getValue()).intValue(); + tzOffsetSec += ((Number) timeProps.get("DST").getValue()).intValue() * 60 * 60; + long receivedMsec = Long.valueOf(timeProps.get("Received").getValue() + "000"); + + GregorianCalendar time = new GregorianCalendar(); + time.setTimeInMillis(utcMsec); + time.add(Calendar.SECOND, -tzOffsetSec); + + // From GsmServiceStateTracker: + // "yy/mm/dd,hh:mm:ss(+/-)tz" + // tz is in number of quarter-hours + String timeStr = String.format("%02d/%02d/%02d,%02d:%02d:%02d%d", + time.get(Calendar.YEAR) % 100, time.get(Calendar.MONTH) + 1, time.get(Calendar.DAY_OF_MONTH), + time.get(Calendar.HOUR_OF_DAY), time.get(Calendar.MINUTE), time.get(Calendar.SECOND), + tzOffsetSec / 15); + + return new Object[] { timeStr, receivedMsec }; + } + + void handle(NetworkTime.NetworkTimeChanged s) { + boolean ignoreNitz = SystemProperties.getBoolean(TelephonyProperties.PROPERTY_IGNORE_NITZ, false); + + if (ignoreNitz) { + // seems awkward to do here, but it's what RIL.java does. + Rlog.d(TAG, "ignoring NetworkTimeChanged signal"); + } else { + mLastTimeReceived = convertFromOfonoTime(s.time); + if (mLastTimeReceived != null) { + sendNotificationOfLastTimeReceived(); + } else { + Rlog.w(TAG, "time was not available in NITZ data"); + } + } + } + +} diff --git a/src/java/net/scintill/ril_ofono/RilOfono.java b/src/java/net/scintill/ril_ofono/RilOfono.java index fd04819..4b3247a 100644 --- a/src/java/net/scintill/ril_ofono/RilOfono.java +++ b/src/java/net/scintill/ril_ofono/RilOfono.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Joey Hewitt <joey@joeyhewitt.com> + * Copyright 2021 Joey Hewitt <joey@joeyhewitt.com> * * This file is part of ril_ofono. * @@ -55,6 +55,7 @@ import org.ofono.MessageManager; import org.ofono.MessageWaiting; import org.ofono.Modem; import org.ofono.NetworkRegistration; +import org.ofono.NetworkTime; import org.ofono.PathAndProperties; import org.ofono.SimManager; import org.ofono.SupplementaryServices; @@ -86,6 +87,7 @@ import static com.android.internal.telephony.CommandsInterface.RadioState; /*package*/ VoicecallModule mVoicecallModule; /*package*/ DatacallModule mDatacallModule; /*package*/ SupplementaryServicesModule mSupplementaryServicesModule; + /*package*/ NetworkTimeModule mNetworkTimeModule; private RilWrapperBase mRilWrapper; private Handler mDbusHandler; @@ -193,7 +195,7 @@ import static com.android.internal.telephony.CommandsInterface.RadioState; // to the next if an exception is encountered. for (Class<?> cl : new Class<?>[] { NetworkRegistration.class, MessageManager.class, SimManager.class, VoiceCallManager.class, - ConnectionManager.class, SupplementaryServices.class, + ConnectionManager.class, SupplementaryServices.class, NetworkTime.class, }) { try { if (cl == NetworkRegistration.class) { @@ -208,6 +210,8 @@ import static com.android.internal.telephony.CommandsInterface.RadioState; updateModuleForConnectionManager(ifaces); } else if (cl == SupplementaryServices.class) { updateModuleForSupplementaryServices(ifaces); + } else if (cl == NetworkTime.class) { + updateModuleForNetworkTime(ifaces); } else { throw new RuntimeException("invalid loop"); } @@ -300,6 +304,17 @@ import static com.android.internal.telephony.CommandsInterface.RadioState; } } + private void updateModuleForNetworkTime(@NonNull Set<String> ifaces) throws DBusException { + if (isInterfaceAbsent(NetworkTime.class, ifaces)) { + mNetworkTimeModule = null; + } else if (mSupplementaryServicesModule == null) { + mNetworkTimeModule = new NetworkTimeModule( + getOfonoInterface(NetworkTime.class), + mRilWrapper.mNITZTimeRegistrants + ); + } + } + private boolean isInterfaceAbsent(Class<?> cl, @NonNull Set<String> modemInterfaces) { return !modemInterfaces.contains(cl.getName()); } @@ -352,7 +367,7 @@ import static com.android.internal.telephony.CommandsInterface.RadioState; ConnectionManager.ContextRemoved.class, ConnectionContext.PropertyChanged.class, Modem.PropertyChanged.class, NetworkRegistration.PropertyChanged.class, SimManager.PropertyChanged.class, MessageWaiting.PropertyChanged.class, - Manager.ModemAdded.class, Manager.ModemRemoved.class, + Manager.ModemAdded.class, Manager.ModemRemoved.class, NetworkTime.NetworkTimeChanged.class, }); } @@ -409,6 +424,9 @@ import static com.android.internal.telephony.CommandsInterface.RadioState; } else if (s instanceof MessageWaiting.PropertyChanged && mSimModule != null) { mSimModule.handle((MessageWaiting.PropertyChanged) s); handled = true; + } else if (s instanceof NetworkTime.NetworkTimeChanged && mNetworkTimeModule != null) { + mNetworkTimeModule.handle((NetworkTime.NetworkTimeChanged) s); + handled = true; } else if (s instanceof Manager.ModemAdded) { handle((Manager.ModemAdded) s); handled = true; diff --git a/src/java/net/scintill/ril_ofono/RilWrapperBase.java b/src/java/net/scintill/ril_ofono/RilWrapperBase.java index 71d6a49..93f74a3 100644 --- a/src/java/net/scintill/ril_ofono/RilWrapperBase.java +++ b/src/java/net/scintill/ril_ofono/RilWrapperBase.java @@ -20,6 +20,7 @@ package net.scintill.ril_ofono; import android.content.Context; +import android.os.Handler; import android.os.Registrant; import android.telephony.Rlog; @@ -72,6 +73,12 @@ public abstract class RilWrapperBase extends SaneBaseCommands { return sCurrentMsg; } + /** + * A sentinel value that indicates that RilWrapper should not automatically return + * a value to the asynchronous caller. getCurrentMessage() will be used to return the value + * later. + * @see RilWrapperBase#getCurrentMessage() + * /*package*/ static final Object RETURN_LATER = new Object() { @Override public String toString() { @@ -79,9 +86,19 @@ public abstract class RilWrapperBase extends SaneBaseCommands { } }; + @Override + public void setOnNITZTime(Handler h, int what, Object obj) { + super.setOnNITZTime(h, what, obj); + // XXX this feels yucky like it's breaking an abstraction... + if (mRilOfono.mNetworkTimeModule != null) { + mRilOfono.mNetworkTimeModule.sendNotificationOfLastTimeReceived(); + } + } + /*package*/ RilOfono.RegistrantList mGsmSmsRegistrants = new DynamicRegistrantListFromField("mGsmSmsRegistrant"); /*package*/ RilOfono.RegistrantList mUSSDRegistrants = new DynamicRegistrantListFromField("mUSSDRegistrant"); /*package*/ RilOfono.RegistrantList mSignalStrengthRegistrants = new DynamicRegistrantListFromField("mSignalStrengthRegistrant"); + /*package*/ RilOfono.RegistrantList mNITZTimeRegistrants = new DynamicRegistrantListFromField("mNITZTimeRegistrant"); /*package*/ RilOfono.RegistrantList mVoiceNetworkStateRegistrants = new RegistrantListAndroidTypeWrapper(super.mVoiceNetworkStateRegistrants), diff --git a/src/java/net/scintill/ril_ofono/SaneBaseCommands.java b/src/java/net/scintill/ril_ofono/SaneBaseCommands.java index d691e03..d39cea8 100644 --- a/src/java/net/scintill/ril_ofono/SaneBaseCommands.java +++ b/src/java/net/scintill/ril_ofono/SaneBaseCommands.java @@ -25,14 +25,16 @@ import android.os.Message; import com.android.internal.telephony.BaseCommands; import com.android.internal.telephony.RadioCapability; +/** + * This is called sane, because it re-abstracts methods that were "implemented" with an empty body + * that never returns to callers. + */ /*package*/ abstract class SaneBaseCommands extends BaseCommands { public SaneBaseCommands(Context context) { super(context); } - // re-abstract methods that were "implemented" with an empty body that never returns to callers - @Override public abstract void sendSMSExpectMore(String smscPDU, String pdu, Message result); |
