Recent

Author Topic: LAMW (solved) how to prevent location mocking / fake gps on LAMW  (Read 8324 times)

Mongkey

  • Sr. Member
  • ****
  • Posts: 430
This is java article i've got, i knew it depreciated on API >25, but it very interesting.

https://www.programcreek.com/java-api-examples/?class=android.telephony.TelephonyManager&method=getAllCellInfo

Since i am very beginner on java, i cant implement it, because the return value like tstring.
« Last Edit: August 21, 2021, 08:38:46 am by Mongkey »

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
« Reply #1 on: August 19, 2021, 04:00:59 pm »
I think this is a Pascal problem. Any Java object is simply translated as a pointer:
Code: Pascal  [Select][+][-]
  1. unit And_jni;
  2. ...
  3. type
  4. ....
  5.      jobject=pointer;

including jList.

While, up to this point, it might be eaiser to solve problems on the Java side, I believe the proper way is to move the problem to the Pascal side.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
« Reply #2 on: August 19, 2021, 04:05:44 pm »
For instance android.telephony.TelephonyManager is something like:
Code: Pascal  [Select][+][-]
  1. unit uATTelephonyManager;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, And_jni, AndroidWidget,
  9.   Laz_And_Controls, uAndroidCommon;
  10.  
  11. type
  12.  
  13.   { jTelephonyManager }
  14.  
  15.   jTelephonyManager=class(jCommon)
  16.   protected
  17.     const CClassPath:string='android/telephony/TelephonyManager';
  18.   protected
  19.     {Shared by *all* jTelephonyManager instances}
  20.     FjClass:jObject;static;
  21.     FInitialized:boolean;static;
  22.     //MethodId fields
  23.     jMethodId_getPhoneCount:jmethodID;static;
  24.     jMethodId_createForSubscriptionId:jmethodID;static;
  25.     jMethodId_getDeviceSoftwareVersion:jmethodID;static;
  26.     jMethodId_getDeviceId1:jmethodID;static;
  27.     jMethodId_getDeviceId2:jmethodID;static;
  28.     jMethodId_getCellLocation:jmethodID;static;
  29.     jMethodId_getNeighboringCellInfo:jmethodID;static;
  30.     jMethodId_getPhoneType:jmethodID;static;
  31.     jMethodId_getNetworkOperatorName:jmethodID;static;
  32.     jMethodId_getNetworkOperator:jmethodID;static;
  33.     jMethodId_isNetworkRoaming:jmethodID;static;
  34.     jMethodId_getNetworkCountryIso:jmethodID;static;
  35.     jMethodId_getNetworkType:jmethodID;static;
  36.     jMethodId_getDataNetworkType:jmethodID;static;
  37.     jMethodId_getVoiceNetworkType:jmethodID;static;
  38.     jMethodId_hasIccCard:jmethodID;static;
  39.     jMethodId_getSimState:jmethodID;static;
  40.     jMethodId_getSimOperator:jmethodID;static;
  41.     jMethodId_getSimOperatorName:jmethodID;static;
  42.     jMethodId_getSimCountryIso:jmethodID;static;
  43.     jMethodId_getSimSerialNumber:jmethodID;static;
  44.     jMethodId_getSubscriberId:jmethodID;static;
  45.     jMethodId_getGroupIdLevel1:jmethodID;static;
  46.     jMethodId_getLine1Number:jmethodID;static;
  47.     jMethodId_setLine1NumberForDisplay:jmethodID;static;
  48.     jMethodId_getVoiceMailNumber:jmethodID;static;
  49.     jMethodId_setVoiceMailNumber:jmethodID;static;
  50.     jMethodId_getVoiceMailAlphaTag:jmethodID;static;
  51.     jMethodId_getCallState:jmethodID;static;
  52.     jMethodId_getDataActivity:jmethodID;static;
  53.     jMethodId_getDataState:jmethodID;static;
  54.     jMethodId_listen:jmethodID;static;
  55.     jMethodId_isVoiceCapable:jmethodID;static;
  56.     jMethodId_isSmsCapable:jmethodID;static;
  57.     jMethodId_getAllCellInfo:jmethodID;static;
  58.     jMethodId_getMmsUserAgent:jmethodID;static;
  59.     jMethodId_getMmsUAProfUrl:jmethodID;static;
  60.     jMethodId_iccOpenLogicalChannel:jmethodID;static;
  61.     jMethodId_iccCloseLogicalChannel:jmethodID;static;
  62.     jMethodId_iccTransmitApduLogicalChannel:jmethodID;static;
  63.     jMethodId_iccTransmitApduBasicChannel:jmethodID;static;
  64.     jMethodId_iccExchangeSimIO:jmethodID;static;
  65.     jMethodId_sendEnvelopeWithStatus:jmethodID;static;
  66.     jMethodId_getIccAuthentication:jmethodID;static;
  67.     jMethodId_setPreferredNetworkTypeToGlobal:jmethodID;static;
  68.     jMethodId_hasCarrierPrivileges:jmethodID;static;
  69.     jMethodId_setOperatorBrandOverride:jmethodID;static;
  70.     jMethodId_canChangeDtmfToneLength:jmethodID;static;
  71.     jMethodId_isWorldPhone:jmethodID;static;
  72.     jMethodId_isTtyModeSupported:jmethodID;static;
  73.     jMethodId_isHearingAidCompatibilitySupported:jmethodID;static;
  74.     jMethodId_getVoicemailRingtoneUri:jmethodID;static;
  75.     jMethodId_isVoicemailVibrationEnabled:jmethodID;static;
  76.   protected
  77.     class function get_jClass:jobject;override;
  78.     class procedure get_jIDs;override;
  79.   public
  80.     constructor Create(AjObject:jObject=nil);overload;
  81.     class procedure Init;
  82.   public
  83.     //Procs
  84.     function getPhoneCount:jint;
  85.     function createForSubscriptionId(_subId:jint):jobject;
  86.     function getDeviceSoftwareVersion:String;
  87.     function getDeviceId:String;overload;
  88.     function getDeviceId(_slotId:jint):String;overload;
  89.     function getCellLocation:jobject;
  90.     function getNeighboringCellInfo:jobject;
  91.     function getPhoneType:jint;
  92.     function getNetworkOperatorName:String;
  93.     function getNetworkOperator:String;
  94.     function isNetworkRoaming:boolean;
  95.     function getNetworkCountryIso:String;
  96.     function getNetworkType:jint;
  97.     function getDataNetworkType:jint;
  98.     function getVoiceNetworkType:jint;
  99.     function hasIccCard:boolean;
  100.     function getSimState:jint;
  101.     function getSimOperator:String;
  102.     function getSimOperatorName:String;
  103.     function getSimCountryIso:String;
  104.     function getSimSerialNumber:String;
  105.     function getSubscriberId:String;
  106.     function getGroupIdLevel1:String;
  107.     function getLine1Number:String;
  108.     function setLine1NumberForDisplay(_alphaTag:String;_number:String):boolean;
  109.     function getVoiceMailNumber:String;
  110.     function setVoiceMailNumber(_alphaTag:String;_number:String):boolean;
  111.     function getVoiceMailAlphaTag:String;
  112.     function getCallState:jint;
  113.     function getDataActivity:jint;
  114.     function getDataState:jint;
  115.     procedure listen(_listener:jobject;_events:jint);
  116.     function isVoiceCapable:boolean;
  117.     function isSmsCapable:boolean;
  118.     function getAllCellInfo:jobject;
  119.     function getMmsUserAgent:String;
  120.     function getMmsUAProfUrl:String;
  121.     function iccOpenLogicalChannel(_AID:String):jobject;
  122.     function iccCloseLogicalChannel(_channel:jint):boolean;
  123.     function iccTransmitApduLogicalChannel(_channel:jint;_cla:jint;_instruction:jint;_p1:jint;_p2:jint;_p3:jint;_data:String):String;
  124.     function iccTransmitApduBasicChannel(_cla:jint;_instruction:jint;_p1:jint;_p2:jint;_p3:jint;_data:String):String;
  125.     function iccExchangeSimIO(_fileID:jint;_command:jint;_p1:jint;_p2:jint;_p3:jint;_filePath:String):jbyte;
  126.     function sendEnvelopeWithStatus(_content:String):String;
  127.     function getIccAuthentication(_appType:jint;_authType:jint;_data:String):String;
  128.     function setPreferredNetworkTypeToGlobal:boolean;
  129.     function hasCarrierPrivileges:boolean;
  130.     function setOperatorBrandOverride(_brand:String):boolean;
  131.     function canChangeDtmfToneLength:boolean;
  132.     function isWorldPhone:boolean;
  133.     function isTtyModeSupported:boolean;
  134.     function isHearingAidCompatibilitySupported:boolean;
  135.     function getVoicemailRingtoneUri(_accountHandle:jobject):jobject;
  136.     function isVoicemailVibrationEnabled(_accountHandle:jobject):boolean;
  137.   end;
  138.  
  139. implementation
  140.  
  141. { jTelephonyManager }
  142.  
  143. constructor jTelephonyManager.Create(AjObject:jObject);
  144. begin
  145.   inherited Create(AjObject);
  146. end;
  147.  
  148. ...
  149. //code was removed to please the forum post limit :(
  150.  

This code is machine generated. For now, it ignores exceptions which should be fixed.

You are interested in:
Code: Pascal  [Select][+][-]
  1.     function getAllCellInfo:jobject;

Notice how it returns jobject. Now we need another class for java.util.List:
Code: Pascal  [Select][+][-]
  1. unit uJUList;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, And_jni, AndroidWidget,
  9.   Laz_And_Controls, uAndroidCommon;
  10.  
  11. type
  12.  
  13.   { jList }
  14.  
  15.   jList=class(jCommon)
  16.   protected
  17.     const CClassPath:string='java/util/List';
  18.   protected
  19.     {Shared by *all* jList instances}
  20.     FjClass:jObject;static;
  21.     FInitialized:boolean;static;
  22.     //MethodId fields
  23.     jMethodId_size:jmethodID;static;
  24.     jMethodId_isEmpty:jmethodID;static;
  25.     jMethodId_contains:jmethodID;static;
  26.     jMethodId_toArray1:jmethodID;static;
  27.     jMethodId_toArray2:jmethodID;static;
  28.     jMethodId_remove:jmethodID;static;
  29.     jMethodId_addAll:jmethodID;static;
  30.     jMethodId_removeAll:jmethodID;static;
  31.     jMethodId_clear:jmethodID;static;
  32.     jMethodId_equals:jmethodID;static;
  33.     jMethodId_get:jmethodID;static;
  34.     jMethodId_add:jmethodID;static;
  35.     jMethodId_indexOf:jmethodID;static;
  36.     jMethodId_listIterator1:jmethodID;static;
  37.     jMethodId_listIterator2:jmethodID;static;
  38.   protected
  39.     class function get_jClass:jobject;override;
  40.     class procedure get_jIDs;override;
  41.   public
  42.     constructor Create(AjObject:jObject=nil);overload;
  43.     class procedure Init;
  44.   public
  45.     //Procs
  46.     function size:jint;
  47.     function isEmpty:boolean;
  48.     function contains(__Param1:jobject):boolean;
  49.     function toArray:jobject;overload;
  50.     function toArray(__Param2:jobject):jobject;overload;
  51.     function remove(__Param1:jobject):boolean;
  52.     function addAll(__Param1:jobject):boolean;
  53.     function removeAll(__Param1:jobject):boolean;
  54.     procedure clear;
  55.     function equals(__Param1:jobject):boolean;
  56.     function get(__Param1:jint):jobject;
  57.     procedure add(__Param1:jint;__Param2:jobject);
  58.     function indexOf(__Param1:jobject):jint;
  59.     function listIterator:jobject;overload;
  60.     function listIterator(__Param1:jint):jobject;overload;
  61.   end;
  62.  
  63. implementation
  64.  
  65. { jList }
  66.  
  67. constructor jList.Create(AjObject:jObject);
  68. begin
  69.   inherited Create(AjObject);
  70. end;
  71. ...
  72. //code is cut to please the forum editor
  73.  

Just like the previous code, this was machine generated.

In theory, you take the jobject from getAllCellInfo and pass it to jList.Create

jList should give you access to its items which are of type CellInfo, so we need a third class:
Code: Pascal  [Select][+][-]
  1. unit uATCellInfo;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, And_jni, AndroidWidget,
  9.   Laz_And_Controls, uAndroidCommon;
  10.  
  11. type
  12.  
  13.   { jCellInfo }
  14.  
  15.   jCellInfo=class(jCommon)
  16.   protected
  17.     const CClassPath:string='android/telephony/CellInfo';
  18.   protected
  19.     {Shared by *all* jCellInfo instances}
  20.     FjClass:jObject;static;
  21.     FInitialized:boolean;static;
  22.     //MethodId fields
  23.     jMethodId_isRegistered:jmethodID;static;
  24.     jMethodId_getTimeStamp:jmethodID;static;
  25.     jMethodId_hashCode:jmethodID;static;
  26.     jMethodId_equals:jmethodID;static;
  27.     jMethodId_toString:jmethodID;static;
  28.     jMethodId_describeContents:jmethodID;static;
  29.     jMethodId_writeToParcel:jmethodID;static;
  30.   protected
  31.     class function get_jClass:jobject;override;
  32.     class procedure get_jIDs;override;
  33.   public
  34.     constructor Create(AjObject:jObject=nil);overload;
  35.     class procedure Init;
  36.   public
  37.     //Procs
  38.     function isRegistered:boolean;
  39.     function getTimeStamp:jlong;
  40.     function hashCode:jint;
  41.     function equals(_other:jobject):boolean;
  42.     function toString:String;
  43.     function describeContents:jint;
  44.     procedure writeToParcel(__Param1:jobject;__Param2:jint);
  45.   end;
  46.  
  47. implementation
  48.  
  49. { jCellInfo }
  50.  
  51. constructor jCellInfo.Create(AjObject:jObject);
  52. begin
  53.   inherited Create(AjObject);
  54. end;
  55.  
  56. class procedure jCellInfo.Init;
  57. var
  58.   LjClass:jobject;
  59. begin
  60.   if not FInitialized then
  61.   begin
  62.     LjClass:=Get_jClassLocalRef(CClassPath);
  63.     FjClass:=Get_jObjGlobalRef(LjClass);
  64.     Delete_jLocalRef(LjClass);
  65.     get_jIDs;
  66.     FInitialized:=True;
  67.   end;
  68. end;
  69.  
  70. class function jCellInfo.get_jClass:jobject;
  71. begin
  72.   Result:=FjClass;
  73. end;
  74.  
  75. class procedure jCellInfo.get_jIDs;
  76. begin
  77.   jMethodId_isRegistered:=Get_jMethodID(FjClass,'isRegistered','()Z');
  78.   jMethodId_getTimeStamp:=Get_jMethodID(FjClass,'getTimeStamp','()J');
  79.   jMethodId_hashCode:=Get_jMethodID(FjClass,'hashCode','()I');
  80.   jMethodId_equals:=Get_jMethodID(FjClass,'equals','(Ljava/lang/Object;)Z');
  81.   jMethodId_toString:=Get_jMethodID(FjClass,'toString','()Ljava/lang/String;');
  82.   jMethodId_describeContents:=Get_jMethodID(FjClass,'describeContents','()I');
  83.   jMethodId_writeToParcel:=Get_jMethodID(FjClass,'writeToParcel','(Landroid/os/Parcel;I)V');
  84. end;
  85.  
  86. function jCellInfo.isRegistered:boolean;
  87. begin
  88. // ()Z
  89.   Result:=jmethod_get_boolean(jMethodID_isRegistered);
  90. end;
  91.  
  92. function jCellInfo.getTimeStamp:jlong;
  93. begin
  94. // ()J
  95.   Result:=jmethod_get_jlong(jMethodID_getTimeStamp);
  96. end;
  97.  
  98. function jCellInfo.hashCode:jint;
  99. begin
  100. // ()I
  101.   Result:=jmethod_get_jint(jMethodID_hashCode);
  102. end;
  103.  
  104. function jCellInfo.equals(_other:jobject):boolean;
  105. var
  106.   jParams:array[0..0] of jvalue absolute _other;
  107. begin
  108. // (Ljava/lang/Object;)Z
  109.   Result:=jmethod_get_booleanA(jMethodId_equals,jParams);
  110. end;
  111.  
  112. function jCellInfo.toString:String;
  113. begin
  114. // ()Ljava/lang/String;
  115.   Result:=jmethod_get_String(jMethodID_toString);
  116. end;
  117.  
  118. function jCellInfo.describeContents:jint;
  119. begin
  120. // ()I
  121.   Result:=jmethod_get_jint(jMethodID_describeContents);
  122. end;
  123.  
  124. procedure jCellInfo.writeToParcel(__Param1:jobject;__Param2:jint);
  125. var
  126.   jParams:array[0..1] of jvalue;
  127. begin
  128. // (Landroid/os/Parcel;I)V
  129.   jParams[0].l:=__Param1;
  130.   jParams[1].i:=__Param2;
  131.   jmethod_voidA(jMethodId_writeToParcel,jParams);
  132. end;
  133.  
  134. end.
  135.  

