summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoey Hewitt <joey@joeyhewitt.com>2021-01-04 22:46:03 -0700
committerJoey Hewitt <joey@joeyhewitt.com>2021-01-04 22:46:03 -0700
commit2a117d3c4dc43dc88bc874bd0070a46f2be128e5 (patch)
tree2e96dcab072ed924714e7a96e3ecda8e965c6b03
parent02b8d1a84e4089b6b1593295f72310c851121c3d (diff)
downloadframeworks_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.java21
-rw-r--r--src/java/net/scintill/ril_ofono/NetworkTimeModule.java104
-rw-r--r--src/java/net/scintill/ril_ofono/RilOfono.java24
-rw-r--r--src/java/net/scintill/ril_ofono/RilWrapperBase.java17
-rw-r--r--src/java/net/scintill/ril_ofono/SaneBaseCommands.java6
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);