Program: 32054
Project: 32054
Buggy source:
/** 
 * Send a "m.new_device" message to remind it that we exist and are a member of a room. This is rate limited to send a message at most once an hour per destination.
 * @param deviceId the id of the device to ping. If nil, all devices.
 * @param userId the id of the user to ping.
 * @param roomId the room id
 */
private void sendPingToDevice(String deviceId,String userId,String roomId){
  if ((null == userId) || (null == roomId)) {
    return;
  }
  if (TextUtils.isEmpty(deviceId)) {
    deviceId="String_Node_Str";
  }
  HashMap<String,Long> lastTsByRoom=mLastNewDeviceMessageTsByUserDeviceRoom.objectForDevice(deviceId,userId);
  if (null == lastTsByRoom) {
    lastTsByRoom=new HashMap<>();
  }
  Long lastTs=lastTsByRoom.get(roomId);
  if (null == lastTs) {
    lastTs=0L;
  }
  long now=System.currentTimeMillis();
  if ((now - lastTs) < 3600000) {
    return;
  }
  lastTsByRoom.put(roomId,now);
  mLastNewDeviceMessageTsByUserDeviceRoom.setObject(lastTsByRoom,userId,deviceId);
  MXUsersDevicesMap<Map<String,Object>> contentMap=new MXUsersDevicesMap<>();
  HashMap<String,Object> submap=new HashMap<>();
  submap.put("String_Node_Str",deviceId);
  submap.put("String_Node_Str",Arrays.asList(roomId));
  HashMap<String,Map<String,Object>> map=new HashMap<>();
  map.put(deviceId,submap);
  contentMap.setObjects(map,userId);
  mSession.getCryptoRestClient().sendToDevice(Event.EVENT_TYPE_NEW_DEVICE,contentMap,new ApiCallback<Void>(){
    @Override public void onSuccess(    Void info){
    }
    @Override public void onNetworkError(    Exception e){
      Log.e(LOG_TAG,"String_Node_Str" + e.getMessage());
    }
    @Override public void onMatrixError(    MatrixError e){
      Log.e(LOG_TAG,"String_Node_Str" + e.getLocalizedMessage());
    }
    @Override public void onUnexpectedError(    Exception e){
      Log.e(LOG_TAG,"String_Node_Str" + e.getMessage());
    }
  }
);
}

Fixed version (ground truth):
/** 
 * Send a "m.new_device" message to remind it that we exist and are a member of a room. This is rate limited to send a message at most once an hour per destination.
 * @param deviceId the id of the device to ping. If nil, all devices.
 * @param userId the id of the user to ping.
 * @param roomId the room id
 */
private void sendPingToDevice(String deviceId,String userId,String roomId){
  if ((null == userId) || (null == roomId)) {
    return;
  }
  if (TextUtils.isEmpty(deviceId)) {
    deviceId="String_Node_Str";
  }
  HashMap<String,Long> lastTsByRoom=mLastNewDeviceMessageTsByUserDeviceRoom.objectForDevice(deviceId,userId);
  if (null == lastTsByRoom) {
    lastTsByRoom=new HashMap<>();
  }
  Long lastTs=lastTsByRoom.get(roomId);
  if (null == lastTs) {
    lastTs=0L;
  }
  long now=System.currentTimeMillis();
  if ((now - lastTs) < 3600000) {
    return;
  }
  lastTsByRoom.put(roomId,now);
  mLastNewDeviceMessageTsByUserDeviceRoom.setObject(lastTsByRoom,userId,deviceId);
  MXUsersDevicesMap<Map<String,Object>> contentMap=new MXUsersDevicesMap<>();
  HashMap<String,Object> submap=new HashMap<>();
  submap.put("String_Node_Str",mSession.getCredentials().deviceId);
  submap.put("String_Node_Str",Arrays.asList(roomId));
  HashMap<String,Map<String,Object>> map=new HashMap<>();
  map.put(deviceId,submap);
  contentMap.setObjects(map,userId);
  mSession.getCryptoRestClient().sendToDevice(Event.EVENT_TYPE_NEW_DEVICE,contentMap,new ApiCallback<Void>(){
    @Override public void onSuccess(    Void info){
    }
    @Override public void onNetworkError(    Exception e){
      Log.e(LOG_TAG,"String_Node_Str" + e.getMessage());
    }
    @Override public void onMatrixError(    MatrixError e){
      Log.e(LOG_TAG,"String_Node_Str" + e.getLocalizedMessage());
    }
    @Override public void onUnexpectedError(    Exception e){
      Log.e(LOG_TAG,"String_Node_Str" + e.getMessage());
    }
  }
);
}