• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Java TypedUtil类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了Java中com.google.ipc.invalidation.util.TypedUtil的典型用法代码示例。如果您正苦于以下问题:Java TypedUtil类的具体用法?Java TypedUtil怎么用?Java TypedUtil使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



TypedUtil类属于com.google.ipc.invalidation.util包,在下文中一共展示了TypedUtil类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Java代码示例。

示例1: deserializeState

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Deserializes a Ticl state blob. Returns either the parsed state or {@code null}
 * if it could not be parsed.
 */
public static PersistentTiclState deserializeState(Logger logger, byte[] stateBlobBytes,
    DigestFunction digestFn) {
  PersistentStateBlob stateBlob;
  try {
    // Try parsing the envelope protocol buffer.
    stateBlob = PersistentStateBlob.parseFrom(stateBlobBytes);
  } catch (ValidationException exception) {
    logger.severe("Failed deserializing Ticl state: %s", exception.getMessage());
    return null;
  }

  // Check the mac in the envelope against the recomputed mac from the state.
  PersistentTiclState ticlState = stateBlob.getTiclState();
  Bytes mac = generateMac(ticlState, digestFn);
  if (!TypedUtil.<Bytes>equals(mac, stateBlob.getAuthenticationCode())) {
    logger.warning("Ticl state failed MAC check: computed %s vs %s", mac,
        stateBlob.getAuthenticationCode());
    return null;
  }
  return ticlState;
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:26,代码来源:PersistenceUtils.java


示例2: handleImplicitSchedulerEvent

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/** Runs all tasks that are ready to run. */
void handleImplicitSchedulerEvent() {
  try {
    while (!scheduledTasks.isEmpty() && (scheduledTasks.firstKey() <= clock.nowMs())) {
      Map.Entry<Long, String> scheduledTask = scheduledTasks.pollFirstEntry();
      Runnable runnable = TypedUtil.mapGet(registeredTasks, scheduledTask.getValue());
      if (runnable == null) {
        logger.severe("No task registered for %s", scheduledTask.getValue());
        continue;
      }
      runnable.run();
    }
  } finally {
    if (!scheduledTasks.isEmpty()) {
      ensureIntentScheduledForSoonestTask();
    }
  }
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:19,代码来源:AndroidInternalScheduler.java


示例3: readKey

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
@Override
public void readKey(final String key, final Callback<SimplePair<Status, byte[]>> done) {
  scheduler.schedule(Scheduler.NO_DELAY,
      new NamedRunnable("MemoryStorage.readKey") {
    @Override
    public void run() {
      byte[] value = TypedUtil.mapGet(ticlPersistentState, key);
      final SimplePair<Status, byte[]> result;
      if (value != null) {
        result = SimplePair.of(Status.newInstance(Status.Code.SUCCESS, ""), value);
      } else {
        String error = "No value present in map for " + key;
        result = SimplePair.of(Status.newInstance(Status.Code.PERMANENT_FAILURE, error), null);
      }
      done.accept(result);
    }
  });
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:19,代码来源:MemoryStorageImpl.java


示例4: equals

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Overridden for tests which compare listener states to verify that they have been correctly
 * (un)marshalled. We implement equals rather than exposing private data.
 */
@Override
public boolean equals(Object object) {
  if (this == object) {
    return true;
  }

  if (!(object instanceof AndroidListenerState)) {
    return false;
  }

  AndroidListenerState that = (AndroidListenerState) object;

  return (this.isDirty == that.isDirty)
      && (this.requestCodeSeqNum == that.requestCodeSeqNum)
      && (this.desiredRegistrations.size() == that.desiredRegistrations.size())
      && (this.desiredRegistrations.containsAll(that.desiredRegistrations))
      && TypedUtil.<Bytes>equals(this.clientId, that.clientId)
      && equals(this.delayGenerators, that.delayGenerators)
      && equals(this.registrationRetries, that.registrationRetries);
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:25,代码来源:AndroidListenerState.java


示例5: deserializeState

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Deserializes a Ticl state blob. Returns either the parsed state or {@code null}
 * if it could not be parsed.
 */
public static PersistentTiclState deserializeState(Logger logger, byte[] stateBlobBytes,
    DigestFunction digestFn) {
  PersistentStateBlob stateBlob;
  try {
    // Try parsing the envelope protocol buffer.
    stateBlob = PersistentStateBlob.parseFrom(stateBlobBytes);
  } catch (InvalidProtocolBufferException exception) {
    logger.severe("Failed deserializing Ticl state: %s", exception.getMessage());
    return null;
  }

  // Check the mac in the envelope against the recomputed mac from the state.
  PersistentTiclState ticlState = stateBlob.getTiclState();
  ByteString mac = generateMac(ticlState, digestFn);
  if (!TypedUtil.<ByteString>equals(mac, stateBlob.getAuthenticationCode())) {
    logger.warning("Ticl state failed MAC check: computed %s vs %s", mac,
        stateBlob.getAuthenticationCode());
    return null;
  }
  return ticlState;
}
 
开发者ID:morristech,项目名称:android-chromium,代码行数:26,代码来源:PersistenceUtils.java


示例6: decodeTiclState

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Returns the persisted state for the client with key {@code clientKey} in
 * {@code storageForClient}, or {@code null} if no valid state could be found.
 * <p>
 * REQUIRES: {@code storageForClient}.load() has been called successfully.
 */


PersistentTiclState decodeTiclState(final String clientKey, AndroidStorage storageForClient) {
  synchronized (lock) {
    // Retrieve the serialized state.
    final Map<String, byte[]> properties = storageForClient.getPropertiesUnsafe();
    byte[] clientStateBytes = TypedUtil.mapGet(properties,
        InvalidationClientCore.CLIENT_TOKEN_KEY);
    if (clientStateBytes == null) {
      logger.warning("No client state found in storage for %s: %s", clientKey,
          properties.keySet());
      return null;
    }

    // Deserialize it.
    PersistentTiclState clientState =
        PersistenceUtils.deserializeState(logger, clientStateBytes, digestFn);
    if (clientState == null) {
      logger.warning("Invalid client state found in storage for %s", clientKey);
      return null;
    }
    return clientState;
  }
}
 
开发者ID:morristech,项目名称:android-chromium,代码行数:31,代码来源:AndroidInvalidationService.java


示例7: MessageInfo

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Constructs a message info.
 *
 * @param messageAccessor descriptor for the protocol buffer
 * @param fields information about the fields
 */
public MessageInfo(Accessor messageAccessor, FieldInfo... fields) {
  // Track which fields in the message descriptor have not yet been covered by a FieldInfo.
  // We'll use this to verify that we get a FieldInfo for every field.
  Set<String> unusedDescriptors = new HashSet<String>();
  unusedDescriptors.addAll(messageAccessor.getAllFieldNames());

  this.messageAccessor = messageAccessor;
  for (FieldInfo info : fields) {
    // Lookup the field given the name in the FieldInfo.
    boolean removed = TypedUtil.remove(unusedDescriptors, info.getFieldDescriptor().getName());
    Preconditions.checkState(removed, "Bad field: %s", info.getFieldDescriptor().getName());

    // Add the field info to the number -> info map.
    fieldInfo.add(info);

    if (info.getPresence() == Presence.REQUIRED) {
      ++numRequiredFields;
    }
  }
  Preconditions.checkState(unusedDescriptors.isEmpty(), "Not all fields specified in %s: %s",
      messageAccessor, unusedDescriptors);
}
 
开发者ID:morristech,项目名称:android-chromium,代码行数:29,代码来源:ProtoValidator.java


示例8: create

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
@Override
protected void create(Request request, Response.Builder response) {
  synchronized (LOCK) {
    validateRequest(request, Action.CREATE, Parameter.ACTION, Parameter.CLIENT,
        Parameter.CLIENT_TYPE, Parameter.ACCOUNT, Parameter.AUTH_TYPE, Parameter.INTENT);
    logger.info("Creating client %s:%s", request.getClientKey(), clientMap.keySet());
    if (!TypedUtil.containsKey(clientMap, request.getClientKey())) {
      // If no client exists with this key, create one.
      clientMap.put(
          request.getClientKey(), new ClientState(request.getAccount(), request.getAuthType(),
              request.getIntent()));
    } else {
      // Otherwise, verify that the existing client has the same account / auth type / intent.
      ClientState existingState = TypedUtil.mapGet(clientMap, request.getClientKey());
      Preconditions.checkState(request.getAccount().equals(existingState.account));
      Preconditions.checkState(request.getAuthType().equals(existingState.authType));
    }
    response.setStatus(Response.Status.SUCCESS);
  }
}
 
开发者ID:morristech,项目名称:android-chromium,代码行数:21,代码来源:InvalidationTestService.java


示例9: deserializeStatistics

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Given the serialized {@code performanceCounters} of the client statistics, returns a Statistics
 * object with the performance counter values from {@code performanceCounters}.
 */

public static Statistics deserializeStatistics(Logger logger,
    Collection<PropertyRecord> performanceCounters) {
  Statistics statistics = new Statistics();

  // For each counter, parse out the counter name and value.
  for (PropertyRecord performanceCounter : performanceCounters) {
    String counterName = performanceCounter.getName();
    String[] parts = counterName.split("\\.");
    if (parts.length != 2) {
      logger.warning("Perf counter name must of form: class.value, skipping: %s", counterName);
      continue;
    }
    String className = parts[0];
    String fieldName = parts[1];
    int counterValue = performanceCounter.getValue();

    // Call the relevant method in a loop (i.e., depending on the type of the class).
    if (TypedUtil.<String>equals(className, SENT_MESSAGE_TYPE_NAME)) {
      incrementPerformanceCounterValue(logger, SENT_MESSAGE_TYPE_NAME_TO_VALUE_MAP,
          statistics.sentMessageTypes, fieldName, counterValue);
    } else if (TypedUtil.<String>equals(className, INCOMING_OPERATION_TYPE_NAME)) {
      incrementPerformanceCounterValue(logger, INCOMING_OPERATION_TYPE_NAME_TO_VALUE_MAP,
          statistics.incomingOperationTypes, fieldName, counterValue);
    } else if (TypedUtil.<String>equals(className, RECEIVED_MESSAGE_TYPE_NAME)) {
      incrementPerformanceCounterValue(logger, RECEIVED_MESSAGE_TYPE_NAME_TO_VALUE_MAP,
          statistics.receivedMessageTypes, fieldName, counterValue);
    } else if (TypedUtil.<String>equals(className,  LISTENER_EVENT_TYPE_NAME)) {
      incrementPerformanceCounterValue(logger, LISTENER_EVENT_TYPE_NAME_TO_VALUE_MAP,
          statistics.listenerEventTypes, fieldName, counterValue);
    } else if (TypedUtil.<String>equals(className,  CLIENT_ERROR_TYPE_NAME)) {
      incrementPerformanceCounterValue(logger, CLIENT_ERROR_TYPE_NAME_TO_VALUE_MAP,
          statistics.clientErrorTypes, fieldName, counterValue);
    } else {
      logger.warning("Skipping unknown enum class name %s", className);
    }
  }
  return statistics;
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:44,代码来源:Statistics.java


示例10: incrementPerformanceCounterValue

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Looks for an enum value with the given {@code fieldName} in {@code valueOfMap} and increments
 * the corresponding entry in {@code counts} by {@code counterValue}. Call to update statistics
 * for a single performance counter.
 */
private static <Key extends Enum<Key>> void incrementPerformanceCounterValue(Logger logger,
    Map<String, Key> valueOfMap, Map<Key, Integer> counts, String fieldName, int counterValue) {
  Key type = TypedUtil.mapGet(valueOfMap, fieldName);
  if (type != null) {
    int currentValue = TypedUtil.mapGet(counts, type);
    counts.put(type, currentValue + counterValue);
  } else {
    logger.warning("Skipping unknown enum value name %s", fieldName);
  }
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:16,代码来源:Statistics.java


示例11: handleSchedulerEvent

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Handles an event intent created in {@link #schedule} by running that event, along with any
 * other events whose time has come.
 */
void handleSchedulerEvent(AndroidSchedulerEvent event) {
  Runnable recurringTaskRunnable = TypedUtil.mapGet(registeredTasks, event.getEventName());
  if (recurringTaskRunnable == null) {
    throw new NullPointerException("No task registered for " + event.getEventName());
  }
  if (ticlId != event.getTiclId()) {
    logger.warning("Ignoring event with wrong ticl id (not %s): %s", ticlId, event);
    return;
  }
  recurringTaskRunnable.run();
  handleImplicitSchedulerEvent();
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:17,代码来源:AndroidInternalScheduler.java


示例12: isDigestValid

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/** Returns whether the digest in {@code state} is correct. */
private static boolean isDigestValid(AndroidTiclStateWithDigest state, Logger logger) {
  Sha1DigestFunction digester = new Sha1DigestFunction();
  digester.update(state.getState().toByteArray());
  byte[] computedDigest = digester.getDigest();
  if (!TypedUtil.<Bytes>equals(new Bytes(computedDigest), state.getDigest())) {
    logger.warning("Android TICL state digest mismatch; computed %s for %s",
        computedDigest, state);
    return false;
  }
  return true;
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:13,代码来源:TiclStateManager.java


示例13: handleTokenChanged

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Handles a token-control message.
 * @param headerToken token in the server message
 * @param newToken the new token provided, or {@code null} if this is a destroy message.
 */
private void handleTokenChanged(Bytes headerToken, final Bytes newToken) {
  Preconditions.checkState(internalScheduler.isRunningOnThread(), "Not on internal thread");

  // The server is either supplying a new token in response to an InitializeMessage, spontaneously
  // destroying a token we hold, or spontaneously upgrading a token we hold.

  if (newToken != null) {
    // Note: headerToken cannot be null, so a null nonce or clientToken will always be non-equal.
    boolean headerTokenMatchesNonce = TypedUtil.<Bytes>equals(headerToken, nonce);
    boolean headerTokenMatchesExistingToken = TypedUtil.<Bytes>equals(headerToken, clientToken);
    boolean shouldAcceptToken = headerTokenMatchesNonce || headerTokenMatchesExistingToken;
    if (!shouldAcceptToken) {
      logger.info("Ignoring new token; %s does not match nonce = %s or existing token = %s",
          newToken, nonce, clientToken);
      return;
    }
    logger.info("New token being assigned at client: %s, Old = %s", newToken, clientToken);

    // Start the regular heartbeats now.
    heartbeatTask.ensureScheduled("Heartbeat-after-new-token");
    setNonce(null);
    setClientToken(newToken);
    persistentWriteTask.ensureScheduled("Write-after-new-token");
  } else {
    logger.info("Destroying existing token: %s", clientToken);
    acquireToken("Destroy");
  }
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:34,代码来源:InvalidationClientCore.java


示例14: validateToken

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Returns whether the token in the header of {@code parsedMessage} matches either the
 * client token or nonce of this Ticl (depending on which is non-{@code null}).
 */
private boolean validateToken(ParsedMessage parsedMessage) {
  if (clientToken != null) {
    // Client token case.
    if (!TypedUtil.<Bytes>equals(clientToken, parsedMessage.header.token)) {
      logger.info("Incoming message has bad token: server = %s, client = %s",
          parsedMessage.header.token, clientToken);
      statistics.recordError(ClientErrorType.TOKEN_MISMATCH);
      return false;
    }
    return true;
  } else if (nonce != null) {
    // Nonce case.
    if (!TypedUtil.<Bytes>equals(nonce, parsedMessage.header.token)) {
      statistics.recordError(ClientErrorType.NONCE_MISMATCH);
      logger.info("Rejecting server message with mismatched nonce: Client = %s, Server = %s",
          nonce, parsedMessage.header.token);
      return false;
    } else {
      logger.info("Accepting server message with matching nonce: %s", nonce);
      return true;
    }
  }
  // Neither token nor nonce; ignore message.
  logger.warning("Neither token nor nonce was set in validateToken: %s, %s", clientToken, nonce);
  return false;
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:31,代码来源:InvalidationClientCore.java


示例15: deleteKey

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
@Override
public void deleteKey(final String key, final Callback<Boolean> done) {
  scheduler.schedule(Scheduler.NO_DELAY,
      new NamedRunnable("MemoryStorage.deleteKey") {
    @Override
    public void run() {
      TypedUtil.remove(ticlPersistentState, key);
      done.accept(true);
    }
  });
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:12,代码来源:MemoryStorageImpl.java


示例16: handleSchedulerEvent

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Handles an event intent created in {@link #schedule} by running the corresponding recurring
 * task.
 * <p>
 * REQUIRES: a recurring task with the name in the intent be present in {@link #registeredTasks}.
 */
void handleSchedulerEvent(AndroidSchedulerEvent event) {
  Runnable recurringTaskRunnable = Preconditions.checkNotNull(
      TypedUtil.mapGet(registeredTasks, event.getEventName()),
      "No task registered for %s", event.getEventName());
  if (ticlId != event.getTiclId()) {
    logger.warning("Ignoring event with wrong ticl id (not %s): %s", ticlId, event);
    return;
  }
  recurringTaskRunnable.run();
}
 
开发者ID:morristech,项目名称:android-chromium,代码行数:17,代码来源:AndroidInternalScheduler.java


示例17: handleTokenChanged

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Handles a token-control message.
 * @param headerToken token in the server message
 * @param newToken the new token provided, or {@code null} if this is a destroy message.
 */
private void handleTokenChanged(ByteString headerToken, final ByteString newToken) {
  Preconditions.checkState(internalScheduler.isRunningOnThread(), "Not on internal thread");

  // The server is either supplying a new token in response to an InitializeMessage, spontaneously
  // destroying a token we hold, or spontaneously upgrading a token we hold.

  if (newToken != null) {
    // Note: headerToken cannot be null, so a null nonce or clientToken will always be non-equal.
    boolean headerTokenMatchesNonce = TypedUtil.<ByteString>equals(headerToken, nonce);
    boolean headerTokenMatchesExistingToken =
        TypedUtil.<ByteString>equals(headerToken, clientToken);
    boolean shouldAcceptToken = headerTokenMatchesNonce || headerTokenMatchesExistingToken;
    if (!shouldAcceptToken) {
      logger.info("Ignoring new token; %s does not match nonce = %s or existing token = %s",
          newToken, nonce, clientToken);
      return;
    }
    logger.info("New token being assigned at client: %s, Old = %s",
        CommonProtoStrings2.toLazyCompactString(newToken),
        CommonProtoStrings2.toLazyCompactString(clientToken));

    // Start the regular heartbeats now.
    heartbeatTask.ensureScheduled("Heartbeat-after-new-token");
    setNonce(null);
    setClientToken(newToken);
    persistentWriteTask.ensureScheduled("Write-after-new-token");
  } else {
    logger.info("Destroying existing token: %s",
        CommonProtoStrings2.toLazyCompactString(clientToken));
    acquireToken("Destroy");
  }
}
 
开发者ID:morristech,项目名称:android-chromium,代码行数:38,代码来源:InvalidationClientCore.java


示例18: validateToken

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Returns whether the token in the header of {@code parsedMessage} matches either the
 * client token or nonce of this Ticl (depending on which is non-{@code null}).
 */
private boolean validateToken(ParsedMessage parsedMessage) {
  if (clientToken != null) {
    // Client token case.
    if (!TypedUtil.<ByteString>equals(clientToken, parsedMessage.header.token)) {
      logger.info("Incoming message has bad token: server = %s, client = %s",
          CommonProtoStrings2.toLazyCompactString(parsedMessage.header.token),
          CommonProtoStrings2.toLazyCompactString(clientToken));
      statistics.recordError(ClientErrorType.TOKEN_MISMATCH);
      return false;
    }
    return true;
  } else if (nonce != null) {
    // Nonce case.
    if (!TypedUtil.<ByteString>equals(nonce, parsedMessage.header.token)) {
      statistics.recordError(ClientErrorType.NONCE_MISMATCH);
      logger.info("Rejecting server message with mismatched nonce: Client = %s, Server = %s",
          CommonProtoStrings2.toLazyCompactString(nonce),
          CommonProtoStrings2.toLazyCompactString(parsedMessage.header.token));
      return false;
    } else {
      logger.info("Accepting server message with matching nonce: %s",
          CommonProtoStrings2.toLazyCompactString(nonce));
      return true;
    }
  }
  // Neither token nor nonce; ignore message.
  logger.warning("Neither token nor nonce was set in validateToken: %s, %s", clientToken, nonce);
  return false;
}
 
开发者ID:morristech,项目名称:android-chromium,代码行数:34,代码来源:InvalidationClientCore.java


示例19: getHighestAckedVersion

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/**
 * Returns the highest acked version for the object id with the given key, or
 * -1 if no versions have been acked.
 */
private long getHighestAckedVersion(ObjectIdP objectId) {
  Long version = TypedUtil.mapGet(highestAckedVersionMap, objectId);
  return (version != null) ? version : -1L;
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:9,代码来源:AckCache.java


示例20: getClientErrorCounterForTest

import com.google.ipc.invalidation.util.TypedUtil; //导入依赖的package包/类
/** Returns the counter value for {@code clientErrorType}. */
int getClientErrorCounterForTest(ClientErrorType clientErrorType) {
  return TypedUtil.mapGet(clientErrorTypes, clientErrorType);
}
 
开发者ID:mogoweb,项目名称:365browser,代码行数:5,代码来源:Statistics.java



注:本文中的com.google.ipc.invalidation.util.TypedUtil类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Java SortOptionList类代码示例发布时间:2022-05-22
下一篇:
Java FormEngine类代码示例发布时间:2022-05-22
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap