// Send a command to the supplicant, and return the reply as a String. static jstring doStringCommand(JNIEnv* env, jstring javaCommand) { char reply[REPLY_BUF_SIZE]; ScopedUtfChars command(env, javaCommand); if (!doCommand(env, javaCommand, reply, sizeof(reply))) { return NULL; } if (DBG) ALOGD("cmd = %s, reply: %s", command.c_str(), reply); String16 str; if (strstr(command.c_str(),"BSS RANGE=")) { parseScanResults(str,reply); } else if (strstr(command.c_str(),"GET_NETWORK") && strstr(command.c_str(),"ssid") && !strstr(command.c_str(),"bssid") && !strstr(command.c_str(),"scan_ssid")){ constructSsid(str, reply); } else { str += String16((char *)reply); } return env->NewString((const jchar *)str.string(), str.size()); }
status_t String16::setTo(const String16& other, size_t len, size_t begin) { const size_t N = other.size(); if (begin >= N) { SharedBuffer::bufferFromData(mString)->release(); mString = getEmptyString(); return NO_ERROR; } if ((begin+len) > N) len = N-begin; if (begin == 0 && len == N) { setTo(other); return NO_ERROR; } if (&other == this) { LOG_ALWAYS_FATAL("Not implemented"); } return setTo(other.string()+begin, len); }
String16 pseudo_generate_expansion(const unsigned int length) { String16 result = k_expansion_string; const char16_t* s = result.string(); if (result.size() < length) { result += String16(" "); result += pseudo_generate_expansion(length - result.size()); } else { int ext = 0; // Should contain only whole words, so looking for a space for (unsigned int i = length + 1; i < result.size(); ++i) { ++ext; if (s[i] == ' ') { break; } } result.remove(length + ext, 0); } return result; }
String16 pseudobidi_string(const String16& source) { const char16_t* s = source.string(); String16 result; result += k_rlm; result += k_rlo; for (size_t i=0; i<source.size(); i++) { char16_t c = s[i]; switch(c) { case ' ': result += k_pdf; result += k_rlm; result.append(&c, 1); result += k_rlm; result += k_rlo; break; default: result.append(&c, 1); break; } } result += k_pdf; result += k_rlm; return result; }
bool String16::startsWith(const String16& prefix) const { const size_t ps = prefix.size(); if (ps > size()) return false; return strzcmp16(mString, ps, prefix.string(), ps) == 0; }
status_t parseStyledString(Bundle* bundle, const char* fileName, ResXMLTree* inXml, const String16& endTag, String16* outString, Vector<StringPool::entry_style_span>* outSpans, bool pseudolocalize) { Vector<StringPool::entry_style_span> spanStack; String16 curString; String16 rawString; const char* errorMsg; int xliffDepth = 0; bool firstTime = true; size_t len; ResXMLTree::event_code_t code; while ((code=inXml->next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { if (code == ResXMLTree::TEXT) { String16 text(inXml->getText(&len)); if (firstTime && text.size() > 0) { firstTime = false; if (text.string()[0] == '@') { // If this is a resource reference, don't do the pseudoloc. pseudolocalize = false; } } if (xliffDepth == 0 && pseudolocalize) { std::string orig(String8(text).string()); std::string pseudo = pseudolocalize_string(orig); curString.append(String16(String8(pseudo.c_str()))); } else { curString.append(text); } } else if (code == ResXMLTree::START_TAG) { const String16 element16(inXml->getElementName(&len)); const String8 element8(element16); size_t nslen; const uint16_t* ns = inXml->getElementNamespace(&nslen); if (ns == NULL) { ns = (const uint16_t*)"\0\0"; nslen = 0; } const String8 nspace(String16(ns, nslen)); if (nspace == XLIFF_XMLNS) { const int N = sizeof(ALLOWED_XLIFF_ELEMENTS)/sizeof(ALLOWED_XLIFF_ELEMENTS[0]); for (int i=0; i<N; i++) { if (element8 == ALLOWED_XLIFF_ELEMENTS[i]) { xliffDepth++; // in this case, treat it like it was just text, in other words, do nothing // here and silently drop this element goto moveon; } } { SourcePos(String8(fileName), inXml->getLineNumber()).error( "Found unsupported XLIFF tag <%s>\n", element8.string()); return UNKNOWN_ERROR; } moveon: continue; } if (outSpans == NULL) { SourcePos(String8(fileName), inXml->getLineNumber()).error( "Found style tag <%s> where styles are not allowed\n", element8.string()); return UNKNOWN_ERROR; } if (!ResTable::collectString(outString, curString.string(), curString.size(), false, &errorMsg, true)) { SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n", errorMsg, String8(curString).string()); return UNKNOWN_ERROR; } rawString.append(curString); curString = String16(); StringPool::entry_style_span span; span.name = element16; for (size_t ai=0; ai<inXml->getAttributeCount(); ai++) { span.name.append(String16(";")); const char16_t* str = inXml->getAttributeName(ai, &len); span.name.append(str, len); span.name.append(String16("=")); str = inXml->getAttributeStringValue(ai, &len); span.name.append(str, len); } //printf("Span: %s\n", String8(span.name).string()); span.span.firstChar = span.span.lastChar = outString->size(); spanStack.push(span); } else if (code == ResXMLTree::END_TAG) { size_t nslen; const uint16_t* ns = inXml->getElementNamespace(&nslen); if (ns == NULL) { ns = (const uint16_t*)"\0\0"; nslen = 0; } const String8 nspace(String16(ns, nslen)); if (nspace == XLIFF_XMLNS) { xliffDepth--; continue; } if (!ResTable::collectString(outString, curString.string(), curString.size(), false, &errorMsg, true)) { SourcePos(String8(fileName), inXml->getLineNumber()).error("%s (in %s)\n", errorMsg, String8(curString).string()); return UNKNOWN_ERROR; } rawString.append(curString); curString = String16(); if (spanStack.size() == 0) { if (strcmp16(inXml->getElementName(&len), endTag.string()) != 0) { SourcePos(String8(fileName), inXml->getLineNumber()).error( "Found tag %s where <%s> close is expected\n", String8(inXml->getElementName(&len)).string(), String8(endTag).string()); return UNKNOWN_ERROR; } break; } StringPool::entry_style_span span = spanStack.top(); String16 spanTag; ssize_t semi = span.name.findFirst(';'); if (semi >= 0) { spanTag.setTo(span.name.string(), semi); } else { spanTag.setTo(span.name); } if (strcmp16(inXml->getElementName(&len), spanTag.string()) != 0) { SourcePos(String8(fileName), inXml->getLineNumber()).error( "Found close tag %s where close tag %s is expected\n", String8(inXml->getElementName(&len)).string(), String8(spanTag).string()); return UNKNOWN_ERROR; } bool empty = true; if (outString->size() > 0) { span.span.lastChar = outString->size()-1; if (span.span.lastChar >= span.span.firstChar) { empty = false; outSpans->add(span); } } spanStack.pop(); /* * This warning seems to be just an irritation to most people, * since it is typically introduced by translators who then never * see the warning. */ if (0 && empty) { fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n", fileName, inXml->getLineNumber(), String8(spanTag).string(), String8(*outString).string()); } } else if (code == ResXMLTree::START_NAMESPACE) { // nothing } } if (code == ResXMLTree::BAD_DOCUMENT) { SourcePos(String8(fileName), inXml->getLineNumber()).error( "Error parsing XML\n"); } if (outSpans != NULL && outSpans->size() > 0) { if (curString.size() > 0) { if (!ResTable::collectString(outString, curString.string(), curString.size(), false, &errorMsg, true)) { SourcePos(String8(fileName), inXml->getLineNumber()).error( "%s (in %s)\n", errorMsg, String8(curString).string()); return UNKNOWN_ERROR; } } } else { // There is no style information, so string processing will happen // later as part of the overall type conversion. Return to the // client the raw unprocessed text. rawString.append(curString); outString->setTo(rawString); } return NO_ERROR; }
String8::String8(const String16& o) : mString(allocFromUTF16(o.string(), o.size())) { }
bool sendBroadcastMessage(String16 action, int value) { ALOGD("sendBroadcastMessage(): Action: %s, Value: %d ", action.string(), value); sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> am = sm->getService(String16("activity")); if (am != NULL) { Parcel data, reply; data.writeInterfaceToken(String16("android.app.IActivityManager")); data.writeStrongBinder(NULL); // intent begin data.writeString16(action); // action data.writeInt32(0); // URI data type data.writeString16(NULL, 0); // type data.writeInt32(0); // flags data.writeString16(NULL, 0); // package name data.writeString16(NULL, 0); // component name data.writeInt32(0); // source bound - size data.writeInt32(0); // categories - size data.writeInt32(0); // selector - size data.writeInt32(0); // clipData - size data.writeInt32(-2); // contentUserHint: -2 -> UserHandle.USER_CURRENT data.writeInt32(-1); // bundle extras length data.writeInt32(0x4C444E42); // 'B' 'N' 'D' 'L' int oldPos = data.dataPosition(); data.writeInt32(1); // size // data.writeInt32(0); // VAL_STRING, need to remove because of analyze common intent data.writeString16(String16(TYPE)); data.writeInt32(1); // VAL_INTEGER data.writeInt32(value); int newPos = data.dataPosition(); data.setDataPosition(oldPos - 8); data.writeInt32(newPos - oldPos); // refill bundle extras length data.setDataPosition(newPos); // intent end data.writeString16(NULL, 0); // resolvedType data.writeStrongBinder(NULL); // resultTo data.writeInt32(0); // resultCode data.writeString16(NULL, 0); // resultData data.writeInt32(-1); // resultExtras data.writeString16(NULL, 0); // permission data.writeInt32(0); // appOp data.writeInt32(1); // serialized: != 0 -> ordered data.writeInt32(0); // sticky data.writeInt32(-2); // userId: -2 -> UserHandle.USER_CURRENT status_t ret = am->transact(IBinder::FIRST_CALL_TRANSACTION + 13, data, &reply); // BROADCAST_INTENT_TRANSACTION if (ret == NO_ERROR) { int exceptionCode = reply.readExceptionCode(); if (exceptionCode) { ALOGE("sendBroadcastMessage(%s) caught exception %d\n", action.string(), exceptionCode); return false; } } else { return false; } } else { ALOGE("getService() couldn't find activity service!\n"); return false; } return true; }
jstring string16ToJstring(JNIEnv* env, String16 string) { const char16_t* str = string.string(); size_t len = string.size(); return env->NewString(reinterpret_cast<const jchar*>(str), len); }
static bool getAppInfo(const String8& path, AppInfo& outInfo) { memset(&outInfo, 0, sizeof(outInfo)); AssetManager assetManager; int32_t cookie = 0; if (!assetManager.addAssetPath(path, &cookie)) { return false; } Asset* asset = assetManager.openNonAsset(cookie, "AndroidManifest.xml", Asset::ACCESS_BUFFER); if (asset == NULL) { return false; } ResXMLTree xml; if (xml.setTo(asset->getBuffer(true), asset->getLength(), false) != NO_ERROR) { delete asset; return false; } const String16 kAndroidNamespace("http://schemas.android.com/apk/res/android"); const String16 kManifestTag("manifest"); const String16 kApplicationTag("application"); const String16 kUsesSdkTag("uses-sdk"); const String16 kVersionCodeAttr("versionCode"); const String16 kMultiArchAttr("multiArch"); const String16 kMinSdkVersionAttr("minSdkVersion"); ResXMLParser::event_code_t event; while ((event = xml.next()) != ResXMLParser::BAD_DOCUMENT && event != ResXMLParser::END_DOCUMENT) { if (event != ResXMLParser::START_TAG) { continue; } size_t len; const char16_t* name = xml.getElementName(&len); String16 name16(name, len); if (name16 == kManifestTag) { ssize_t idx = xml.indexOfAttribute( kAndroidNamespace.string(), kAndroidNamespace.size(), kVersionCodeAttr.string(), kVersionCodeAttr.size()); if (idx >= 0) { outInfo.versionCode = xml.getAttributeData(idx); } } else if (name16 == kApplicationTag) { ssize_t idx = xml.indexOfAttribute( kAndroidNamespace.string(), kAndroidNamespace.size(), kMultiArchAttr.string(), kMultiArchAttr.size()); if (idx >= 0) { outInfo.multiArch = xml.getAttributeData(idx) != 0; } } else if (name16 == kUsesSdkTag) { ssize_t idx = xml.indexOfAttribute( kAndroidNamespace.string(), kAndroidNamespace.size(), kMinSdkVersionAttr.string(), kMinSdkVersionAttr.size()); if (idx >= 0) { uint16_t type = xml.getAttributeDataType(idx); if (type >= Res_value::TYPE_FIRST_INT && type <= Res_value::TYPE_LAST_INT) { outInfo.minSdkVersion = xml.getAttributeData(idx); } else if (type == Res_value::TYPE_STRING) { String8 minSdk8(xml.getStrings().string8ObjectAt(idx)); char* endPtr; int minSdk = strtol(minSdk8.string(), &endPtr, 10); if (endPtr != minSdk8.string() + minSdk8.size()) { fprintf(stderr, "warning: failed to parse android:minSdkVersion '%s'\n", minSdk8.string()); } else { outInfo.minSdkVersion = minSdk; } } else { fprintf(stderr, "warning: unrecognized value for android:minSdkVersion.\n"); } } } } delete asset; return true; }
/** * Converts characters so they look like they've been localized. * * Note: This leaves escape sequences untouched so they can later be * processed by ResTable::collectString in the normal way. */ String16 pseudolocalize_string(const String16& source) { const char16_t* s = source.string(); String16 result; const size_t I = source.size(); for (size_t i=0; i<I; i++) { char16_t c = s[i]; if (c == '\\') { // Escape syntax, no need to pseudolocalize if (i<I-1) { result += String16("\\"); i++; c = s[i]; switch (c) { case 'u': // this one takes up 5 chars result += String16(s+i, 5); i += 4; break; case 't': case 'n': case '#': case '@': case '?': case '"': case '\'': case '\\': default: result.append(&c, 1); break; } } else { result.append(&c, 1); } } else if (c == '%') { // Placeholder syntax, no need to pseudolocalize result += k_placeholder_open; bool end = false; result.append(&c, 1); while (!end && i < I) { ++i; c = s[i]; result.append(&c, 1); if (is_possible_normal_placeholder_end(c)) { end = true; } else if (c == 't') { ++i; c = s[i]; result.append(&c, 1); end = true; } } result += k_placeholder_close; } else if (c == '<' || c == '&') { // html syntax, no need to pseudolocalize bool tag_closed = false; while (!tag_closed && i < I) { if (c == '&') { String16 escape_text; escape_text.append(&c, 1); bool end = false; size_t htmlCodePos = i; while (!end && htmlCodePos < I) { ++htmlCodePos; c = s[htmlCodePos]; escape_text.append(&c, 1); // Valid html code if (c == ';') { end = true; i = htmlCodePos; } // Wrong html code else if (!((c == '#' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')))) { end = true; } } result += escape_text; if (escape_text != String16("<")) { tag_closed = true; } continue; } if (c == '>') { tag_closed = true; result.append(&c, 1); continue; } result.append(&c, 1); i++; c = s[i]; } } else { // This is a pure text that should be pseudolocalized const char* p = pseudolocalize_char(c); if (p != NULL) { result += String16(p); } else { result.append(&c, 1); } } } return result; }