Code Monkey home page Code Monkey logo

dejavu's Introduction

Déjà Vu - A Local RF Based Backend

This is a backend for UnifiedNlp that uses locally acquired WLAN/WiFi AP and mobile/cellular tower data to resolve user location. Collectively, “WLAN/WiFi and mobile/cellular” signals will be called “RF emitters” below.

Conceptually, this backend consists of two parts sharing a common database. One part passively monitors the GPS. If the GPS has acquired and has a good position accuracy, then the coverage maps for RF emitters detected by the phone are created and saved.

The other part is the actual location provider which uses the database to estimate location when the GPS is not available.

This backend uses no network data. All data acquired by the phone stays on the phone.

Get it on F-Droid

Yet Another Location Backend

This grew out of frustration with my earlier mobile tower backend’s two major faults:

  1. Need to periodically download a huge database. Only feasible when using WLAN/Wifi or fast unlimited mobile/cellular data.
  2. Despite repeated use of stumbling apps for the two projects that maintain tower data, the database never had good results for some very rural areas I frequently visit.

I decided that I wanted a mobile/cellular backend that worked the same way as my WLAN/WiFi backend. Initially I considered adding mobile/cellular support to the WLAN/WiFi backend.

However, the WLAN/WiFi backend had grown over time and had developed complex settings that had to be repeatedly explained.

Thus this new backend that has been written from scratch, admittedly with some copying and much inspiration from the two previous backends.

It is structured so that adding additional RF emitter types like Bluetooth should be easy. However based on warnings about high resource use when scanning for Bluetooth and the high probability that a Bluetooth device will be mobile that has not been implemented.

Requirements on phone

This is a plug-in for µg UnifiedNlp which can be installed from f-droid. The µg GmsCore can also use this backend.

Setup on phone

In the NLP Controller app (interface for µg UnifiedNlp) select the "Déjà Vu Location Service". If using GmsCore, then the little gear at microG Settings->UnifiedNlp Settings->Configure location backends->Déjà Vu Location Service is used.

When enabled, microG will request you grant location permissions to this backend. This is required so that the backend can monitor mobile/cell tower data and so that it can monitor the positions reported by the GPS.

Note: The microG configuration check requires a location from a location backend to indicate that it is setup properly. However this backend will not return a location until it has mapped at least one mobile cell tower or two WLAN/WiFi access points. So it is necessary to run an app that uses the GPS for a while before this backend will report information to microG. You may wish to also install a different backend to verify microG setup quickly.

Collecting RF Emitter Data

To conserve power the collection process does not actually turn on the GPS. If some other app turns on the GPS, for example a map or navigation app, then the backend will monitor the location and collect RF emitter data.

What is stored in the database

For each RF emitter detected an estimate of its coverage area (center and radius) and an estimate of how much it can be trusted is saved.

For WLAN/WiFi APs the SSID is also saved for debug purposes. Analysis of the SSIDs detected by the phone can help identify name patterns used on mobile APs. The backend removes records from the database if the RF emitter seems to have moved, has disappeared or has a SSID that is associated with WLAN/WiFi APs that are often mobile (e.g. "Joes iPhone").

Clearing the database

This software does not have a clear or reset database function built it but you can use settings->Storage>Internal shared storage->Apps->Déjà Vu Location Service->Clear Data to remove the current database.

Moved RF Emitter Handling

For position computations we wish to only use stationary RF emitters. For mobile/cellular towers this is not a huge problem. But with transit systems providing WiFi, car manufacturer's building WiFi hotspots into vehicles and the general use of WiFi tethering on mobile/cell phones, moving APs is an issue.

This backend attempts to handle that in several ways.

  1. If the SSID of a WiFi AP matches a known pattern for an AP that is likely to be moving, the AP is “blacklisted”. Examples include SSIDs that have the name of a known transit company, SSIDs that contain "iphone" in the name, etc. You can examine the black list logic in the blacklistWifi() method of the RfEmitter class.
  2. A RF Emitter needs to be seen multiple times in locations that are reasonably close to one another before it is trusted.
  3. If the implied coverage area for a RF emitter is implausibly large, it is assumed that it has moved. Moved emitters will not be trusted again until they have a number of observations compatible with their new location.
  4. When a scan completes, the RF emitters are grouped by how close they are to one another. An emitter that is implausibly far from others ends up in its own group. We use the largest group of emitters to compute location.
  5. If we have a good location from the GPS we see if there are any RF emitters that we should have seen on our RF scan but did not. If we expected to see an emitter but didn’t, then we lower our level of trust in the emitter’s location.
  6. If our trust of an emitter’s location goes too low (i.e. we haven’t seen it in a long while in an area where we expect to see it), we remove the emitter from our database.

Permissions Required

Permission Use
ACCESS_COARSE_LOCATION Allows backend to determine which cell towers your phone detects.
ACCESS_FINE_LOCATION Allows backend to monitor position reports from the GPS.

Note: The backend uses standard Android API calls to determine if it has sufficient privileges before attempting privileged operations. But there appears to be an issue with some versions of CyanogenMod where the permission check succeeds when the backend does not actually have the permissions is needs. The result is a continuous series of force closes which can lock up the Launcher UI or the phone. If you are using CyanogenMod, you should grant permissions to Dévá Vu prior to selecting it in the settings UnifiedNlp or microG. LineageOS 14.1 does not have this issue nor does it seem to appear on AOSP based ROMs. See issues 2 and 8 in the bug list for details.

Changes

Revision history is kept in a separate change log.

Credits

The Kalman filter used in this backend is based on work by @villoren.

License

Most of this project is licensed by GNU GPL. The Kalman filter code retains its original MIT license.

Icon

The icon for this project is derived from two sources:

A globe icon and a map pin icon both released under a Creative Commons share alike license.

GNU General Public License

Copyright (C) 2017-18 Tod Fitch

This program 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.

This program 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

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

dejavu's People

Contributors

akallabeth avatar bboa avatar burunduk avatar lbschenkel avatar lee-carre avatar n76 avatar poussinou avatar skewedzeppelin avatar verdulo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dejavu's Issues

Déjà Vu 1.0.8 crashes Android 5.0.2 device

Hi,

When I try to activate (= simply check the box, no need to tap ok !) Déjà Vu 1.0.8 in MicroG/UnifiedNlp settings on a Sony Xperia SP (C5303) running Android 5.0.2 (CyanogenMod 12), the phone crashes then reboots 100% of the time :

I/ActivityManager(14083): Start proc org.fitchfamily.android.dejavu for service org.fitchfamily.android.dejavu/.BackendService: pid=17544 uid=10082 gids={50082, 9997} abi=armeabi-v7a
F/libc    (17544): invalid address or address of corrupt block 0x28 passed to dlfree
F/libc    (17544): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 17544 (.android.dejavu)
I/DEBUG   (  670): property debug.db.uid not set; NOT waiting for gdb.
I/DEBUG   (  670): HINT: adb shell setprop debug.db.uid 100000
I/DEBUG   (  670): HINT: adb forward tcp:5039 tcp:5039
I/DEBUG   (  670): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  670): Build fingerprint: 'Sony/C5303/C5303:4.3/12.1.A.1.207/Nvt_nw:user/release-keys'
I/DEBUG   (  670): Revision: '0'
I/DEBUG   (  670): ABI: 'arm'
I/DEBUG   (  670): pid: 17544, tid: 17544, name: .android.dejavu  >>> org.fitchfamily.android.dejavu <<<
I/DEBUG   (  670): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbaad
I/DEBUG   (  670): Abort message: 'invalid address or address of corrupt block 0x28 passed to dlfree'
I/DEBUG   (  670):     r0 00000000  r1 b6fb6dec  r2 deadbaad  r3 00000000
I/DEBUG   (  670):     r4 00000028  r5 b6fb80d4  r6 a4d21000  r7 00000030
I/DEBUG   (  670):     r8 be8e7c5c  r9 be8e7d1c  sl b6ca6226  fp b6ca622f
I/DEBUG   (  670):     ip 00008000  sp be8e7c08  lr b6f887af  pc b6f887b0  cpsr 600d0030
I/DEBUG   (  670): 
I/DEBUG   (  670): backtrace:
I/DEBUG   (  670):     #00 pc 000287b0  /system/lib/libc.so (dlfree+1239)
I/DEBUG   (  670):     #01 pc 0000f043  /system/lib/libc.so (free+10)
I/DEBUG   (  670):     #02 pc 00013a1d  /system/lib/libandroidfw.so (android::ResStringPool::uninit()+38)
I/DEBUG   (  670):     #03 pc 00014777  /system/lib/libandroidfw.so (android::ResXMLTree::uninit()+12)
I/DEBUG   (  670):     #04 pc 00014795  /system/lib/libandroidfw.so (android::ResXMLTree::~ResXMLTree()+4)
I/DEBUG   (  670):     #05 pc 00011487  /system/lib/libandroidfw.so (android::AssetManager::getPkgName(char const*)+258)
I/DEBUG   (  670):     #06 pc 000114e9  /system/lib/libandroidfw.so (android::AssetManager::getBasePackageName(unsigned int)+68)
I/DEBUG   (  670):     #07 pc 00081af7  /system/lib/libandroid_runtime.so
I/DEBUG   (  670):     #08 pc 00270eef  /data/dalvik-cache/arm/system@[email protected]
I/DEBUG   (  670): 
I/DEBUG   (  670): Tombstone written to: /data/tombstones/tombstone_04
I/BootReceiver(14083): Copying /data/tombstones/tombstone_04 to DropBox (SYSTEM_TOMBSTONE)
E/SharedPreferencesImpl(14083): Couldn't create directory for SharedPreferences file shared_prefs/log_files.xml
F/libc    (14083): invalid address or address of corrupt block 0xa0 passed to dlfree
F/libc    (14083): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 14137 (ActivityManager)
I/DEBUG   (  670): property debug.db.uid not set; NOT waiting for gdb.
I/DEBUG   (  670): HINT: adb shell setprop debug.db.uid 100000
I/DEBUG   (  670): HINT: adb forward tcp:5039 tcp:5039
I/Zygote  (13882): Process 17544 exited due to signal (11)
I/DEBUG   (  670): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  670): Build fingerprint: 'Sony/C5303/C5303:4.3/12.1.A.1.207/Nvt_nw:user/release-keys'
I/DEBUG   (  670): Revision: '0'
I/DEBUG   (  670): ABI: 'arm'
I/DEBUG   (  670): pid: 14083, tid: 14137, name: ActivityManager  >>> system_server <<<
I/DEBUG   (  670): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbaad
I/DEBUG   (  670): Abort message: 'invalid address or address of corrupt block 0xa0 passed to dlfree'
I/DEBUG   (  670):     r0 00000000  r1 b6fb6dec  r2 deadbaad  r3 00000000
I/DEBUG   (  670):     r4 000000a0  r5 b6fb80d4  r6 9b1fb000  r7 000000a8
I/DEBUG   (  670):     r8 a53a549c  r9 a53a555c  sl b6ca6226  fp b6ca622f
I/DEBUG   (  670):     ip 00008000  sp a53a5448  lr b6f887af  pc b6f887b0  cpsr 600d0030
I/DEBUG   (  670): 
I/DEBUG   (  670): backtrace:
I/DEBUG   (  670):     #00 pc 000287b0  /system/lib/libc.so (dlfree+1239)
I/DEBUG   (  670):     #01 pc 0000f043  /system/lib/libc.so (free+10)
I/DEBUG   (  670):     #02 pc 00013a1d  /system/lib/libandroidfw.so (android::ResStringPool::uninit()+38)
I/DEBUG   (  670):     #03 pc 00014777  /system/lib/libandroidfw.so (android::ResXMLTree::uninit()+12)
I/DEBUG   (  670):     #04 pc 00014795  /system/lib/libandroidfw.so (android::ResXMLTree::~ResXMLTree()+4)
I/DEBUG   (  670):     #05 pc 00011487  /system/lib/libandroidfw.so (android::AssetManager::getPkgName(char const*)+258)
I/DEBUG   (  670):     #06 pc 000114e9  /system/lib/libandroidfw.so (android::AssetManager::getBasePackageName(unsigned int)+68)
I/DEBUG   (  670):     #07 pc 00081af7  /system/lib/libandroid_runtime.so
I/DEBUG   (  670):     #08 pc 00270eef  /data/dalvik-cache/arm/system@[email protected]
I/DEBUG   (  670): 
I/DEBUG   (  670): Tombstone written to: /data/tombstones/tombstone_05
I/sysmon-tsens_tz_sensor3(  710): sensor_work - read value = 340
E/installd(  679): eof
E/installd(  679): failed to read size
I/installd(  679): closing connection
I/lowmemorykiller(  655): ActivityManager disconnected
I/lowmemorykiller(  655): Closing Activity Manager data connection
I/ServiceManager(  656): service 'entropy' died
I/ServiceManager(  656): service 'commontime_management' died
I/ServiceManager(  656): service 'usb' died
…

I also had to grant location permission beforehand (cf #2), otherwise the whole system would become VERY unstable and eventually crash too.

Please note that this phone has a locked bootloader so I can't install an official, up-to-date LineageOS/CyanogenMod ROM, and had to rely on this : https://forum.xda-developers.com/xperia-sp/development/xperiasp-locked-bootloader-lbl-t2947194 so it's quite flaky overall.

Don't move mobile emitters

Non-blacklisted mobile emitters are moved if the bounding box is very large, see

// Bounding box has increased, see if it is now unbelievably large
if (coverage.getRadius() >= ourCharacteristics.moveDetectDistance) {
Log.d(TAG, "updateLocation("+id+") emitter has moved (" + gpsLoc.distanceTo(_getLocation()) + ")");
coverage = new BoundingBox(gpsLoc.getLatitude(), gpsLoc.getLongitude(), 0.0f);
trust = ourCharacteristics.discoveryTrust;
changeStatus(EmitterStatus.STATUS_CHANGED, "updateLocation('"+logString()+"') Moved");

but in some (I suspect many) cases the emitter keeps moving, and thus we keep moving the emitter position in our database.

Example:
We're in a train with a non-blacklisted WiFi (maybe blacklist is outdated, or maybe the WiFi doesn't broadcast SSID).
Once the WiFi is added to DejaVu DB, our location will be reported wherever we added the WiFi. If we have enough GPS accuracy and are more than moveDetectDistance (300 m) away, the WiFi will be moved to our current position, and bad location reports will continue, but with a different location.

Proposed solution:
Don't move the emitter, instead don't use emitters with radius > moveDetectDistance for location reports. Ideally there would be some EmitterStatus.STATUS_IGNORED, which is set when radius is too large, and acts similar to blacklisted, but without removing the emitter from DB. The new status would avoid useless emitter updates in DB

Further example:
Same as above, but our GPS accuracy is not enough to move the emitter (e.g. we detected the emitter at the train station, but inside the train GPS accuracy is too bad)
Now the emitter will continue being used for location reports even though we have a contradicting GPS location.

Proposed solution:
Loosen the requirements in

if ((gpsLoc == null) || (gpsLoc.getAccuracy() > ourCharacteristics.reqdGpsAccuracy)) {

e.g. to gpsLoc.getAccuracy() > ourCharacteristics.reqdGpsAccuracy || gpsLoc.distanceTo(<center of emitter>) > moveDetectDistance + gpsLoc.getAccuracy() + <some padding to be sure>.
Then the bouding box will be increased to an "unbeliavable" size and the emitter will not be used in location reports (if upper solution is implemented)

(related to #33 )

Thank you!

Thank you!

Thank you for your project and software!

Thank you for maintenance in the past and in the future!

Kind regards and season's greetings!

Bouding box uses wrong conversion between degrees and meters

in

double locEast = lon + (radius_ew * BackendService.METER_TO_DEG) * cosLat;
double locWest = lon - (radius_ew * BackendService.METER_TO_DEG) * cosLat;

east-west size of the bounding box is set by converting meters to degrees and multiplying with cosLat. This results in narrower bouding boxes (in degrees) for high latitude.
But actually the bouding boxes with the same e-w width in metes should get wider if we go towards the poles.

Proposed solution:
change to (radius_ew * BackendService.METER_TO_DEG) / cosLat;
and change

radius_ew = (float)(((east - center_lon) * BackendService.DEG_TO_METER) / cosLat);
to ((east - center_lon) * BackendService.DEG_TO_METER) * cosLat

There is no donation link

I have no financial way to thank the project. Clearly, the absence of a paypal tip jar is a bug in the project documentation! (I have too many ongoing projects to contribute with code so I figured, you know, cash is always welcome.)

I found DejaVu in the F-Droid store and wanted to use it so badly that I switched roms and stopped using gapps. :) The least I can do is buy a beer.

Updated zh-rCN (Chinese (China)) translation

I have translated your application into zh-rCN (Chinese (China)).
Maybe this one's translation is not inportant, but here is the xml:

app/src/main/res/values/strings.xml
<resources>
    <string name="app_name">Déjà Vu 位置服务</string>
    <string name="summary">一个使用设备自带的 RF 射频信号发射器实现的 microG/UnifiedNlp 位置提供器</string>
</resources>

Translation made with Stringlate.

Runtime version check missing before TelephonyManager.getNeighboringCellInfo()

Hi, there, I've found a version check is missing in version 1.1.12, which is downloaded from F-Droid.

Issue Description

The API getNeighboringCellInfo is added in Android API-level 25, so if the app is running on a device less than 25, it will crash.

Currently this API is called in a try-catch here

final List<NeighboringCellInfo> neighbors = tm.getNeighboringCellInfo();

I think a better choice is to explicitly check it, rather than suppress the warning by try-catch.

For example,

if (Build.VERSION.SDK_INT >= 25)
    // call the API
else
    // something else

@n76 Could you help me view this? Very thx!

[feature request]: add sharing abilities

I like this project and immediately installed it to my phone, it already greatly improved location accuracy. IMHO, the "self-learning" approach is the highway to heaven. As well I like taking WiFi and GSM together, it no longer makes sense to have distinguished WiFi and GSM backends.
Therefore - thank you very much for your work.

But (sorry for the "but", but inavoidable):
Why should the achieved results not be shared amongst the users - in the case they want to? And why should every user build his own database from scratch? (Nobody will do anyway, but use several location backends at the same time, not knowing how they will interact, as I do now - now I have 3 backends, which may not be the optimal solution)

So - these are my thoughts on enhancements (certainly nothing new to you):

  • OPTION: provide a "to-begin-with" database, containing results from the openwlanmap.org project or some other open location project. Database size could be limited by just downloading certain postcode areas, landline phone region codes (my favourite) or just countries.
  • OPTION: when phone is operating and GPS is active, check whether the given results can be improved in terms of accuracy -> if yes, mark these database entries and collect them for occasional transfer to the central server (when phone is connected to WiFi and AC power)
  • OPTION: occasionally check the differences between phone database and central database and find out whether the phone can achieve improved data
  • OPTION: offer an option to call GPS in regions with known-bad-coverage, with user-adjustable level of required minimum % of battery charge for that. (I'd be happy to do some GPS logging to improve the central database, but not if my phone is short of power...)

Sorry, this requires quite some controls and switches in the app. But as we're not iphone users, we should be able to handle them.

Chers,
Wolf

crashes WhatsApp (ArrayIndexOutOfBoundsException)

I'm using:

  • Device: FP3
  • OS: /e/ 0.11
  • microG 0.2.10.19420-77 (68c4e0d)
  • Déjà Vu 1.1.12
  • WhatsApp 2.20.202.15

WhatsApp crashes very often when I try to use the "share live location" feature. This feature is practically unusable as almost all of the attempts crash at some point.

"send current location" works fine. Only "share live location" has this problem.

If I switch to other UnifiedNlp backends (I tried MLS and Radiocells), then the crashes don't happen.

Edit: with Radiocells (org.openbmap.unifiedNlpProvider) the crashes don't happen, but the exact same ArrayIndexOutOfBoundsException is produced. The difference being that Radiocells is able to handle this gracefully and instead of crashing WhatsApp, the message attempt fails and WhatsApp UI displays a "Retry" button. See my reply below.

Edit2: I've seen the same ArrayIndexOutOfBoundsException happen with MLS too, albeit much less frequently. And WhatsApp doesn't crash either. In fact you can't notice it by watching the WhatsApp UI, only by monitoring logcat.

logcat dump:

--------- beginning of crash
10-26 22:08:10.595 3122 3122 E AndroidRuntime: FATAL EXCEPTION: main
10-26 22:08:10.595 3122 3122 E AndroidRuntime: Process: com.whatsapp, PID: 3122
10-26 22:08:10.595 3122 3122 E AndroidRuntime: java.lang.ArrayIndexOutOfBoundsException: length=30; index=30
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at a.b.c.f.f.a(Unknown Source:9)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at org.microg.gms.maps.mapbox.GoogleMapImpl.clear(Unknown Source:16)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at org.microg.gms.maps.mapbox.GoogleMapImpl.clear(Unknown Source:25)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at com.google.android.gms.maps.internal.IGoogleMapDelegate$Stub.onTransact(Unknown Source:846)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at org.microg.gms.maps.mapbox.GoogleMapImpl.onTransact(Unknown Source:0)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at android.os.Binder.transact(Binder.java:667)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at X.1EX.A02(:263077)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at X.1sP.clear(:330635)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at X.2aA.A03(:407683)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at X.2aA.A0S(:408227)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at X.0Yb.onAnimationStart(:177870)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at android.view.animation.Animation$1.run(Animation.java:373)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:873)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at android.os.Looper.loop(Looper.java:193)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6718)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:491)
10-26 22:08:10.595 3122 3122 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
10-26 22:08:10.612 1211 2041 W ActivityManager: Force finishing activity com.whatsapp/.location.LocationPicker2
10-26 22:08:10.617 3122 3122 I Process : Sending signal. PID: 3122 SIG: 9
10-26 22:08:10.675 1211 1561 W InputDispatcher: channel 'c27227b com.whatsapp/com.whatsapp.location.LocationPicker2 (server)' ~ Consumer closed input channel or an error occurred. events=0x9
10-26 22:08:10.675 1211 1561 E InputDispatcher: channel 'c27227b com.whatsapp/com.whatsapp.location.LocationPicker2 (server)' ~ Channel is unrecoverably broken and will be disposed!
10-26 22:08:10.676 1211 1561 W InputDispatcher: channel 'f5f25e4 com.whatsapp/com.whatsapp.Conversation (server)' ~ Consumer closed input channel or an error occurred. events=0x9
10-26 22:08:10.676 1211 1561 E InputDispatcher: channel 'f5f25e4 com.whatsapp/com.whatsapp.Conversation (server)' ~ Channel is unrecoverably broken and will be disposed!