It might be possible to use Pascal generics to make jList more like its counterpart in Java.

Anyway, I could be wrong, but this is how I see it.

WARNING:
This code was not tested.
« Last Edit: August 19, 2021, 04:18:25 pm by engkin »

Mongkey

  • Sr. Member
  • ****
  • Posts: 430
Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
« Reply #3 on: August 20, 2021, 12:05:23 am »
 Thank you bro! I'll do my best to follow your sample.

Mongkey

  • Sr. Member
  • ****
  • Posts: 430
Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
« Reply #4 on: August 20, 2021, 01:34:57 am »
i tried a lot, too much errors, not find symbol ,i dont understand java, its difficult for me  %),

I wish this attached code functions intact to LAMW jTelephony component, or new component jGeoFencing  :D

I got many fake gps coordinates, may be by retrieving from cell LAC, MNC solving this problem.

New candidate -> geofencing sample.

Thank you anyway!
« Last Edit: August 20, 2021, 05:43:27 am by Mongkey »

jmpessoa

  • Hero Member
  • *****
  • Posts: 2302
Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
« Reply #5 on: August 20, 2021, 06:51:20 am »
Done!

improved jTelephonyManager component

[need tests  and maybe some fix....]

[need "android.permission.ACCESS_COARSE_LOCATION"  granted by the user! ]

 GetLocationAreaCode()
 GetBaseStationId()
 GetMobileNetworkCode()
