1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2010 The Android Open Source Project
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License.
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and
14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License.
15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <input/KeyCharacterMap.h>
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <input/KeyLayoutMap.h>
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <input/VirtualKeyMap.h>
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/PropertyMap.h>
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/String8.h>
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdio.h>
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdlib.h>
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <string.h>
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace android;
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const char* gProgName = "validatekeymaps";
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskienum FileType {
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FILETYPE_UNKNOWN,
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FILETYPE_KEYLAYOUT,
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FILETYPE_KEYCHARACTERMAP,
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FILETYPE_VIRTUALKEYDEFINITION,
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FILETYPE_INPUTDEVICECONFIGURATION,
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void usage() {
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(stderr, "Keymap Validation Tool\n\n");
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(stderr, "Usage:\n");
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(stderr,
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        " %s [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]\n"
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "   Validates the specified key layouts, key character maps, \n"
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        "   input device configurations, or virtual key definitions.\n\n",
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        gProgName);
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic FileType getFileType(const char* filename) {
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char *extension = strrchr(filename, '.');
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (extension) {
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (strcmp(extension, ".kl") == 0) {
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return FILETYPE_KEYLAYOUT;
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (strcmp(extension, ".kcm") == 0) {
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return FILETYPE_KEYCHARACTERMAP;
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (strcmp(extension, ".idc") == 0) {
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return FILETYPE_INPUTDEVICECONFIGURATION;
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (strstr(filename, "virtualkeys.")) {
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return FILETYPE_VIRTUALKEYDEFINITION;
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return FILETYPE_UNKNOWN;
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic bool validateFile(const char* filename) {
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(stdout, "Validating file '%s'...\n", filename);
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FileType fileType = getFileType(filename);
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    switch (fileType) {
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    case FILETYPE_UNKNOWN:
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(stderr, "Supported file types: *.kl, *.kcm, virtualkeys.*\n\n");
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return false;
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    case FILETYPE_KEYLAYOUT: {
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<KeyLayoutMap> map;
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t status = KeyLayoutMap::load(String8(filename), &map);
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (status) {
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "Error %d parsing key layout file.\n\n", status);
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        break;
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    case FILETYPE_KEYCHARACTERMAP: {
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<KeyCharacterMap> map;
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t status = KeyCharacterMap::load(String8(filename),
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                KeyCharacterMap::FORMAT_ANY, &map);
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (status) {
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "Error %d parsing key character map file.\n\n", status);
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        break;
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    case FILETYPE_INPUTDEVICECONFIGURATION: {
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        PropertyMap* map;
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t status = PropertyMap::load(String8(filename), &map);
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (status) {
105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "Error %d parsing input device configuration file.\n\n", status);
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delete map;
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        break;
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    case FILETYPE_VIRTUALKEYDEFINITION: {
113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        VirtualKeyMap* map;
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t status = VirtualKeyMap::load(String8(filename), &map);
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (status) {
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(stderr, "Error %d parsing virtual key definition file.\n\n", status);
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delete map;
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        break;
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fputs("No errors.\n\n", stdout);
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return true;
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiint main(int argc, const char** argv) {
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (argc < 2) {
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        usage();
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 1;
132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int result = 0;
135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (int i = 1; i < argc; i++) {
136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!validateFile(argv[i])) {
137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            result = 1;
138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (result) {
142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fputs("Failed!\n", stderr);
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fputs("Success.\n", stdout);
145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return result;
147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
148