No known location in UnifiedNlp

There is "no last known location" in UnifiedNlp despite all boxes checked in self-check and Deja Vu enabled.

"Use location" and "Wi-Fi scanning" are both checked/enabled in Android settings.

Android Version: 9
Custom ROM: LineageOS 16

Bluetooth beacons

From the README

However based on warnings about high resource use when scanning for Bluetooth and the high probability that a Bluetooth device will be mobile that has not been implemented.

Bluetooth beacons are more likely to be stationary, and useful for positioning.

If the concern re scanning is power usage, then make scanning conditional:

  • when externally powered (mains charger or external battery)
  • when the position hasn't changed much (<50 metres in 30 minutes?) perform a background scan — this should more likely capture places the user cares about, be inside buildings, and avoid scanning while travelling
  • use BT's low-energy mode & background scanning

How to open database

Hi 👋🏻

I'd like to take a look into the database to see which data I've already collected.

Where is the DB located on my device and how can I open it? Maybe it's even worth adding these information to README.md?

Best regards and thanks

French translation

Here is a small contribution. Thanks for your work.

<resources>
<string name="app_name">Déjà Vu - Service de géolocalisation</string>
<string name="summary">Un service de géolocalisation pour microG/Unified Network Location Provider utilisant une base de données privée stockée sur le téléphone de l\'utilisateur</string>
</resources>

