/* * Obtain device names configured in the WebUI (ReGa) */ private static void fetchDeviceNamesFromReGa() { lastFetch = System.currentTimeMillis(); L.info("Obtaining ReGa device and channel names"); String r = TCLRegaHandler.sendHMScript( "string id;" + "foreach(id, root.Channels ().EnumUsedIDs())" + " {" + " var ch=dom.GetObject(id);" + " WriteLine(ch.Address()+\"\t\"+ch.Name());" + " }" + "foreach(id, root.Devices().EnumUsedIDs())" + " {" + " var d=dom.GetObject(id);" + " WriteLine(d.Address()+\":0\t\"+d.Name());" + " }"); if (r == null) return; String lines[] = r.split("\n"); for (String l : lines) { String p[] = l.split("\t"); synchronized (nameCache) { if (p.length == 2) nameCache.put(p[0], p[1]); } } couldFetchOnce = true; DeviceInfo.resolveNames(); }
/** * Sends the message using the Sender object to the registered device. * * @param message the message to be sent in the GCM ping to the device. * @param sender the Sender object to be used for ping, * @param deviceInfo the registration id of the device. * @return Result the result of the ping. */ private static Result doSendViaGcm(String message, Sender sender, DeviceInfo deviceInfo) throws IOException { // Trim message if needed. if (message.length() > 1000) { message = message.substring(0, 1000) + "[...]"; } // This message object is a Google Cloud Messaging object, it is NOT // related to the MessageData class Message msg = new Message.Builder().addData("message", message).build(); Result result = sender.send(msg, deviceInfo.getDeviceRegistrationID(), 5); if (result.getMessageId() != null) { String canonicalRegId = result.getCanonicalRegistrationId(); if (canonicalRegId != null) { endpoint.removeDeviceInfo(deviceInfo.getDeviceRegistrationID()); deviceInfo.setDeviceRegistrationID(canonicalRegId); endpoint.insertDeviceInfo(deviceInfo); } } else { String error = result.getErrorCodeName(); if (error.equals(Constants.ERROR_NOT_REGISTERED)) { endpoint.removeDeviceInfo(deviceInfo.getDeviceRegistrationID()); } } return result; }
// We need to iterate again - can be avoided with a query. // delete will fail if the pm is different than the one used to // load the object - we must close the object when we're done public void deleteRegistration(String regId) { if (ctx == null) { return; } PersistenceManager pm = DBHelper.getPMF(ctx).getPersistenceManager(); try { List<DeviceInfo> registrations = DeviceInfo.getDeviceInfoForUserEmail(pm, userEmail); for (int i = 0; i < registrations.size(); i++) { DeviceInfo deviceInfo = registrations.get(i); if (deviceInfo.getDeviceRegistrationID().equals(regId)) { pm.deletePersistent(deviceInfo); // Keep looping in case of duplicates log.log( Level.INFO, "RequestInfo:deleteRegistration() : deleted deviceInfo for " + deviceInfo.getDeviceRegistrationID()); } } } catch (JDOObjectNotFoundException e) { log.warning("RequestInfo:deleteRegistration() : User unknown"); } catch (Exception e) { log.warning( "RequestInfo:deleteRegistration() : Error unregistering device: " + e.getMessage()); } finally { pm.close(); } }
public static void storeDevices(Hashtable devices, String selected) { File cf = getConfigFile(); if (cf == null) { return; } FileWriter fw = null; try { fw = new FileWriter(cf, false); for (Enumeration i = devices.keys(); i.hasMoreElements(); ) { String addr = (String) i.nextElement(); DeviceInfo di = (DeviceInfo) devices.get(addr); fw.write(devicePrefix + di.saveAsLine() + "\n"); } if (selected != null) { fw.write(selectedPrefix + selected + "\n"); } for (Enumeration en = properties.propertyNames(); en.hasMoreElements(); ) { String name = (String) en.nextElement(); fw.write(name + "=" + properties.getProperty(name) + "\n"); } fw.flush(); } catch (Throwable e) { Logger.debug(e); return; } finally { if (fw != null) { try { fw.close(); } catch (IOException e) { } } } }
public static SharedWrapper with(@NonNull Context context, @NonNull String name) { if (secretSingleton == null || ivSingleton == null) { synchronized (SharedWrapper.class) { if (secretSingleton == null) { secretSingleton = Crypt.AES.generateSecret(Digest.SHA256.getRaw(DeviceInfo.getDeviceToken(context))); } if (ivSingleton == null) { ivSingleton = Crypt.AES.generateIV(Digest.MD5.getRaw(DeviceInfo.getDeviceToken(context))); } } } return new SharedWrapper(context, name, secretSingleton, ivSingleton); }
public static String loadDevices(Hashtable devices) { File cf = getConfigFile(); if (cf == null || !cf.exists()) { return null; } Reader fr = null; LineNumberReader lnr = null; try { lnr = new LineNumberReader(fr = new FileReader(cf)); devices.clear(); String line = lnr.readLine(); String selected = null; while (line != null) { if (line.startsWith(devicePrefix)) { DeviceInfo di = new DeviceInfo(); di.loadFromLine(line.substring(devicePrefix.length())); if (di.isValid()) { devices.put(di.btAddress.toLowerCase(), di); } } else if (line.startsWith(selectedPrefix)) { selected = line.substring(selectedPrefix.length()); } else { int p = line.indexOf('='); if (p != -1) { properties.put(line.substring(0, p), line.substring(p + 1)); } } line = lnr.readLine(); } return selected; } catch (Throwable e) { Logger.debug(e); return null; } finally { if (lnr != null) { try { lnr.close(); } catch (IOException e) { } } if (fr != null) { try { fr.close(); } catch (IOException e) { } } } }
private void initDevices(ServletContext ctx) { // Context-shared PMF. PersistenceManager pm = DBHelper.getPMF(ctx).getPersistenceManager(); try { devices = DeviceInfo.getDeviceInfoForUserEmail(pm, userEmail); // cleanup for multi-device /*if (devices.size() > 1) { // Make sure there is no 'bare' registration // Keys are sorted - check the first DeviceInfo first = devices.get(0); Key oldKey = first.getKey(); if (oldKey.toString().indexOf("#") < 0) { log.warning("Removing old-style key " + oldKey.toString()); // multiple devices, first is old-style. devices.remove(0); pm.deletePersistent(first); } }*/ log.log( Level.INFO, "RequestInfo:initDevices() : loading devices " + devices.size() + " for user = "******"RequestInfo:initDevices() : Error loading registrations ", e); } finally { pm.close(); } }
@Override public void uncaughtException(Thread arg0, Throwable arg1) { // 把错误的堆栈信息 获取出来 String errorInfo = getErrorInfo(arg1); String uuidKey = UUID.nameUUIDFromBytes(errorInfo.getBytes()).toString(); String existsException = Utils.getSharedPreferences("uncaughtException").getString(uuidKey, ""); if (!existsException.equals("")) { // -- this uncaughtException has got Debug.Log("Exception has got yet: " + errorInfo); Debug.Log("kill self() "); android.os.Process.killProcess(android.os.Process.myPid()); return; } Editor editor = Utils.getSharedPreferences("uncaughtException").edit(); editor.putString(uuidKey, "Mark"); editor.commit(); String content = DeviceInfo.getInfo(context).toString(); String msg = content + "\nStack:\n" + errorInfo; Debug.Log("uncaughtException: " + msg); errorContent = msg; // sendExceptionMsg(); }
public static String getConnectionSuffix() { String connSuffix; if (DeviceInfo.isSimulator()) { connSuffix = ";deviceside=true"; } else if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) && RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN)) { connSuffix = ";interface=wifi"; } else { String uid = null; ServiceBook sb = ServiceBook.getSB(); ServiceRecord[] records = sb.findRecordsByCid("WPTCP"); for (int i = 0; i < records.length; i++) { if (records[i].isValid() && !records[i].isDisabled()) { if (records[i].getUid() != null && records[i].getUid().length() != 0) { if ((records[i].getCid().toLowerCase().indexOf("wptcp") != -1) && (records[i].getUid().toLowerCase().indexOf("wifi") == -1) && (records[i].getUid().toLowerCase().indexOf("mms") == -1)) { uid = records[i].getUid(); break; } } } } if (uid != null) { // WAP2 Connection connSuffix = ";ConnectionUID=" + uid; } else { connSuffix = ";deviceside=true"; } } return connSuffix; }
private boolean doRegisterIOSToUrban(DeviceInfo deviceInfo) { try { URL url = new URL( "https://go.urbanairship.com/api/device_tokens/" + deviceInfo.getDeviceRegistrationID()); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("PUT"); connection.setDoOutput(true); String appKey = Config.URBAN_APP_KEY; String appMasterSecret = Config.URBAN_APP_MASTERSECRET; String authString = appKey + ":" + appMasterSecret; String authStringBase64 = Base64.encode(authString.getBytes()); authStringBase64 = authStringBase64.trim(); connection.setRequestProperty("Content-type", "application/json"); connection.setRequestProperty("Authorization", "Basic " + authStringBase64); JSONObject object = new JSONObject(); if (deviceInfo.getDeviceName() != null && !deviceInfo.getDeviceName().isEmpty()) { object.put("alias", deviceInfo.getDeviceName()); } object.put("tz", "America/Los_Angeles"); // String jsonBodyString = "{\"alias\": \""+ deviceInfo.getDeviceName() + // "\", \"tz\": \"America/Los_Angeles\" }"; OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream()); osw.write(object.toString()); osw.close(); int responseCode = connection.getResponseCode(); log.log( Level.INFO, "RegisterServlet.doRegisterIOSToUrban() : registering to Urban OK, resp = " + responseCode); return true; } catch (Exception e) { log.log( Level.WARNING, "RegisterServlet.doRegisterIOSToUrban() : Error registering to Urban.", e); } return false; }
private static boolean doSendViaC2dm( String message, String sender, C2DMessaging push, String collapseKey, DeviceInfo deviceInfo) { // Trim message if needed. if (message.length() > 1000) { message = message.substring(0, 1000) + "[...]"; } return push.sendNoRetry( deviceInfo.getDeviceRegistrationID(), collapseKey, "sender", sender, "message", message); }
private void doUnregister(String deviceRegistrationID, String accountName) { log.info("in unregister: accountName = " + accountName); PersistenceManager pm = PMF.get().getPersistenceManager(); try { List<DeviceInfo> registrations = DeviceInfo.getDeviceInfoForUser(accountName); for (int i = 0; i < registrations.size(); i++) { DeviceInfo deviceInfo = registrations.get(i); if (deviceInfo.getDeviceRegistrationID().equals(deviceRegistrationID)) { pm.deletePersistent(deviceInfo); // Keep looping in case of duplicates } } } catch (JDOObjectNotFoundException e) { log.warning("User " + accountName + " unknown"); } catch (Exception e) { log.warning("Error unregistering device: " + e.getMessage()); } finally { pm.close(); } }
/** For debug - and possibly show the info, allow device selection. */ @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { GeatteRegisterRequestInfo reqInfo = GeatteRegisterRequestInfo.processRequest(req, resp, getServletContext()); if (reqInfo == null) { return; } resp.setContentType("application/json"); JSONObject regs = new JSONObject(); try { regs.put("userEmail", reqInfo.getUserEmail()); JSONArray devices = new JSONArray(); for (DeviceInfo di : reqInfo.devices) { JSONObject dijson = new JSONObject(); dijson.put("key", di.getKey().toString()); dijson.put("deviceName", di.getDeviceName()); dijson.put("type", di.getType()); dijson.put("registrationId", di.getDeviceRegistrationID()); dijson.put("timestamp", di.getRegistrationTimestamp()); devices.put(dijson); } regs.put("devices", devices); PrintWriter out = resp.getWriter(); regs.write(out); } catch (JSONException e) { throw new IOException(e); } }
private boolean containsDeviceInfo(DeviceInfo deviceinfo) { EntityManager mgr = getEntityManager(); boolean contains = true; try { DeviceInfo item = mgr.find(DeviceInfo.class, deviceinfo.getDeviceRegistrationID()); if (item == null) { contains = false; } } finally { mgr.close(); } return contains; }
/* * Obtain device names from a JSON table (e.g. from hm-manager) */ private static void fetchDeviceNamesFromNameTable(String filename) { lastFetch = System.currentTimeMillis(); try (FileReader f = new FileReader(filename)) { JsonObject table = Json.parse(f).asObject(); int cnt = 0; synchronized (nameCache) { for (Member m : table) { nameCache.put(m.getName(), m.getValue().asString()); cnt++; } } L.log(Level.INFO, "Read " + cnt + " entries from name table " + filename); couldFetchOnce = true; DeviceInfo.resolveNames(); } catch (Exception e) { L.log(Level.WARNING, "Error reading device name table " + filename, e); } }
public DeviceInfo getDeviceInfoFromApplicationContext() { return DeviceInfo.getInstance(this); }
/** * directory of removable SD card, can be different from getExternalStorageDirectory() according * to devices * * @return */ public static File getRemovableSDCardDirectory() { return DeviceInfo.singleton().getDeviceController().getRemovableSDCardDirectory(); }
private void doRegister( String deviceRegistrationId, String deviceType, String deviceId, String accountName) throws Exception { log.info("in register: accountName = " + accountName); PersistenceManager pm = PMF.get().getPersistenceManager(); try { List<DeviceInfo> registrations = DeviceInfo.getDeviceInfoForUser(accountName); log.info("got registrations"); if (registrations.size() > MAX_DEVICES) { log.info("got registrations > MAX_DEVICES"); // we could return an error - but user can't handle it yet. // we can't let it grow out of bounds. // TODO: we should also define a 'ping' message and expire/remove // unused registrations DeviceInfo oldest = registrations.get(0); if (oldest.getRegistrationTimestamp() == null) { pm.deletePersistent(oldest); } else { long oldestTime = oldest.getRegistrationTimestamp().getTime(); for (int i = 1; i < registrations.size(); i++) { if (registrations.get(i).getRegistrationTimestamp().getTime() < oldestTime) { oldest = registrations.get(i); oldestTime = oldest.getRegistrationTimestamp().getTime(); } } pm.deletePersistent(oldest); } } // Get device if it already exists, else create String suffix = (deviceId != null ? "#" + Long.toHexString(Math.abs(deviceId.hashCode())) : ""); log.info("suffix = " + suffix); Key key = KeyFactory.createKey(DeviceInfo.class.getSimpleName(), accountName + suffix); log.info("key = " + key); DeviceInfo device = null; try { device = pm.getObjectById(DeviceInfo.class, key); } catch (JDOObjectNotFoundException e) { log.info("Caught JDOObjectNotFoundException"); } if (device == null) { device = new DeviceInfo(key, deviceRegistrationId); device.setType(deviceType); } else { // update registration id device.setDeviceRegistrationID(deviceRegistrationId); device.setRegistrationTimestamp(new Date()); } pm.makePersistent(device); return; } catch (Exception e) { log.info("Caught exception: " + e); throw e; } finally { pm.close(); } }
public static boolean isFileOnRemovableSDCard(File file) { return DeviceInfo.singleton().getDeviceController().isFileOnRemovableSDCard(file); }
public void doRequest(int type) { switch (type) { case REQUEST_SESSION: { String time = new Long(new Date().getTime()).toString(); String timestamp = time.substring(0, time.length() - 3); String postParam = "application_id=" + PUSH_APP_ID + "&auth_key=" + PUSH_AUTH_KEY + "&nonce=" + nonce + "×tamp=" + timestamp; String signature = ""; try { signature = QBUtils.hmacsha1(PUSH_AUTH_SECRET, postParam); } catch (Exception ex) { DebugStorage.getInstance().Log(0, "<PushAuthScreen> doRequest REQUEST_SESSION ", ex); break; } JSONObject postObject = new JSONObject(); try { postObject.put("application_id", PUSH_APP_ID); postObject.put("auth_key", PUSH_AUTH_KEY); postObject.put("nonce", nonce); postObject.put("timestamp", timestamp); postObject.put("signature", signature); } catch (Exception ex) { DebugStorage.getInstance().Log(0, "<PushAuthScreen> doRequest REQUEST_SESSION ", ex); } BigVector postData = new BigVector(); postData.addElement(postObject.toString()); QBHTTPConnManager man = new QBHTTPConnManager(POST, PUSH_SERVER_API + "session.json", postData, type, this); break; } case REQUEST_SIGN_UP_USER: { String pin = Integer.toHexString(DeviceInfo.getDeviceId()).toUpperCase(); JSONObject credentialsObject = new JSONObject(); JSONObject postObject = new JSONObject(); try { credentialsObject.put("login", pin); credentialsObject.put("password", TextUtils.reverse(pin)); postObject.put("user", credentialsObject); } catch (Exception ex) { } BigVector postData = new BigVector(); postData.addElement(TOKEN); postData.addElement(postObject.toString()); DebugStorage.getInstance().Log(0, "Post data: " + postObject.toString()); QBHTTPConnManager man = new QBHTTPConnManager(POST, PUSH_SERVER_API + "users.json", postData, type, this); break; } case REQUEST_SESSION_WITH_USER_AND_DEVICE_PARAMS: { JSONObject postObject = new JSONObject(); JSONObject userObject = new JSONObject(); JSONObject deviceObject = new JSONObject(); try { String pin = Integer.toHexString(DeviceInfo.getDeviceId()).toUpperCase(); String postParam = "application_id=" + PUSH_APP_ID + "&auth_key=" + PUSH_AUTH_KEY + "&device[platform]=" + "blackberry" + "&device[udid]=" + pin + "&nonce=" + nonce + "×tamp=" + timestamp + "&user[login]=" + pin + "&user[password]=" + TextUtils.reverse(pin); String signature = ""; try { signature = QBUtils.hmacsha1(PUSH_AUTH_SECRET, postParam); } catch (Exception ex) { System.out.println("QBUtils.hmacsha1(PUSH_AUTH_SECRET, postParam) exception = " + ex); } postObject.put("application_id", PUSH_APP_ID); postObject.put("auth_key", PUSH_AUTH_KEY); postObject.put("timestamp", timestamp); postObject.put("nonce", nonce); postObject.put("signature", signature); userObject.put("login", pin); userObject.put("password", TextUtils.reverse(pin)); postObject.put("user", userObject); deviceObject.put("platform", "blackberry"); deviceObject.put("udid", pin); postObject.put("device", deviceObject); } catch (Exception ex) { DebugStorage.getInstance().Log(0, "<PushAuthScreen> doRequest REQUEST_SESSION ", ex); onClose(); } BigVector postData = new BigVector(); postData.addElement(postObject.toString()); QBHTTPConnManager man = new QBHTTPConnManager(POST, PUSH_SERVER_API + "session.json", postData, type, this); break; } case REQUEST_PUSH_TOKEN: { String pin = Integer.toHexString(DeviceInfo.getDeviceId()).toUpperCase(); JSONObject credentialsObject = new JSONObject(); JSONObject postObject = new JSONObject(); try { // credentialsObject.put("environment", "production"); credentialsObject.put("environment", "development"); credentialsObject.put("client_identification_sequence", pin); postObject.put("push_token", credentialsObject); } catch (Exception ex) { System.out.println("-----<doRequest><REQUEST_PUSH_TOKEN> Exception = " + ex); } BigVector postData = new BigVector(); postData.addElement(TOKEN); postData.addElement(postObject.toString()); QBHTTPConnManager man = new QBHTTPConnManager( POST, PUSH_SERVER_API + "push_tokens.json", postData, type, this); break; } // REQUEST_PUSH_SUBSCRIBE case REQUEST_PUSH_SUBSCRIBE: { System.out.println("-----<doRequest><REQUEST_PUSH_SUBSCRIBE>"); JSONObject postObject = new JSONObject(); try { postObject.put("notification_channels", "bbps"); } catch (Exception ex) { System.out.println("-----<doRequest><REQUEST_PUSH_SUBSCRIBE> Exception = " + ex); } BigVector postData = new BigVector(); postData.addElement(TOKEN); postData.addElement(postObject.toString()); QBHTTPConnManager man = new QBHTTPConnManager( POST, PUSH_SERVER_API + "subscriptions.json", postData, type, this); break; } default: break; } }
private void initialize() { DeviceInfo.initialize(this); getServerConfig(); }
public static String sendMessage(ServletContext context, String recipient, String message) { PersistenceManager pm = PMF.get().getPersistenceManager(); try { UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); String sender = "nobody"; if (user != null) { sender = user.getEmail(); } log.info("sendMessage: sender = " + sender); log.info("sendMessage: recipient = " + recipient); log.info("sendMessage: message = " + message); // ok = we sent to at least one device. boolean ok = false; // Send push message to phone C2DMessaging push = C2DMessaging.get(context); boolean res = false; String collapseKey = "" + message.hashCode(); // delete will fail if the pm is different than the one used to // load the object - we must close the object when we're done List<DeviceInfo> registrations = null; registrations = DeviceInfo.getDeviceInfoForUser(recipient); log.info("sendMessage: got " + registrations.size() + " registrations"); // Deal with upgrades and multi-device: // If user has one device with an old version and few new ones - // the old registration will be deleted. if (registrations.size() > 1) { // Make sure there is no 'bare' registration // Keys are sorted - check the first DeviceInfo first = registrations.get(0); Key oldKey = first.getKey(); if (oldKey.toString().indexOf("#") < 0) { // multiple devices, first is old-style. registrations.remove(0); // don't send to it pm.deletePersistent(first); } } int numSendAttempts = 0; for (DeviceInfo deviceInfo : registrations) { if (!"ac2dm".equals(deviceInfo.getType())) { continue; // user-specified device type } res = doSendViaC2dm(message, sender, push, collapseKey, deviceInfo); numSendAttempts++; if (res) { ok = true; } } if (ok) { return "Success: Message sent"; } else if (numSendAttempts == 0) { return "Failure: User " + recipient + " not registered"; } else { return "Failure: Unable to send message"; } } catch (Exception e) { return "Failure: Got exception " + e; } finally { pm.close(); } }
public void get(URL url, HashMap hashmap, String s) { if (isConnected()) { url = new Request(RestUtil.prepareGetUrl("http://IP_ADDRESS:PORT/ws/app/WIDGET_ID/queue/device/DEVICE_ID", url, "interactivity_Button_label", DeviceInfo.getDeviceId()), "GET", true); url.addHeaders(hashmap); url.addBody(s); _requestExecuter.execute(url, 9003, _onRequestCallbackListener); return; } else { Log.w("RestClient", "Application not connected!"); return; } }
/** * wrapper of android.os.Environment.getExternalStorageDirectory * * @return */ public static File getExternalStorageDirectory() { return DeviceInfo.singleton().getDeviceController().getExternalStorageDirectory(); }
@Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { log.log(Level.INFO, "RegisterServlet.doPOST() : START RegisterServlet.doPOST()"); resp.setContentType("text/plain"); GeatteRegisterRequestInfo reqInfo = GeatteRegisterRequestInfo.processRequest(req, resp, getServletContext()); if (reqInfo == null) { log.severe("RegisterServlet.doPOST() : can not load RequestInfo!!"); return; } // Because the deviceRegistrationId isn't static, we use a static // identifier for the device. (Can be null in older clients) String deviceId = reqInfo.getParameter(Config.DEVICE_ID_PARAM); if (deviceId == null) { resp.setStatus(400); resp.getWriter().println(ERROR_STATUS + "(Must specify " + Config.DEVICE_ID_PARAM + ")"); log.severe( "RegisterServlet.doPOST() : Missing device id, " + Config.DEVICE_ID_PARAM + " is null"); return; } else { log.log( Level.INFO, "RegisterServlet.doPOST() : user sent a " + Config.DEVICE_ID_PARAM + " = " + deviceId); } String phoneNumber = reqInfo.getParameter(Config.DEV_PHONE_NUMBER_PARAM); if (phoneNumber == null) { resp.setStatus(400); resp.getWriter() .println(ERROR_STATUS + "(Must specify " + Config.DEV_PHONE_NUMBER_PARAM + ")"); log.severe( "RegisterServlet.doPOST() : Missing phone number, " + Config.DEV_PHONE_NUMBER_PARAM + " is null"); return; } else { log.log( Level.INFO, "RegisterServlet.doPOST() : user sent a " + Config.DEV_PHONE_NUMBER_PARAM + " = " + phoneNumber); } String phoneCountryIso = reqInfo.getParameter(Config.DEV_PHONE_COUNTRY_ISO_PARAM); if (phoneCountryIso == null) { // default is us phoneCountryIso = "us"; log.severe( "RegisterServlet.doPOST() : Missing phone country iso, " + Config.DEV_PHONE_COUNTRY_ISO_PARAM + " is null"); return; } else { log.log( Level.INFO, "RegisterServlet.doPOST() : user sent a " + Config.DEV_PHONE_COUNTRY_ISO_PARAM + " = " + phoneCountryIso); } PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); PhoneNumber numberProto = null; try { numberProto = phoneUtil.parse(phoneNumber, phoneCountryIso); } catch (NumberParseException npe) { log.log(Level.WARNING, "RegisterServlet.doPOST(): NumberParseException was thrown: ", npe); } if (numberProto != null && phoneUtil.isValidNumber(numberProto)) { phoneNumber = phoneUtil.format(numberProto, PhoneNumberFormat.E164); } else { log.log( Level.WARNING, "RegisterServlet.doPOST() : Invalid phone number so use passed-in number, " + Config.DEV_PHONE_NUMBER_PARAM + " = " + phoneNumber + ", countryIso = " + phoneCountryIso); } if (reqInfo.deviceRegistrationID == null) { resp.setStatus(400); resp.getWriter().println(ERROR_STATUS + "(Must specify " + Config.DEV_REG_ID_PARAM + ")"); log.severe( "RegisterServlet.doPOST() : Missing registration id, reqInfo.deviceRegistrationID is null"); return; } else { log.log( Level.INFO, "RegisterServlet.doPOST() : reqInfo.deviceRegistrationID = " + reqInfo.deviceRegistrationID); } String deviceName = reqInfo.getParameter(Config.DEVICE_NAME_PARAM); if (deviceName == null) { deviceName = "Phone"; log.log( Level.INFO, "RegisterServlet.doPOST() : use default " + Config.DEVICE_NAME_PARAM + " = " + deviceName); } else { log.log( Level.INFO, "RegisterServlet.doPOST() : user sent a " + Config.DEVICE_NAME_PARAM + " = " + deviceName); } // TODO: generate the device name by adding a number suffix for multiple // devices of same type. Change android app to send model/type. String deviceType = reqInfo.getParameter(Config.DEVICE_TYPE_PARAM); if (deviceType == null) { deviceType = DeviceInfo.TYPE_AC2DM; log.log( Level.INFO, "RegisterServlet.doPOST() : use default " + Config.DEVICE_TYPE_PARAM + " = " + deviceType); } else { log.log( Level.INFO, "RegisterServlet.doPOST() : user sent a " + Config.DEVICE_TYPE_PARAM + " = " + deviceType); } // Context-shared PMF. PersistenceManager pm = DBHelper.getPMF(getServletContext()).getPersistenceManager(); try { List<DeviceInfo> registrations = reqInfo.devices; if (registrations.size() > MAX_DEVICES) { log.log( Level.INFO, "RegisterServlet.doPOST() : user has too many devices, registrations.size = " + registrations.size()); // we could return an error - but user can't handle it yet. // we can't let it grow out of bounds. // TODO: we should also define a 'ping' message and // expire/remove // unused registrations DeviceInfo oldest = registrations.get(0); if (oldest.getRegistrationTimestamp() == null) { log.log( Level.INFO, "RegisterServlet.doPOST() : user has too many devices, trying to remove old one = " + oldest.getDeviceRegistrationID()); pm.deletePersistent(oldest); } else { long oldestTime = oldest.getRegistrationTimestamp().getTime(); for (int i = 1; i < registrations.size(); i++) { if (registrations.get(i).getRegistrationTimestamp().getTime() < oldestTime) { oldest = registrations.get(i); oldestTime = oldest.getRegistrationTimestamp().getTime(); } } log.log( Level.INFO, "RegisterServlet.doPOST() : user has too many devices, trying to remove old one = " + oldest.getDeviceRegistrationID()); pm.deletePersistent(oldest); } } // Get device if it already exists, else create // String suffix = (deviceId != null ? "#" + // Long.toHexString(Math.abs(deviceId.hashCode())) : ""); // Key key = KeyFactory.createKey(DeviceInfo.class.getSimpleName(), // reqInfo.userName + suffix); Key key = KeyFactory.createKey(DeviceInfo.class.getSimpleName(), deviceId); DeviceInfo device = null; try { device = pm.getObjectById(DeviceInfo.class, key); } catch (JDOObjectNotFoundException e) { } if (device == null) { log.log( Level.INFO, "RegisterServlet.doPOST() : can not find a DeviceInfo by key = " + key + ", create a new one"); // clean devices for same phone number, only one device allowed for one phone try { List<DeviceInfo> devicesForSameNumber = DeviceInfo.getDeviceInfoForNumber(pm, phoneNumber, phoneCountryIso); for (DeviceInfo deviceSameNumber : devicesForSameNumber) { pm.deletePersistent(deviceSameNumber); } } catch (JDOObjectNotFoundException e) { } device = new DeviceInfo(key, reqInfo.deviceRegistrationID); device.setType(deviceType); } else { log.log( Level.INFO, "RegisterServlet.doPOST() : find a DeviceInfo by key = " + key + ", update deviceRegistrationID to " + reqInfo.deviceRegistrationID); // update registration id device.setDeviceRegistrationID(reqInfo.deviceRegistrationID); device.setRegistrationTimestamp(new Date()); } device.setPhoneNumber(phoneNumber); // update phoneNumber device.setCountryCode(phoneCountryIso); // update country code device.setUserEmail(reqInfo.getUserEmail()); // update user email device.setDeviceName(deviceName); // update display name // TODO: only need to write if something changed, for chrome nothing // changes, we just create a new channel pm.makePersistent(device); log.log( Level.INFO, "RegisterServlet.doPOST() : Registered device userEmail = " + reqInfo.getUserEmail() + ", deviceType = " + deviceType + ", deviceRegistrationID = " + reqInfo.deviceRegistrationID + ", key = " + key); // if type is IOS, register to Urban if (device.getType().equalsIgnoreCase(DeviceInfo.TYPE_IOS)) { doRegisterIOSToUrban(device); resp.getWriter().println(OK_STATUS); } else if (device.getType().equalsIgnoreCase(DeviceInfo.TYPE_ANDROID) || device.getType().equalsIgnoreCase(DeviceInfo.TYPE_AC2DM)) { resp.getWriter().println(OK_STATUS); } else { resp.getWriter().println(ERROR_STATUS + "(Wrong " + Config.DEVICE_TYPE_PARAM + ")"); } log.log(Level.INFO, "RegisterServlet.doPOST() : END RegisterServlet.doPOST()"); } catch (Exception e) { resp.setStatus(500); resp.getWriter().println(ERROR_STATUS + " (Error registering device)"); log.log(Level.WARNING, "RegisterServlet.doPOST() : Error registering device.", e); } finally { pm.close(); } }