GetMobileCountryCode()

Thanks you!

PS. files changed:

"jTelephonyManager.java"
"telephonymanager.pas"
« Last Edit: August 20, 2021, 06:58:55 am by jmpessoa »
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

Mongkey

  • Sr. Member
  • ****
  • Posts: 430
Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
« Reply #6 on: August 20, 2021, 07:36:59 am »
 :),

thanks prof JM, you are the best!

Actually i get more 1 solution for this:
for API > 18

Code: Java  [Select][+][-]
  1. public static boolean isMockLocationOn(Context context) {
  2.     if (Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"))
  3.         return false;
  4.     else
  5.         return true;
  6. }
« Last Edit: August 20, 2021, 07:39:50 am by Mongkey »

Mongkey

  • Sr. Member
  • ****
  • Posts: 430
Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
« Reply #7 on: August 20, 2021, 08:29:52 am »
Working very well on android 10, just tested get cell location, is it compatible for dual sim android? I gonna test it soon!
« Last Edit: August 20, 2021, 08:35:30 am by Mongkey »

Mongkey

  • Sr. Member
  • ****
  • Posts: 430
Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
« Reply #8 on: August 21, 2021, 07:41:18 am »
GetLocationAreaCode()
GetBaseStationId()
GetMobileNetworkCode()
GetMobileCountryCode()

After trying all, all retrieve same value :( (dual sim, sim1-> but with expiring telco subscription , no card on sim2), yesterday just tried GetLocationAreaCode(), not yet trying 3 others.

After inspecting -> working ok for dual sim -> detect on sim2 only, no card on sim1 -> WORK  :D

may be, retrieving same value if the card has expired -> useful for detecting no longer in service telco simcard  :)
« Last Edit: August 21, 2021, 09:34:49 am by Mongkey »

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
« Reply #9 on: August 22, 2021, 06:10:39 pm »
This took me longer than I like. I kept having stange exception with an "invalid object". I tracked it down to a call in my code:
Code: Pascal  [Select][+][-]
  1.   javContext:=gApp.GetContext();//<---- fails

which is:
Code: Pascal  [Select][+][-]
  1. function jApp.GetContext(): jObject;
  2. begin
  3.   Result:= jApp_GetContext(Self.Jni.jEnv, Self.Jni.jThis);//<--- this fails!!
  4. end;

I assumed Self.Jni.jThis is not holding a valid value anymore, so I turned it into a Java global variable reference:
Code: Pascal  [Select][+][-]
  1. var
  2.   gThis:jobject;
  3.   gContext:jobject;
  4.  
  5. procedure Java_Event_pAppOnCreate(env: PJNIEnv; this: jobject; context:jobject; layout:jobject; intent: jobject);
  6. begin
  7.   gThis:=env^.NewGlobalRef(env,this);
  8.   gContext:=env^.NewGlobalRef(env,context);
  9.  
  10.   gApp.IsAppActivityRecreate := gApp.FInitialized;
  11.   gApp.FInitialized := False;
  12.   //gApp.Init(env,this,context,layout, intent);
  13.   gApp.Init(env,gThis,gContext,layout, intent);
  14. end;

Surprisingly that was not enough!!
then I skipped Self.Jni.jThis and used the global variable gThis directly:

Code: Pascal  [Select][+][-]
  1. function jApp.GetContext(): jObject;
  2. begin
  3.   Result:= jApp_GetContext(Self.Jni.jEnv, gThis);
  4. end;

Now it works:
Quote
<Init>
</Init>
<Context>
gApp.APILevel: 30
prob: 7
</Context>
<Activity>
</Activity>
pasContext.TELEPHONY_SERVICE:
phone
<TelephonyManager>
<getAllCellInfo>
<List>
pasList.size: 4
<Loop>
get(0)
CellInfo
CellInfoLte:{mRegistered=YES ....
get(1)
CellInfo
CellInfoLte:{mRegistered=NO ...
get(2)
CellInfo
CellInfoLte:{mRegistered=NO ...
get(3)
CellInfo
CellInfoLte:{mRegistered=NO ...
</Loop>

jmpessoa

  • Hero Member
  • *****
  • Posts: 2302
Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
« Reply #10 on: August 22, 2021, 10:29:20 pm »
Quote
function jApp.GetContext(): jObject;
begin
  Result:= jApp_GetContext(Self.Jni.jEnv, Self.Jni.jThis);//<--- this fails!!
end;


You can see in "Laz_And_Controls_Events.pas"  and "Laz_And_Controls.pas"

that all  "Java_Event_*"  call has some code like this:

Code: [Select]
Procedure Java_Event_pOnTimePicker(env: PJNIEnv; this: jobject; Obj: TObject; hourOfDay: integer; minute: integer);
begin

  gApp.Jni.jEnv := env;          // <----
  if this <> nil then gApp.Jni.jThis := this;      // <----

  ......
  .......
end; 

It keeps these global data always "up to date"!

the reference is here:

https://android-developers.googleblog.com/2011/11/jni-local-reference-changes-in-ics.html


Are you "by passing" LAMW code architecture?
« Last Edit: August 22, 2021, 10:34:23 pm by jmpessoa »
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
« Reply #11 on: August 22, 2021, 11:40:30 pm »
No, I am not bypassing LAMW's architecture. I am trying to extend it by bringing Java/Android classes to Pascal.

As your reference link shows, Java_Event_pAppOnCreate is expected to use env->NewGlobalRef to store its parameters on the Pascal side, otherwise these values become invalid because of the Garbage Collector moving them around. How come you're not following that reference?  :-\

I made a simple app with a jButton and jEditText. The button calls javContext:=gApp.GetContext();

That call fails because gApp.Jni.jThis became invalid.
Then I used NewGlobalRef as soon as I received the parameters in Java_Event_pAppOnCreate
Passing the results to jApp.Init *seemed* not to work,
but NOW, thanks to your explanation, I think they got overwritten by LOCAL references again.

That explains why it worked when I used gThis directly,  because it holds the GLOBAL reference.

If my understanding is correct, there is a bug in LAMW, it should set the members of jApp.Jni once, AND it should use NewGlobalRef for that, AND it should not change them inside Java_Event_* in unit "Laz_And_Controls_Events.pas"  or any other place.

Of course, at the end of the app it should delete the global references.
« Last Edit: August 22, 2021, 11:47:26 pm by engkin »

jmpessoa

  • Hero Member
  • *****
  • Posts: 2302
Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
« Reply #12 on: August 23, 2021, 12:29:13 am »
So at the moment we are doing different readings of the document.....

this code:

Code: Pascal  [Select][+][-]
  1. Procedure Java_Event_pOnTimePicker(env: PJNIEnv; this: jobject; Obj: TObject; hourOfDay: integer; minute: integer);
  2. begin
  3.  
  4.   gApp.Jni.jEnv := env;          // <----
  5.   if this <> nil then gApp.Jni.jThis := this;      // <----
  6.  
  7.   ......
  8.   .......
  9. end;
  10.  

is vital for the entire LAMW code architecture ... and yes "gApp" is global, but  properties
gApp.Jni.jEnv and  gApp.Jni.jThis  need to be continually updated
otherwise we will get "staled"  object reference....
« Last Edit: August 23, 2021, 03:30:30 am by jmpessoa »
Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
« Reply #13 on: August 23, 2021, 01:44:47 am »
When I said global, I was not talking about Pascal global variables.  I meant Jave global references. These references do not stall, the Garbage Collector doesn't touch them.

What you receive in Java_Event_* is Java local references, these local references will stall. If you intend to use them outside these procedures, as in LAMW, you're supposed to turn the Java local references to Java global references.

This is what the article you linked is saying, and it is what works on my side.

If you are not convinced, can you show me one simple example where my suggestion will not work?

jmpessoa

  • Hero Member
  • *****
  • Posts: 2302
Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
« Reply #14 on: August 23, 2021, 04:16:09 am »

Quote
can you show me one simple example where my suggestion .....

From reference:

Quote
Now there’s a per-thread local reference table, it’s vital that you only use a JNIEnv* on the right thread.

Quote
If you have a native peer (a long-lived native object corresponding to a Java object, usually created when the Java object is created and destroyed when the Java object’s finalizer runs), you must not stash a jobject in that native object, because it won’t be valid next time you try to use it. (Similar is true of JNIEnv*s. They might be valid if the next native call happens on the same thread, but they won’t be valid otherwise.)

and from here: https://developer.android.com/training/articles/perf-jni

Quote
The JNIEnv is used for thread-local storage. For this reason, you cannot share a JNIEnv between threads.


Remember that "LAMW Pascal" side/code  talk to "LAMW java" [multi-thread?] side/code..... 

So at some time if you comment out these two lines of code:

Quote
  gApp.Jni.jEnv := env;                             // <----
  if this <> nil then gApp.Jni.jThis := this;  // <--- 

you will get  a staled object reference .....

Lamw: Lazarus Android Module Wizard
https://github.com/jmpessoa/lazandroidmodulewizard

 

TinyPortal © 2005-2018