[SOLVED] Freeze on Android 6.0.1

Hi !

When I install Déjà Vu Location Service 1.0.2 from F-Droid on my LG G4/H815 running LineageOS 13/Android 6.0.1, my phone freezes as soon as I activate the backend in MicroG UnifiedNlp settings. After about two minutes, the phone will reboot and freeze again as soon as it has finished booting. Same if I reboot it beforehand.

I need to reboot to recovery (e.g. with adb reboot recovery) and delete /data/app/org.fitchfamily.android.dejavu for my phone to stop freezing.

Checking for expected emitters has bad performance

At the end of each reporting period, a check for missing emitters is done:

// If we are dealing with very movable emitters, then try to detect ones that
// have moved out of the area. We do that by collecting the set of emitters
// that we expected to see in this area based on the GPS and our own location
// computation.
Set<RfIdentification> expectedSet = new HashSet<>();
if (weightedAverageLocation != null) {
emitterCache.sync(); // getExpected() ends bypassing the cache, so sync first
for (RfEmitter.EmitterType etype : RfEmitter.EmitterType.values()) {
expectedSet.addAll(getExpected(weightedAverageLocation, etype));
}
if (gpsLocation != null) {
for (RfEmitter.EmitterType etype : RfEmitter.EmitterType.values()) {
expectedSet.addAll(getExpected(gpsLocation.getLocation(), etype));
}
}
}

This makes sense, but is rather slow and not strictly necessary (mostly to clean old data from DB).
Performance of this check with a large database is actually so bad that DejaVu may end up as most battery consuming app (according to battery usage in Android settings).

Proposed improvements:

  • getExpected() queries emitters from DB by latitude, longitude and type, so we should add an index on latitude, longitude and type to the database.
  • we get all types of emitters from DB, with the purpose of decreasing trust of the ones we expect, but could not find. But EmitterType.MOBILE has decrTrust 0, so trust cannot be decreased. There is no point in fetching MOBILE emitters from DB.
  • emitterCache.sync(); is not necessary: the only emitters that are not in DB (or are not updated) are emitters we have in seenSet, and the only purpose of the expected check is decreasing trust of expected emitters that are not in the seenSet.
  • (+some more potential improvements that require more changes)

Add export/import ability

I would at least like to be able to look at the data in the database. For export, the simplest thing seems to be just copying the database file (assuming it is sqlite) to the (real or emulated) SD card.

For import, this could be more work than is justified, but just iterating over a database in the above format and adding info for emitters not already known would help a lot with syncing between multiple personal devices.

Ignore invalid LAC

I noticed some bad GSM-based location reports with LAC (location area code) 0.
However, at least for GSM cells (maybe others as well), a valid LAC can't be 0, see

Location Area Code (LAC) which is a fixed length code (of 2 octets) identifying a location area within a GSM PLMN. This part of the location area identification can be coded using a full hexadecimal representation except for the following reserved hexadecimal values:
0000, and
FFFE.

from https://www.etsi.org/deliver/etsi_ts/123000_123099/123003/03.07.00_60/ts_123003v030700p.pdf

Proposed solution:
Treat LAC 0 as invalid.

(related to #33)

Turn on GPS when new emitter seen and location unknown

I have a suggestion. Deja Vu could currently monitor for emitters appearing constantly with very low power usage. Then, if Deja Vu sees an emitter it hasn't seen before, it should try and get the most accurate location with low power usage. The logic would be as follows:

  1. A GPS location is already obtained for some other app, we already have an accurate location, use it. (current behaviour)
  2. We can get a network location from Deja Vu or another provider. Use that. Less accurate, but low power.
  3. If the above fails, request a lock on GPS for long enough to get a location, record the details, and release the lock.

This would allow it to minimise GPS usage while updating the database more regularly.

At the moment I find myself forcing a GPS lock for long periods when on longer trips to gather data, which smashes my battery life.

I'd be happy to implement this if you're interested.

5GHz WLAN

subj not collected by this backend: database lacks any wifi records other than "WLAN_24GHZ". also there is no traces from known 5GHz access points (no ssid nor bssid)

Not fetching location

Not sure what am I doing wrong here but it appears that both DejaVu and GSM backend fail to work on my device. In case of DejaVu, I looked inside the database and it is correctly populated with both cellular and WiFi entries from the places I've been to. On the other hand, I am pretty sure that I have downloaded the Mozilla database correctly with the MCC codes for my country. In both cases however, I just never get a location while using OsmAnd or any other app. I do know MicroG is setup correctly because it takes less than 5 seconds to fetch location using the Mozilla (Ichnaea) backend. I also tested with SatStat and it shows exactly the same info as one of the entries in the DejaVu database, so I have no idea where is it going wrong. Thoughts?

Update WiFi blacklist

Could you add "CDWiFi", "Regiojet - zluty"/"RegioJet - zluty" (Czech transport companies), "WESTlan" (Austrian Westbahn) and "Wifi in de trein" (Dutch NS) to the wifi blacklist?

And maybe the "OEBB" entry could be changed to only blacklist "OEBB" and not the stationary "OEBB-station" networks.

Blacklist compares mixed case with lower case

final String lc = note.toLowerCase(Locale.US);

and
lc.contentEquals("CDWiFi") || // WLAN network on Czech railways

results in "CDWiFi" being compared to "cdwifi" when the entry should match, so this entry is useless (applies to others as well).

Proposed solution:
only use lowercase when comparing with lc.

Updated de (German) translation

I have translated your application into de (German). Here is the xml:

<resources>
    <string name="app_name">Standort Dienst mit Gedächtnis</string>
    <string name="summary">Ein microG/UnifiedNlp Standortdienst der eine private Datenbank der Mobilfunkstationen benutzt</string>
</resources>

Database files permissions

Hi, I have DejaVu installed in a Fairphone 2 with their latest Open FP OS, microG and Xposed. The backend worked initially but it tended to crash frequently. It crashed every time I deactivated and reactivated DejaVu in the microG framework app, and sometimes when there was database recording activity. I solved the problem by assigning full file system permissions (-rwxrwxrwx) to the two database files in /data/data/.

Only 2.4 GHz WLAN recorded in the db

OP3T running Android 11 (LineageOS). Only 2.4 GHz gets recorded in the database. On previous versions of LineageOS (although I can't pinpoint which was the last - could be 10 - mobile cells were recorded as well).

Lack of 5GHz WLAN possibly related to #31

Logo/Icon proposal

Greetings, Im a graphics designer here on Github and I would like to ask for your permission to design for your logo/icon that you maybe used for your future plans in your project. I want to help open source projects by designing logos or banners for there project. Thank you for your time reading this

Best regards
-jbeguna04

problem with GSM towers

rooted stock Android 7, sony F5121, app version 1.0.2 from f-droid

After some test run (about 50 km) i found that GSM location doesnt work properly. In application database i found only one row related to GSM with strange 'rfID' = 'GSM/2147483647/2147483647/2147483647/2147483647' and absurdly large raduis 18190.615234375.
If it can help there is (minimum) 4 cells with this cell id (2147483647) in my area: 25099_15401_2147483647, 25099_15402_2147483647, 25099_41130_2147483647 and 25099_41129_2147483647.

NullPointerException - Android 7.1.2

02-25 02:25:35.118 E/AndroidRuntime(9342): FATAL EXCEPTION: Thread-133
02-25 02:25:35.118 E/AndroidRuntime(9342): Process: org.fitchfamily.android.dejavu, PID: 9342
02-25 02:25:35.118 E/AndroidRuntime(9342): java.lang.NullPointerException: Attempt to invoke virtual method 'org.fitchfamily.android.dejavu.RfEmitter org.fitchfamily.android.dejavu.Database.getEmitter(org.fitchfamily.android.dejavu.RfIdentification)' on a null object reference
02-25 02:25:35.118 E/AndroidRuntime(9342): at org.fitchfamily.android.dejavu.Cache.get(Cache.java:106)
02-25 02:25:35.118 E/AndroidRuntime(9342): at org.fitchfamily.android.dejavu.BackendService.getRfLocations(BackendService.java:759)
02-25 02:25:35.118 E/AndroidRuntime(9342): at org.fitchfamily.android.dejavu.BackendService.endOfPeriodProcessing(BackendService.java:912)
02-25 02:25:35.118 E/AndroidRuntime(9342): at org.fitchfamily.android.dejavu.BackendService.backgroundProcessing(BackendService.java:727)
02-25 02:25:35.118 E/AndroidRuntime(9342): at org.fitchfamily.android.dejavu.BackendService.access$300(BackendService.java:71)
02-25 02:25:35.118 E/AndroidRuntime(9342): at org.fitchfamily.android.dejavu.BackendService$4.run(BackendService.java:668)
02-25 02:25:35.118 E/AndroidRuntime(9342): at java.lang.Thread.run(Thread.java:761)

Wrong locations reported

I have the issue that DejaVu sometimes reports clearly wrong locations. There seem to be at least 2 different cases how this happens:

a) DejaVu reports a location far away, tens (in one case even hundreds) of km away from actual position. Every time it is the location of a GSM tower with the ID ending in /0/0 (in DejaVu database).
Are these entries even valid? http://www.cell2gps.com/ can't find any of those towers, same thing for the ones just ending in /0.

b) DejaVu reports a location a few km away, sometimes (rarely) even repeatedly over the course of several minutes and km while moving.
When looking in the database, I always find (one or more) WiFi entries near that location, and often the SSID indicates a stationary WiFi (e.g. a restaurant). Contrary to case a), there is nothing unusual in the entries. Trust is always at or close to 100.
It is impossible that my phone really sees the WiFi due to distance and houses in between, but apparently it still reports those WiFis. I am not sure whether this a problem of my phone or some bug in DejaVu...

