@@ -89,46 +89,100 @@ KeyCharacterMap::KeyCharacterMap() :
8989 mType (KEYBOARD_TYPE_UNKNOWN) {
9090}
9191
92+ KeyCharacterMap::KeyCharacterMap (const KeyCharacterMap& other) :
93+ RefBase (), mType (other.mType ) {
94+ for (size_t i = 0 ; i < other.mKeys .size (); i++) {
95+ mKeys .add (other.mKeys .keyAt (i), new Key (*other.mKeys .valueAt (i)));
96+ }
97+ }
98+
9299KeyCharacterMap::~KeyCharacterMap () {
93100 for (size_t i = 0 ; i < mKeys .size (); i++) {
94101 Key* key = mKeys .editValueAt (i);
95102 delete key;
96103 }
97104}
98105
99- status_t KeyCharacterMap::load (const String8& filename, sp<KeyCharacterMap>* outMap) {
106+ status_t KeyCharacterMap::load (const String8& filename,
107+ Format format, sp<KeyCharacterMap>* outMap) {
100108 outMap->clear ();
101109
102110 Tokenizer* tokenizer;
103111 status_t status = Tokenizer::open (filename, &tokenizer);
104112 if (status) {
105113 ALOGE (" Error %d opening key character map file %s." , status, filename.string ());
106114 } else {
107- sp<KeyCharacterMap> map = new KeyCharacterMap ();
108- if (!map.get ()) {
109- ALOGE (" Error allocating key character map." );
110- status = NO_MEMORY;
111- } else {
115+ status = load (tokenizer, format, outMap);
116+ delete tokenizer;
117+ }
118+ return status;
119+ }
120+
121+ status_t KeyCharacterMap::loadContents (const String8& filename, const char * contents,
122+ Format format, sp<KeyCharacterMap>* outMap) {
123+ outMap->clear ();
124+
125+ Tokenizer* tokenizer;
126+ status_t status = Tokenizer::fromContents (filename, contents, &tokenizer);
127+ if (status) {
128+ ALOGE (" Error %d opening key character map." , status);
129+ } else {
130+ status = load (tokenizer, format, outMap);
131+ delete tokenizer;
132+ }
133+ return status;
134+ }
135+
136+ status_t KeyCharacterMap::load (Tokenizer* tokenizer,
137+ Format format, sp<KeyCharacterMap>* outMap) {
138+ status_t status = OK;
139+ sp<KeyCharacterMap> map = new KeyCharacterMap ();
140+ if (!map.get ()) {
141+ ALOGE (" Error allocating key character map." );
142+ status = NO_MEMORY;
143+ } else {
112144#if DEBUG_PARSER_PERFORMANCE
113- nsecs_t startTime = systemTime (SYSTEM_TIME_MONOTONIC);
145+ nsecs_t startTime = systemTime (SYSTEM_TIME_MONOTONIC);
114146#endif
115- Parser parser (map.get (), tokenizer);
116- status = parser.parse ();
147+ Parser parser (map.get (), tokenizer, format );
148+ status = parser.parse ();
117149#if DEBUG_PARSER_PERFORMANCE
118- nsecs_t elapsedTime = systemTime (SYSTEM_TIME_MONOTONIC) - startTime;
119- ALOGD (" Parsed key character map file '%s' %d lines in %0.3fms." ,
120- tokenizer->getFilename ().string (), tokenizer->getLineNumber (),
121- elapsedTime / 1000000.0 );
150+ nsecs_t elapsedTime = systemTime (SYSTEM_TIME_MONOTONIC) - startTime;
151+ ALOGD (" Parsed key character map file '%s' %d lines in %0.3fms." ,
152+ tokenizer->getFilename ().string (), tokenizer->getLineNumber (),
153+ elapsedTime / 1000000.0 );
122154#endif
123- if (!status) {
124- *outMap = map;
125- }
155+ if (!status) {
156+ *outMap = map;
126157 }
127- delete tokenizer;
128158 }
129159 return status;
130160}
131161
162+ sp<KeyCharacterMap> KeyCharacterMap::combine (const sp<KeyCharacterMap>& base,
163+ const sp<KeyCharacterMap>& overlay) {
164+ if (overlay == NULL ) {
165+ return base;
166+ }
167+ if (base == NULL ) {
168+ return overlay;
169+ }
170+
171+ sp<KeyCharacterMap> map = new KeyCharacterMap (*base.get ());
172+ for (size_t i = 0 ; i < overlay->mKeys .size (); i++) {
173+ int32_t keyCode = overlay->mKeys .keyAt (i);
174+ Key* key = overlay->mKeys .valueAt (i);
175+ ssize_t oldIndex = map->mKeys .indexOfKey (keyCode);
176+ if (oldIndex >= 0 ) {
177+ delete map->mKeys .valueAt (oldIndex);
178+ map->mKeys .editValueAt (oldIndex) = new Key (*key);
179+ } else {
180+ map->mKeys .add (keyCode, new Key (*key));
181+ }
182+ }
183+ return map;
184+ }
185+
132186sp<KeyCharacterMap> KeyCharacterMap::empty () {
133187 return sEmpty ;
134188}
@@ -508,6 +562,11 @@ KeyCharacterMap::Key::Key() :
508562 label (0 ), number(0 ), firstBehavior(NULL ) {
509563}
510564
565+ KeyCharacterMap::Key::Key (const Key& other) :
566+ label (other.label), number(other.number),
567+ firstBehavior (other.firstBehavior ? new Behavior(*other.firstBehavior) : NULL ) {
568+ }
569+
511570KeyCharacterMap::Key::~Key () {
512571 Behavior* behavior = firstBehavior;
513572 while (behavior) {
@@ -524,11 +583,17 @@ KeyCharacterMap::Behavior::Behavior() :
524583 next (NULL ), metaState(0 ), character(0 ), fallbackKeyCode(0 ) {
525584}
526585
586+ KeyCharacterMap::Behavior::Behavior (const Behavior& other) :
587+ next (other.next ? new Behavior(*other.next) : NULL ),
588+ metaState (other.metaState), character(other.character),
589+ fallbackKeyCode (other.fallbackKeyCode) {
590+ }
591+
527592
528593// --- KeyCharacterMap::Parser ---
529594
530- KeyCharacterMap::Parser::Parser (KeyCharacterMap* map, Tokenizer* tokenizer) :
531- mMap (map), mTokenizer (tokenizer), mState (STATE_TOP) {
595+ KeyCharacterMap::Parser::Parser (KeyCharacterMap* map, Tokenizer* tokenizer, Format format ) :
596+ mMap (map), mTokenizer (tokenizer), mFormat (format), mState (STATE_TOP) {
532597}
533598
534599KeyCharacterMap::Parser::~Parser () {
@@ -588,10 +653,24 @@ status_t KeyCharacterMap::Parser::parse() {
588653 return BAD_VALUE;
589654 }
590655
591- if (mMap ->mType == KEYBOARD_TYPE_UNKNOWN) {
592- ALOGE (" %s: Missing required keyboard 'type' declaration." ,
593- mTokenizer ->getLocation ().string ());
594- return BAD_VALUE;
656+ if (mFormat == FORMAT_BASE) {
657+ if (mMap ->mType == KEYBOARD_TYPE_UNKNOWN) {
658+ ALOGE (" %s: Base keyboard layout missing required keyboard 'type' declaration." ,
659+ mTokenizer ->getLocation ().string ());
660+ return BAD_VALUE;
661+ }
662+ if (mMap ->mType == KEYBOARD_TYPE_OVERLAY) {
663+ ALOGE (" %s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'." ,
664+ mTokenizer ->getLocation ().string ());
665+ return BAD_VALUE;
666+ }
667+ } else if (mFormat == FORMAT_OVERLAY) {
668+ if (mMap ->mType != KEYBOARD_TYPE_OVERLAY) {
669+ ALOGE (" %s: Overlay keyboard layout missing required keyboard "
670+ " 'type OVERLAY' declaration." ,
671+ mTokenizer ->getLocation ().string ());
672+ return BAD_VALUE;
673+ }
595674 }
596675
597676 return NO_ERROR;
@@ -616,6 +695,8 @@ status_t KeyCharacterMap::Parser::parseType() {
616695 type = KEYBOARD_TYPE_FULL;
617696 } else if (typeToken == " SPECIAL_FUNCTION" ) {
618697 type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
698+ } else if (typeToken == " OVERLAY" ) {
699+ type = KEYBOARD_TYPE_OVERLAY;
619700 } else {
620701 ALOGE (" %s: Expected keyboard type label, got '%s'." , mTokenizer ->getLocation ().string (),
621702 typeToken.string ());
0 commit comments