Device:
S4 Mini Duos
AOKP (LineageOS 14.1 based)
MicroG 0.2.8.17785-mapbox
DejaVu 1.1.12 (no other location backends)

Repeated crashes with some apps

DejaVu repeatedly crashes with a few apps that use location (but not all apps that use location). Here are segments of the event log:

03-05 00:48:33.596 I/am_crash( 2207): [5205,0,org.fitchfamily.android.dejavu,952680004,java.lang.NullPointerException,Attempt to invoke virtual method 'org.fitchfamily.android.dejavu.RfEmitter org.fitchfamily.android.dejavu.Database.getEmitter(org.fitchfamily.android.dejavu.RfIdentification)' on a null object reference,Cache.java,106]

03-05 01:20:37.514 I/am_crash( 2207): [10908,0,org.fitchfamily.android.dejavu,952680004,java.lang.NullPointerException,Attempt to invoke virtual method 'org.fitchfamily.android.dejavu.RfEmitter org.fitchfamily.android.dejavu.Database.getEmitter(org.fitchfamily.android.dejavu.RfIdentification)' on a null object reference,Cache.java,106]
03-05 01:20:39.576 I/am_proc_died( 2207): [0,10908,org.fitchfamily.android.dejavu]
03-05 01:20:39.688 I/sf_frame_dur( 288): [Application Error: org.fitchfamily.android.dejavu,11,1,0,1,0,2,0]
03-05 01:20:42.199 I/am_proc_start( 2207): [0,22144,10167,org.fitchfamily.android.dejavu,service,org.fitchfamily.android.dejavu/.BackendService]
03-05 01:20:42.336 I/am_proc_bound( 2207): [0,22144,org.fitchfamily.android.dejavu]

Add ability to not record emitters in another database

I certainly agree with the points of this program, both having data where e.g. radiocells does not, and the privacy issue. But, it would be great to be able to have the data avoid lots of overlap with a backend that uses a downloaded database, to avoid recording things that are a) known and b) not incrementally useful given the values in the other database.

The idea would be to have a side channel to query the other provider, and if recording the emitter is not useful given that it's in the other db, skip it.

Obviously this needs to be configurable and default to off.

It could be that the savings in the database is small, but my LocalWifi backend now has 300K wifis in it, and I suspect a fair number of those are in radiocells.

[Request] Add "Active Mode" to build initial database

Current functionality:

DejaVu requires another app to request GPS location in order for database to begin being built (eg: Maps.me)

Desired functionality:

A toggle is made in DejaVu to actively build a database by requesting GPS on its own. Ideally this would be ran by the user for the first while in a new location to build new database entries.

I'm sure this would be a drain on battery however its implemented. Is this possible, or is this beyond the scope of this project? Thank you very much for this backend!

Future development

@Lee-Carre @gdt @n76
In #41 was the question about someone willing to take over the project...
I'm definitely willing to help, but I don't have any experience with actually maintaining an app, or making it available in F-Droid. Maybe @gdt would be would be more suitable?

As mentioned, I've been working on some improvements:

What is changed

  • blacklist improvements
  • database adjustments for faster query of nearby (expected) emitters
  • performance improvements of database access from cache
  • no moving of emitter if radius grows too large (instead it's not used in location reports)
    • this reduces wrong location reports by a lot
  • allow emitter radius to grow too large even if we have insufficient accuracy for this emitter type
    • helps against some remaining cases of wrong location reports
  • ignore mobile cells with LAC 0 (again, bad / wrong location reports)
  • don't scan if not possible (due to airplane mode or WiFi settings)
    • maybe not necessary
  • don't expect nearby WiFi emitters if WiFi scanning is not allowed
  • (partially) migrate to kotlin, simply because I'm much more familiar with kotlin than with java

What is missing, but should be done

  • unit tests (would have saved me from a few bugs I introduced)
  • API upgrade
    • 5G and TD-SCDMA need API 29
    • 6 GHZ WiFi check needs API 30
    • TelephonyManager.getNeighboringCellInfo was removed in API 29, but is needed on some older phones where getAllCellInfo does not work properly.
      • any workaroud for accessing getNeighboringCellInfo on old phones when building for API 29+?
  • Detection / use of Bluetooth emitters
  • RfCharacteristics for newly introduced/split emitter types (6 GHz WiFi, 5G, LTE, 3G variants, Bluetooth)
  • deal with WiFi scan throttling
  • and maybe a simple UI for things like import/export, actively requesting GPS locations, getting debug logs, allow overriding some detections (e.g. wifiManager erroneously reports my phone isn't capable of 5 GHz WiFi)
    Any comments / additions regarding changes and to-dos?

Update

Can you please update org.microg:unifiednlp-api to 1.5.6 and targetSdkVersion to 27?

Like this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.