1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org> 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the Android port of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 package org.qtproject.qt5.android; 41 42 import java.io.File; 43 import java.io.FileNotFoundException; 44 import java.io.FileOutputStream; 45 import java.io.IOException; 46 import java.io.OutputStreamWriter; 47 import java.lang.reflect.Field; 48 import java.util.ArrayList; 49 import java.util.HashMap; 50 import java.util.Map; 51 52 import org.json.JSONArray; 53 import org.json.JSONException; 54 import org.json.JSONObject; 55 import org.xmlpull.v1.XmlPullParser; 56 57 import android.content.Context; 58 import android.content.res.ColorStateList; 59 import android.content.res.Resources; 60 import android.content.res.TypedArray; 61 import android.content.res.XmlResourceParser; 62 import android.graphics.Bitmap; 63 import android.graphics.Bitmap.Config; 64 import android.graphics.Canvas; 65 import android.graphics.NinePatch; 66 import android.graphics.Paint; 67 import android.graphics.Rect; 68 import android.graphics.RectF; 69 import android.graphics.PorterDuff; 70 import android.graphics.drawable.AnimationDrawable; 71 import android.graphics.drawable.BitmapDrawable; 72 import android.graphics.drawable.ClipDrawable; 73 import android.graphics.drawable.ColorDrawable; 74 import android.graphics.drawable.Drawable; 75 import android.graphics.drawable.GradientDrawable; 76 import android.graphics.drawable.GradientDrawable.Orientation; 77 import android.graphics.drawable.InsetDrawable; 78 import android.graphics.drawable.LayerDrawable; 79 import android.graphics.drawable.NinePatchDrawable; 80 import android.graphics.drawable.RotateDrawable; 81 import android.graphics.drawable.ScaleDrawable; 82 import android.graphics.drawable.StateListDrawable; 83 import android.os.Build; 84 import android.util.AttributeSet; 85 import android.util.Log; 86 import android.util.Xml; 87 import android.view.inputmethod.EditorInfo; 88 89 90 public class ExtractStyle { 91 extractChunkInfo20(byte[] chunkData)92 native static int[] extractChunkInfo20(byte[] chunkData); extractNativeChunkInfo20(long nativeChunk)93 native static int[] extractNativeChunkInfo20(long nativeChunk); 94 95 Class<?> styleableClass = getClass("android.R$styleable"); 96 Class<?> rippleDrawableClass = getClass("android.graphics.drawable.RippleDrawable"); 97 Class<?> animatedStateListDrawableClass = getClass("android.graphics.drawable.AnimatedStateListDrawable"); 98 Class<?> vectorDrawableClass = getClass("android.graphics.drawable.VectorDrawable"); 99 100 final int[] EMPTY_STATE_SET = {}; 101 final int[] ENABLED_STATE_SET = {android.R.attr.state_enabled}; 102 final int[] FOCUSED_STATE_SET = {android.R.attr.state_focused}; 103 final int[] SELECTED_STATE_SET = {android.R.attr.state_selected}; 104 final int[] PRESSED_STATE_SET = {android.R.attr.state_pressed}; 105 final int[] WINDOW_FOCUSED_STATE_SET = {android.R.attr.state_window_focused}; 106 final int[] ENABLED_FOCUSED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, FOCUSED_STATE_SET); 107 final int[] ENABLED_SELECTED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, SELECTED_STATE_SET); 108 final int[] ENABLED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 109 final int[] FOCUSED_SELECTED_STATE_SET = stateSetUnion(FOCUSED_STATE_SET, SELECTED_STATE_SET); 110 final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 111 final int[] SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 112 final int[] ENABLED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_STATE_SET, SELECTED_STATE_SET); 113 final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 114 final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 115 final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 116 final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(ENABLED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 117 final int[] PRESSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 118 final int[] PRESSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, SELECTED_STATE_SET); 119 final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 120 final int[] PRESSED_FOCUSED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, FOCUSED_STATE_SET); 121 final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 122 final int[] PRESSED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_STATE_SET, SELECTED_STATE_SET); 123 final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 124 final int[] PRESSED_ENABLED_STATE_SET = stateSetUnion(PRESSED_STATE_SET, ENABLED_STATE_SET); 125 final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 126 final int[] PRESSED_ENABLED_SELECTED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, SELECTED_STATE_SET); 127 final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 128 final int[] PRESSED_ENABLED_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_STATE_SET, FOCUSED_STATE_SET); 129 final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 130 final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_STATE_SET, SELECTED_STATE_SET); 131 final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = stateSetUnion(PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, WINDOW_FOCUSED_STATE_SET); 132 133 134 final int View_background = getField(styleableClass,"View_background"); 135 final int View_padding = getField(styleableClass,"View_padding"); 136 final int View_paddingLeft = getField(styleableClass,"View_paddingLeft"); 137 final int View_paddingTop = getField(styleableClass,"View_paddingTop"); 138 final int View_paddingRight = getField(styleableClass,"View_paddingRight"); 139 final int View_paddingBottom = getField(styleableClass,"View_paddingBottom"); 140 final int View_scrollX = getField(styleableClass,"View_scrollX"); 141 final int View_scrollY = getField(styleableClass,"View_scrollY"); 142 final int View_id = getField(styleableClass,"View_id"); 143 final int View_tag = getField(styleableClass,"View_tag"); 144 final int View_fitsSystemWindows = getField(styleableClass,"View_fitsSystemWindows"); 145 final int View_focusable = getField(styleableClass,"View_focusable"); 146 final int View_focusableInTouchMode = getField(styleableClass,"View_focusableInTouchMode"); 147 final int View_clickable = getField(styleableClass,"View_clickable"); 148 final int View_longClickable = getField(styleableClass,"View_longClickable"); 149 final int View_saveEnabled = getField(styleableClass,"View_saveEnabled"); 150 final int View_duplicateParentState = getField(styleableClass,"View_duplicateParentState"); 151 final int View_visibility = getField(styleableClass,"View_visibility"); 152 final int View_drawingCacheQuality = getField(styleableClass,"View_drawingCacheQuality"); 153 final int View_contentDescription = getField(styleableClass,"View_contentDescription"); 154 final int View_soundEffectsEnabled = getField(styleableClass,"View_soundEffectsEnabled"); 155 final int View_hapticFeedbackEnabled = getField(styleableClass,"View_hapticFeedbackEnabled"); 156 final int View_scrollbars = getField(styleableClass,"View_scrollbars"); 157 final int View_fadingEdge = getField(styleableClass,"View_fadingEdge"); 158 final int View_scrollbarStyle = getField(styleableClass,"View_scrollbarStyle"); 159 final int View_scrollbarFadeDuration = getField(styleableClass,"View_scrollbarFadeDuration"); 160 final int View_scrollbarDefaultDelayBeforeFade = getField(styleableClass,"View_scrollbarDefaultDelayBeforeFade"); 161 final int View_scrollbarSize = getField(styleableClass,"View_scrollbarSize"); 162 final int View_scrollbarThumbHorizontal = getField(styleableClass,"View_scrollbarThumbHorizontal"); 163 final int View_scrollbarThumbVertical = getField(styleableClass,"View_scrollbarThumbVertical"); 164 final int View_scrollbarTrackHorizontal = getField(styleableClass,"View_scrollbarTrackHorizontal"); 165 final int View_scrollbarTrackVertical = getField(styleableClass,"View_scrollbarTrackVertical"); 166 final int View_isScrollContainer = getField(styleableClass,"View_isScrollContainer"); 167 final int View_keepScreenOn = getField(styleableClass,"View_keepScreenOn"); 168 final int View_filterTouchesWhenObscured = getField(styleableClass,"View_filterTouchesWhenObscured"); 169 final int View_nextFocusLeft = getField(styleableClass,"View_nextFocusLeft"); 170 final int View_nextFocusRight = getField(styleableClass,"View_nextFocusRight"); 171 final int View_nextFocusUp = getField(styleableClass,"View_nextFocusUp"); 172 final int View_nextFocusDown = getField(styleableClass,"View_nextFocusDown"); 173 final int View_minWidth = getField(styleableClass,"View_minWidth"); 174 final int View_minHeight = getField(styleableClass,"View_minHeight"); 175 final int View_onClick = getField(styleableClass,"View_onClick"); 176 final int View_overScrollMode = getField(styleableClass,"View_overScrollMode"); 177 final int View_paddingStart = getField(styleableClass,"View_paddingStart"); 178 final int View_paddingEnd = getField(styleableClass,"View_paddingEnd"); 179 180 final int TextAppearance_textColorHighlight = getField(styleableClass,"TextAppearance_textColorHighlight"); 181 final int TextAppearance_textColor = getField(styleableClass,"TextAppearance_textColor"); 182 final int TextAppearance_textColorHint = getField(styleableClass,"TextAppearance_textColorHint"); 183 final int TextAppearance_textColorLink = getField(styleableClass,"TextAppearance_textColorLink"); 184 final int TextAppearance_textSize = getField(styleableClass,"TextAppearance_textSize"); 185 final int TextAppearance_typeface = getField(styleableClass,"TextAppearance_typeface"); 186 final int TextAppearance_textStyle = getField(styleableClass,"TextAppearance_textStyle"); 187 final int TextAppearance_textAllCaps = getField(styleableClass,"TextAppearance_textAllCaps"); 188 final int TextView_editable = getField(styleableClass,"TextView_editable"); 189 final int TextView_inputMethod = getField(styleableClass,"TextView_inputMethod"); 190 final int TextView_numeric = getField(styleableClass,"TextView_numeric"); 191 final int TextView_digits = getField(styleableClass,"TextView_digits"); 192 final int TextView_phoneNumber = getField(styleableClass,"TextView_phoneNumber"); 193 final int TextView_autoText = getField(styleableClass,"TextView_autoText"); 194 final int TextView_capitalize = getField(styleableClass,"TextView_capitalize"); 195 final int TextView_bufferType = getField(styleableClass,"TextView_bufferType"); 196 final int TextView_selectAllOnFocus = getField(styleableClass,"TextView_selectAllOnFocus"); 197 final int TextView_autoLink = getField(styleableClass,"TextView_autoLink"); 198 final int TextView_linksClickable = getField(styleableClass,"TextView_linksClickable"); 199 final int TextView_drawableLeft = getField(styleableClass,"TextView_drawableLeft"); 200 final int TextView_drawableTop = getField(styleableClass,"TextView_drawableTop"); 201 final int TextView_drawableRight = getField(styleableClass,"TextView_drawableRight"); 202 final int TextView_drawableBottom = getField(styleableClass,"TextView_drawableBottom"); 203 final int TextView_drawableStart = getField(styleableClass,"TextView_drawableStart"); 204 final int TextView_drawableEnd = getField(styleableClass,"TextView_drawableEnd"); 205 final int TextView_drawablePadding = getField(styleableClass,"TextView_drawablePadding"); 206 final int TextView_textCursorDrawable = getField(styleableClass,"TextView_textCursorDrawable"); 207 final int TextView_maxLines = getField(styleableClass,"TextView_maxLines"); 208 final int TextView_maxHeight = getField(styleableClass,"TextView_maxHeight"); 209 final int TextView_lines = getField(styleableClass,"TextView_lines"); 210 final int TextView_height = getField(styleableClass,"TextView_height"); 211 final int TextView_minLines = getField(styleableClass,"TextView_minLines"); 212 final int TextView_minHeight = getField(styleableClass,"TextView_minHeight"); 213 final int TextView_maxEms = getField(styleableClass,"TextView_maxEms"); 214 final int TextView_maxWidth = getField(styleableClass,"TextView_maxWidth"); 215 final int TextView_ems = getField(styleableClass,"TextView_ems"); 216 final int TextView_width = getField(styleableClass,"TextView_width"); 217 final int TextView_minEms = getField(styleableClass,"TextView_minEms"); 218 final int TextView_minWidth = getField(styleableClass,"TextView_minWidth"); 219 final int TextView_gravity = getField(styleableClass,"TextView_gravity"); 220 final int TextView_hint = getField(styleableClass,"TextView_hint"); 221 final int TextView_text = getField(styleableClass,"TextView_text"); 222 final int TextView_scrollHorizontally = getField(styleableClass,"TextView_scrollHorizontally"); 223 final int TextView_singleLine = getField(styleableClass,"TextView_singleLine"); 224 final int TextView_ellipsize = getField(styleableClass,"TextView_ellipsize"); 225 final int TextView_marqueeRepeatLimit = getField(styleableClass,"TextView_marqueeRepeatLimit"); 226 final int TextView_includeFontPadding = getField(styleableClass,"TextView_includeFontPadding"); 227 final int TextView_cursorVisible = getField(styleableClass,"TextView_cursorVisible"); 228 final int TextView_maxLength = getField(styleableClass,"TextView_maxLength"); 229 final int TextView_textScaleX = getField(styleableClass,"TextView_textScaleX"); 230 final int TextView_freezesText = getField(styleableClass,"TextView_freezesText"); 231 final int TextView_shadowColor = getField(styleableClass,"TextView_shadowColor"); 232 final int TextView_shadowDx = getField(styleableClass,"TextView_shadowDx"); 233 final int TextView_shadowDy = getField(styleableClass,"TextView_shadowDy"); 234 final int TextView_shadowRadius = getField(styleableClass,"TextView_shadowRadius"); 235 final int TextView_enabled = getField(styleableClass,"TextView_enabled"); 236 final int TextView_textColorHighlight = getField(styleableClass,"TextView_textColorHighlight"); 237 final int TextView_textColor = getField(styleableClass,"TextView_textColor"); 238 final int TextView_textColorHint = getField(styleableClass,"TextView_textColorHint"); 239 final int TextView_textColorLink = getField(styleableClass,"TextView_textColorLink"); 240 final int TextView_textSize = getField(styleableClass,"TextView_textSize"); 241 final int TextView_typeface = getField(styleableClass,"TextView_typeface"); 242 final int TextView_textStyle = getField(styleableClass,"TextView_textStyle"); 243 final int TextView_password = getField(styleableClass,"TextView_password"); 244 final int TextView_lineSpacingExtra = getField(styleableClass,"TextView_lineSpacingExtra"); 245 final int TextView_lineSpacingMultiplier = getField(styleableClass,"TextView_lineSpacingMultiplier"); 246 final int TextView_inputType = getField(styleableClass,"TextView_inputType"); 247 final int TextView_imeOptions = getField(styleableClass,"TextView_imeOptions"); 248 final int TextView_imeActionLabel = getField(styleableClass,"TextView_imeActionLabel"); 249 final int TextView_imeActionId = getField(styleableClass,"TextView_imeActionId"); 250 final int TextView_privateImeOptions = getField(styleableClass,"TextView_privateImeOptions"); 251 final int TextView_textSelectHandleLeft = getField(styleableClass,"TextView_textSelectHandleLeft"); 252 final int TextView_textSelectHandleRight = getField(styleableClass,"TextView_textSelectHandleRight"); 253 final int TextView_textSelectHandle = getField(styleableClass,"TextView_textSelectHandle"); 254 final int TextView_textIsSelectable = getField(styleableClass,"TextView_textIsSelectable"); 255 final int TextView_textAllCaps = getField(styleableClass,"TextView_textAllCaps"); 256 257 final int ImageView_src = getField(styleableClass,"ImageView_src"); 258 final int ImageView_baselineAlignBottom = getField(styleableClass,"ImageView_baselineAlignBottom"); 259 final int ImageView_adjustViewBounds = getField(styleableClass,"ImageView_adjustViewBounds"); 260 final int ImageView_maxWidth = getField(styleableClass,"ImageView_maxWidth"); 261 final int ImageView_maxHeight = getField(styleableClass,"ImageView_maxHeight"); 262 final int ImageView_scaleType = getField(styleableClass,"ImageView_scaleType"); 263 final int ImageView_tint = getField(styleableClass,"ImageView_tint"); 264 final int ImageView_cropToPadding = getField(styleableClass,"ImageView_cropToPadding"); 265 266 final Resources.Theme m_theme; 267 final String m_extractPath; 268 Context m_context; 269 final int defaultBackgroundColor; 270 final int defaultTextColor; 271 final boolean m_minimal; 272 273 class SimpleJsonWriter 274 { 275 private OutputStreamWriter m_writer; 276 private boolean m_addComma = false; 277 private int m_indentLevel = 0; SimpleJsonWriter(String filePath)278 public SimpleJsonWriter(String filePath) throws FileNotFoundException 279 { 280 m_writer = new OutputStreamWriter(new FileOutputStream(filePath)); 281 } 282 close()283 public void close() throws IOException 284 { 285 m_writer.close(); 286 } 287 writeIndent()288 private void writeIndent() throws IOException 289 { 290 m_writer.write(" ", 0, m_indentLevel); 291 } 292 beginObject()293 SimpleJsonWriter beginObject() throws IOException 294 { 295 writeIndent(); 296 m_writer.write("{\n"); 297 ++m_indentLevel; 298 m_addComma = false; 299 return this; 300 } 301 endObject()302 SimpleJsonWriter endObject() throws IOException 303 { 304 m_writer.write("\n"); 305 writeIndent(); 306 m_writer.write("}\n"); 307 --m_indentLevel; 308 m_addComma = false; 309 return this; 310 } 311 name(String name)312 SimpleJsonWriter name(String name) throws IOException 313 { 314 if (m_addComma) { 315 m_writer.write(",\n"); 316 } 317 writeIndent(); 318 m_writer.write(JSONObject.quote(name) + ": "); 319 m_addComma = true; 320 return this; 321 } 322 value(JSONObject value)323 SimpleJsonWriter value(JSONObject value) throws IOException 324 { 325 m_writer.write(value.toString()); 326 return this; 327 } 328 } 329 330 class FakeCanvas extends Canvas { 331 int[] chunkData = null; 332 class Size { 333 public int s,e; Size(int start, int end)334 Size(int start, int end) 335 { 336 s=start; 337 e=end; 338 } 339 } 340 isHardwareAccelerated()341 public boolean isHardwareAccelerated() { 342 return true; 343 } 344 drawPatch(Bitmap bmp, byte[] chunks, RectF dst, Paint paint)345 public void drawPatch(Bitmap bmp, byte[] chunks, RectF dst, Paint paint) { 346 chunkData = extractChunkInfo20(chunks); 347 } 348 } 349 350 351 stateSetUnion(final int[] stateSet1, final int[] stateSet2)352 private int[] stateSetUnion(final int[] stateSet1, final int[] stateSet2) 353 { 354 try 355 { 356 final int stateSet1Length = stateSet1.length; 357 final int stateSet2Length = stateSet2.length; 358 final int[] newSet = new int[stateSet1Length + stateSet2Length]; 359 int k = 0; 360 int i = 0; 361 int j = 0; 362 // This is a merge of the two input state sets and assumes that the 363 // input sets are sorted by the order imposed by ViewDrawableStates. 364 int[] viewDrawableStatesState=(int[]) styleableClass.getDeclaredField("ViewDrawableStates").get(null); 365 for (int viewState : viewDrawableStatesState) 366 { 367 if (i < stateSet1Length && stateSet1[i] == viewState) 368 { 369 newSet[k++] = viewState; 370 i++; 371 } else if (j < stateSet2Length && stateSet2[j] == viewState) { 372 newSet[k++] = viewState; 373 j++; 374 } 375 if (k > 1) { 376 assert(newSet[k - 1] > newSet[k - 2]); 377 } 378 } 379 return newSet; 380 } 381 catch(Exception e) 382 { 383 e.printStackTrace(); 384 } 385 return null; 386 } 387 getClass(String className)388 private Class<?> getClass(String className) { 389 try { 390 return Class.forName(className); 391 } catch (ClassNotFoundException e) { 392 e.printStackTrace(); 393 } 394 return null; 395 } 396 getAccessibleField(Class<?> clazz, String fieldName)397 Field getAccessibleField(Class<?> clazz, String fieldName) { 398 try { 399 Field f = clazz.getDeclaredField(fieldName); 400 f.setAccessible(true); 401 return f; 402 } catch (Exception e) { 403 e.printStackTrace(); 404 } 405 return null; 406 } 407 tryGetAccessibleField(Class<?> clazz, String fieldName)408 Field tryGetAccessibleField(Class<?> clazz, String fieldName) { 409 if (clazz == null) 410 return null; 411 412 try { 413 Field f = clazz.getDeclaredField(fieldName); 414 f.setAccessible(true); 415 return f; 416 } catch (Exception e) { 417 for (Class<?> c : clazz.getInterfaces()) { 418 Field f = tryGetAccessibleField(c, fieldName); 419 if (f != null) 420 return f; 421 } 422 } 423 return tryGetAccessibleField(clazz.getSuperclass(), fieldName); 424 } 425 getField(Class<?> clazz, String fieldName)426 int getField(Class<?> clazz, String fieldName) 427 { 428 try { 429 return clazz.getDeclaredField(fieldName).getInt(null); 430 } catch (Exception e) { 431 e.printStackTrace(); 432 } 433 return -1; 434 } 435 getColorStateList(ColorStateList colorList)436 JSONObject getColorStateList(ColorStateList colorList) 437 { 438 JSONObject json = new JSONObject(); 439 try 440 { 441 json.put("EMPTY_STATE_SET", colorList.getColorForState(EMPTY_STATE_SET, 0)); 442 json.put("WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(WINDOW_FOCUSED_STATE_SET, 0)); 443 json.put("SELECTED_STATE_SET", colorList.getColorForState(SELECTED_STATE_SET, 0)); 444 json.put("SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); 445 json.put("FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_STATE_SET, 0)); 446 json.put("FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_WINDOW_FOCUSED_STATE_SET, 0)); 447 json.put("FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_STATE_SET, 0)); 448 json.put("FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); 449 json.put("ENABLED_STATE_SET", colorList.getColorForState(ENABLED_STATE_SET, 0)); 450 json.put("ENABLED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_WINDOW_FOCUSED_STATE_SET, 0)); 451 json.put("ENABLED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_STATE_SET, 0)); 452 json.put("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); 453 json.put("ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_STATE_SET, 0)); 454 json.put("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0)); 455 json.put("ENABLED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_SELECTED_STATE_SET, 0)); 456 json.put("ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); 457 json.put("PRESSED_STATE_SET", colorList.getColorForState(PRESSED_STATE_SET, 0)); 458 json.put("PRESSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_WINDOW_FOCUSED_STATE_SET, 0)); 459 json.put("PRESSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_STATE_SET, 0)); 460 json.put("PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); 461 json.put("PRESSED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_STATE_SET, 0)); 462 json.put("PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0)); 463 json.put("PRESSED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_SELECTED_STATE_SET, 0)); 464 json.put("PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); 465 json.put("PRESSED_ENABLED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_STATE_SET, 0)); 466 json.put("PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET, 0)); 467 json.put("PRESSED_ENABLED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_SELECTED_STATE_SET, 0)); 468 json.put("PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); 469 json.put("PRESSED_ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_STATE_SET, 0)); 470 json.put("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0)); 471 json.put("PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, 0)); 472 json.put("PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); 473 } catch (JSONException e) { 474 e.printStackTrace(); 475 } 476 477 return json; 478 } 479 480 final int [] DrawableStates ={android.R.attr.state_active, android.R.attr.state_checked 481 , android.R.attr.state_enabled, android.R.attr.state_focused 482 , android.R.attr.state_pressed, android.R.attr.state_selected 483 , android.R.attr.state_window_focused, 16908288, 16843597, 16843518, 16843547}; 484 final String[] DrawableStatesLabels = {"active", "checked", "enabled", "focused", "pressed", "selected", "window_focused", "background", "multiline", "activated", "accelerated"}; 485 final String[] DisableDrawableStatesLabels = {"inactive", "unchecked", "disabled", "not_focused", "no_pressed", "unselected", "window_not_focused", "background", "multiline", "activated", "accelerated"}; 486 getFileName(String file, String[] states)487 String getFileName(String file, String[] states) 488 { 489 for (String state: states) 490 file+="__"+state; 491 return file; 492 } 493 getStatesName(String[] states)494 String getStatesName(String[] states) 495 { 496 String statesName=""; 497 for (String state: states) 498 { 499 if (statesName.length()>0) 500 statesName+="__"; 501 statesName += state; 502 } 503 return statesName; 504 } 505 addDrawableItemIfNotExists(JSONObject json, ArrayList<Integer> list, Drawable item, String[] states, String filename)506 void addDrawableItemIfNotExists(JSONObject json, ArrayList<Integer> list, Drawable item, String[] states, String filename) 507 { 508 for (Integer it : list) 509 { 510 if (it.equals(item.hashCode())) 511 return; 512 } 513 list.add(item.hashCode()); 514 try { 515 json.put(getStatesName(states), getDrawable(item, getFileName(filename, states), null)); 516 } catch (JSONException e) { 517 e.printStackTrace(); 518 } 519 } 520 addSolution(String filename, JSONObject json, int c, Drawable drawable, ArrayList<Integer> drawableList, int u)521 void addSolution(String filename, JSONObject json, int c, Drawable drawable, ArrayList<Integer> drawableList, int u) 522 { 523 int pos=0; 524 int states[] = new int[c]; 525 String [] statesText = new String[c]; 526 527 for (int n= 0;u > 0;++n, u>>= 1) 528 if ((u & 1) > 0) 529 { 530 statesText[pos]=DrawableStatesLabels[n]; 531 states[pos++]=DrawableStates[n]; 532 } 533 drawable.setState(states); 534 addDrawableItemIfNotExists(json, drawableList, drawable.getCurrent(), statesText, filename); 535 } 536 bitCount(int u)537 int bitCount(int u) 538 { 539 int n; 540 for (n= 0;u > 0;++n, u&= (u - 1)); 541 return n; 542 } 543 getStatesList(int [] states)544 JSONObject getStatesList(int [] states) throws JSONException 545 { 546 JSONObject json = new JSONObject(); 547 for (int s : states) 548 { 549 boolean found=false; 550 for (int d = 0;d<DrawableStates.length;d++) 551 { 552 if (s==DrawableStates[d]) 553 { 554 json.put(DrawableStatesLabels[d], true); 555 found=true; 556 break; 557 } 558 else if (s==-DrawableStates[d]) 559 { 560 json.put(DrawableStatesLabels[d], false); 561 562 found=true; 563 break; 564 } 565 } 566 if (!found) 567 { 568 json.put("unhandled_state_"+s,s>0); 569 } 570 } 571 return json; 572 } 573 getStatesName(int [] states)574 String getStatesName(int [] states) 575 { 576 String statesName=""; 577 for (int s : states) 578 { 579 boolean found=false; 580 for (int d = 0;d<DrawableStates.length;d++) 581 { 582 if (s==DrawableStates[d]) 583 { 584 if (statesName.length()>0) 585 statesName+="__"; 586 statesName+=DrawableStatesLabels[d]; 587 found=true; 588 break; 589 } 590 else if (s==-DrawableStates[d]) 591 { 592 if (statesName.length()>0) 593 statesName+="__"; 594 statesName+=DisableDrawableStatesLabels[d]; 595 found=true; 596 break; 597 } 598 } 599 if (!found) 600 { 601 if (statesName.length()>0) 602 statesName+=";"; 603 statesName+=s; 604 } 605 } 606 if (statesName.length()>0) 607 return statesName; 608 return "empty"; 609 } 610 getLayerDrawable(Object drawable, String filename)611 private JSONObject getLayerDrawable(Object drawable, String filename) 612 { 613 JSONObject json = new JSONObject(); 614 LayerDrawable layers = (LayerDrawable) drawable; 615 final int nr=layers.getNumberOfLayers(); 616 try { 617 JSONArray array =new JSONArray(); 618 for (int i = 0; i < nr; i++) 619 { 620 int id = layers.getId(i); 621 if (id == -1) 622 id = i; 623 JSONObject layerJsonObject=getDrawable(layers.getDrawable(i), filename+"__"+id, null); 624 layerJsonObject.put("id", id); 625 array.put(layerJsonObject); 626 } 627 json.put("type", "layer"); 628 Rect padding = new Rect(); 629 if (layers.getPadding(padding)) 630 json.put("padding", getJsonRect(padding)); 631 json.put("layers", array); 632 } catch (JSONException e) { 633 e.printStackTrace(); 634 } 635 return json; 636 } 637 getStateListDrawable(Object drawable, String filename)638 private JSONObject getStateListDrawable(Object drawable, String filename) 639 { 640 JSONObject json = new JSONObject(); 641 try { 642 StateListDrawable stateList = (StateListDrawable) drawable; 643 final int numStates = (Integer) StateListDrawable.class.getMethod("getStateCount").invoke(stateList); 644 JSONArray array =new JSONArray(); 645 for (int i = 0; i < numStates; i++) 646 { 647 JSONObject stateJson = new JSONObject(); 648 final Drawable d = (Drawable) StateListDrawable.class.getMethod("getStateDrawable", Integer.TYPE).invoke(stateList, i); 649 final int [] states = (int[]) StateListDrawable.class.getMethod("getStateSet", Integer.TYPE).invoke(stateList, i); 650 if (states != null) 651 stateJson.put("states", getStatesList(states)); 652 stateJson.put("drawable", getDrawable(d, filename+"__" + (states != null ? getStatesName(states) : ("state_pos_" + i)), null)); 653 array.put(stateJson); 654 } 655 json.put("type", "stateslist"); 656 Rect padding = new Rect(); 657 if (stateList.getPadding(padding)) 658 json.put("padding", getJsonRect(padding)); 659 json.put("stateslist", array); 660 } catch (Exception e) { 661 e.printStackTrace(); 662 } 663 return json; 664 } 665 getGradientDrawable(GradientDrawable drawable)666 private JSONObject getGradientDrawable(GradientDrawable drawable) { 667 JSONObject json = new JSONObject(); 668 try { 669 json.put("type", "gradient"); 670 Object obj=drawable.getConstantState(); 671 Class<?> gradientStateClass=obj.getClass(); 672 json.put("shape",gradientStateClass.getField("mShape").getInt(obj)); 673 json.put("gradient",gradientStateClass.getField("mGradient").getInt(obj)); 674 GradientDrawable.Orientation orientation=(Orientation) gradientStateClass.getField("mOrientation").get(obj); 675 json.put("orientation",orientation.name()); 676 int [] intArray=(int[]) gradientStateClass.getField((Build.VERSION.SDK_INT < 23) ? "mColors" : "mGradientColors").get(obj); 677 if (intArray != null) 678 json.put("colors",getJsonArray(intArray, 0, intArray.length)); 679 json.put("positions",getJsonArray((float[]) gradientStateClass.getField("mPositions").get(obj))); 680 json.put("strokeWidth",gradientStateClass.getField("mStrokeWidth").getInt(obj)); 681 json.put("strokeDashWidth",gradientStateClass.getField("mStrokeDashWidth").getFloat(obj)); 682 json.put("strokeDashGap",gradientStateClass.getField("mStrokeDashGap").getFloat(obj)); 683 json.put("radius",gradientStateClass.getField("mRadius").getFloat(obj)); 684 float [] floatArray=(float[]) gradientStateClass.getField("mRadiusArray").get(obj); 685 if (floatArray!=null) 686 json.put("radiusArray",getJsonArray(floatArray)); 687 Rect rc= (Rect) gradientStateClass.getField("mPadding").get(obj); 688 if (rc!=null) 689 json.put("padding",getJsonRect(rc)); 690 json.put("width",gradientStateClass.getField("mWidth").getInt(obj)); 691 json.put("height",gradientStateClass.getField("mHeight").getInt(obj)); 692 json.put("innerRadiusRatio",gradientStateClass.getField("mInnerRadiusRatio").getFloat(obj)); 693 json.put("thicknessRatio",gradientStateClass.getField("mThicknessRatio").getFloat(obj)); 694 json.put("innerRadius",gradientStateClass.getField("mInnerRadius").getInt(obj)); 695 json.put("thickness",gradientStateClass.getField("mThickness").getInt(obj)); 696 } catch (Exception e) { 697 e.printStackTrace(); 698 } 699 return json; 700 } 701 getRotateDrawable(RotateDrawable drawable, String filename)702 private JSONObject getRotateDrawable(RotateDrawable drawable, String filename) { 703 JSONObject json = new JSONObject(); 704 try { 705 json.put("type", "rotate"); 706 Object obj = drawable.getConstantState(); 707 Class<?> rotateStateClass = obj.getClass(); 708 if (Build.VERSION.SDK_INT < 23) 709 json.put("drawable", getDrawable(getAccessibleField(rotateStateClass, "mDrawable").get(obj), filename, null)); 710 else 711 json.put("drawable", getDrawable(drawable.getClass().getMethod("getDrawable").invoke(drawable), filename, null)); 712 json.put("pivotX", getAccessibleField(rotateStateClass, "mPivotX").getFloat(obj)); 713 json.put("pivotXRel", getAccessibleField(rotateStateClass, "mPivotXRel").getBoolean(obj)); 714 json.put("pivotY", getAccessibleField(rotateStateClass, "mPivotY").getFloat(obj)); 715 json.put("pivotYRel", getAccessibleField(rotateStateClass, "mPivotYRel").getBoolean(obj)); 716 json.put("fromDegrees", getAccessibleField(rotateStateClass, "mFromDegrees").getFloat(obj)); 717 json.put("toDegrees", getAccessibleField(rotateStateClass, "mToDegrees").getFloat(obj)); 718 } catch (Exception e) { 719 e.printStackTrace(); 720 } 721 return json; 722 } 723 getAnimationDrawable(AnimationDrawable drawable, String filename)724 private JSONObject getAnimationDrawable(AnimationDrawable drawable, String filename) { 725 JSONObject json = new JSONObject(); 726 try { 727 json.put("type", "animation"); 728 json.put("oneshot", drawable.isOneShot()); 729 final int count = drawable.getNumberOfFrames(); 730 JSONArray frames = new JSONArray(); 731 for (int i = 0; i < count; ++i) 732 { 733 JSONObject frame = new JSONObject(); 734 frame.put("duration", drawable.getDuration(i)); 735 frame.put("drawable", getDrawable(drawable.getFrame(i), filename+"__"+i, null)); 736 frames.put(frame); 737 } 738 json.put("frames", frames); 739 } catch (Exception e) { 740 e.printStackTrace(); 741 } 742 return json; 743 } 744 getJsonRect(Rect rect)745 private JSONObject getJsonRect(Rect rect) throws JSONException 746 { 747 JSONObject jsonRect = new JSONObject(); 748 jsonRect.put("left", rect.left); 749 jsonRect.put("top", rect.top); 750 jsonRect.put("right", rect.right); 751 jsonRect.put("bottom", rect.bottom); 752 return jsonRect; 753 754 } 755 getJsonArray(int[] array, int pos, int len)756 private JSONArray getJsonArray(int[] array, int pos, int len) 757 { 758 JSONArray a = new JSONArray(); 759 final int l = pos+len; 760 for (int i=pos; i<l;i++) 761 a.put(array[i]); 762 return a; 763 } 764 getJsonArray(float[] array)765 private JSONArray getJsonArray(float[] array) throws JSONException 766 { 767 JSONArray a = new JSONArray(); 768 if (array != null) 769 for (float val: array) 770 a.put(val); 771 return a; 772 } 773 getJsonChunkInfo(int[] chunkData)774 private JSONObject getJsonChunkInfo(int[] chunkData) throws JSONException 775 { 776 JSONObject jsonRect = new JSONObject(); 777 if (chunkData == null) 778 return jsonRect; 779 780 jsonRect.put("xdivs", getJsonArray(chunkData, 3, chunkData[0])); 781 jsonRect.put("ydivs", getJsonArray(chunkData, 3 + chunkData[0], chunkData[1])); 782 jsonRect.put("colors", getJsonArray(chunkData, 3 + chunkData[0] + chunkData[1], chunkData[2])); 783 return jsonRect; 784 } 785 findPatchesMarings(Drawable d)786 private JSONObject findPatchesMarings(Drawable d) throws JSONException, NoSuchFieldException, IllegalAccessException 787 { 788 NinePatch np; 789 Field f = tryGetAccessibleField(NinePatchDrawable.class, "mNinePatch"); 790 if (f != null) { 791 np = (NinePatch) f.get(d); 792 } else { 793 Object state = getAccessibleField(NinePatchDrawable.class, "mNinePatchState").get(d); 794 np = (NinePatch) getAccessibleField(state.getClass(), "mNinePatch").get(state); 795 } 796 return getJsonChunkInfo(extractNativeChunkInfo20(getAccessibleField(np.getClass(), "mNativeChunk").getLong(np))); 797 } 798 799 class DrawableCache 800 { DrawableCache(JSONObject json, Object drawable)801 public DrawableCache(JSONObject json, Object drawable) 802 { 803 object = json; 804 this.drawable = drawable; 805 } 806 JSONObject object; 807 Object drawable; 808 } 809 private HashMap<String, DrawableCache> m_drawableCache = new HashMap<String, DrawableCache>(); 810 getRippleDrawable(Object drawable, String filename, Rect padding)811 private JSONObject getRippleDrawable(Object drawable, String filename, Rect padding) 812 { 813 JSONObject json = getLayerDrawable(drawable, filename); 814 JSONObject ripple = new JSONObject(); 815 try { 816 final Object mState = getAccessibleField(rippleDrawableClass, "mState").get(drawable); 817 ripple.put("mask", getDrawable((Drawable)getAccessibleField(rippleDrawableClass, "mMask").get(drawable), filename, padding)); 818 ripple.put("maxRadius", getAccessibleField(mState.getClass(), "mMaxRadius").getInt(mState)); 819 ripple.put("color", getColorStateList((ColorStateList)getAccessibleField(mState.getClass(), "mColor").get(mState))); 820 json.put("ripple", ripple); 821 } catch (Exception e) { 822 e.printStackTrace(); 823 } 824 return json; 825 } 826 getStateTransitions(Object sa)827 private HashMap<Long, Long> getStateTransitions(Object sa) throws Exception 828 { 829 HashMap<Long, Long> transitions = new HashMap<Long, Long>(); 830 final int sz = getAccessibleField(sa.getClass(), "mSize").getInt(sa); 831 long[] keys = (long[]) getAccessibleField(sa.getClass(), "mKeys").get(sa); 832 long[] values = (long[]) getAccessibleField(sa.getClass(), "mValues").get(sa); 833 for (int i = 0; i < sz; i++) { 834 transitions.put(keys[i], values[i]); 835 } 836 return transitions; 837 } 838 getStateIds(Object sa)839 private HashMap<Integer, Integer> getStateIds(Object sa) throws Exception 840 { 841 HashMap<Integer, Integer> states = new HashMap<Integer, Integer>(); 842 final int sz = getAccessibleField(sa.getClass(), "mSize").getInt(sa); 843 int[] keys = (int[]) getAccessibleField(sa.getClass(), "mKeys").get(sa); 844 int[] values = (int[]) getAccessibleField(sa.getClass(), "mValues").get(sa); 845 for (int i = 0; i < sz; i++) { 846 states.put(keys[i], values[i]); 847 } 848 return states; 849 } 850 findStateIndex(int id, HashMap<Integer, Integer> stateIds)851 private int findStateIndex(int id, HashMap<Integer, Integer> stateIds) 852 { 853 for (Map.Entry<Integer, Integer> s : stateIds.entrySet()) { 854 if (id == s.getValue()) 855 return s.getKey(); 856 } 857 return -1; 858 } 859 getAnimatedStateListDrawable(Object drawable, String filename)860 private JSONObject getAnimatedStateListDrawable(Object drawable, String filename) 861 { 862 JSONObject json = getStateListDrawable(drawable, filename); 863 try { 864 Object state = getAccessibleField(animatedStateListDrawableClass, "mState").get(drawable); 865 866 HashMap<Integer, Integer> stateIds = getStateIds(getAccessibleField(state.getClass(), "mStateIds").get(state)); 867 HashMap<Long, Long> transitions = getStateTransitions(getAccessibleField(state.getClass(), "mTransitions").get(state)); 868 869 for (Map.Entry<Long, Long> t : transitions.entrySet()) { 870 final int toState = findStateIndex(t.getKey().intValue(), stateIds); 871 final int fromState = findStateIndex((int) (t.getKey() >> 32), stateIds); 872 873 JSONObject transition = new JSONObject(); 874 transition.put("from", fromState); 875 transition.put("to", toState); 876 transition.put("reverse", (t.getValue() >> 32) != 0); 877 878 JSONArray stateslist = json.getJSONArray("stateslist"); 879 JSONObject stateobj = stateslist.getJSONObject(t.getValue().intValue()); 880 stateobj.put("transition", transition); 881 } 882 } catch (Exception e) { 883 e.printStackTrace(); 884 } 885 return json; 886 } 887 getVPath(Object path)888 private JSONObject getVPath(Object path) throws Exception 889 { 890 JSONObject json = new JSONObject(); 891 final Class<?> pathClass = path.getClass(); 892 json.put("type", "path"); 893 json.put("name", tryGetAccessibleField(pathClass, "mPathName").get(path)); 894 Object[] mNodes = (Object[]) tryGetAccessibleField(pathClass, "mNodes").get(path); 895 JSONArray nodes = new JSONArray(); 896 for (Object n: mNodes) { 897 JSONObject node = new JSONObject(); 898 node.put("type", String.valueOf(getAccessibleField(n.getClass(), "mType").getChar(n))); 899 node.put("params", getJsonArray((float[])getAccessibleField(n.getClass(), "mParams").get(n))); 900 nodes.put(node); 901 } 902 json.put("nodes", nodes); 903 json.put("isClip", (Boolean) pathClass.getMethod("isClipPath").invoke(path)); 904 905 if (tryGetAccessibleField(pathClass, "mStrokeColor") == null) 906 return json; // not VFullPath 907 908 json.put("strokeColor", getAccessibleField(pathClass, "mStrokeColor").getInt(path)); 909 json.put("strokeWidth", getAccessibleField(pathClass, "mStrokeWidth").getFloat(path)); 910 json.put("fillColor", getAccessibleField(pathClass, "mFillColor").getInt(path)); 911 json.put("strokeAlpha", getAccessibleField(pathClass, "mStrokeAlpha").getFloat(path)); 912 json.put("fillRule", getAccessibleField(pathClass, "mFillRule").getInt(path)); 913 json.put("fillAlpha", getAccessibleField(pathClass, "mFillAlpha").getFloat(path)); 914 json.put("trimPathStart", getAccessibleField(pathClass, "mTrimPathStart").getFloat(path)); 915 json.put("trimPathEnd", getAccessibleField(pathClass, "mTrimPathEnd").getFloat(path)); 916 json.put("trimPathOffset", getAccessibleField(pathClass, "mTrimPathOffset").getFloat(path)); 917 json.put("strokeLineCap", (Paint.Cap) getAccessibleField(pathClass, "mStrokeLineCap").get(path)); 918 json.put("strokeLineJoin", (Paint.Join) getAccessibleField(pathClass, "mStrokeLineJoin").get(path)); 919 json.put("strokeMiterlimit", getAccessibleField(pathClass, "mStrokeMiterlimit").getFloat(path)); 920 return json; 921 } 922 923 @SuppressWarnings("unchecked") getVGroup(Object group)924 private JSONObject getVGroup(Object group) throws Exception 925 { 926 JSONObject json = new JSONObject(); 927 json.put("type", "group"); 928 final Class<?> groupClass = group.getClass(); 929 json.put("name", getAccessibleField(groupClass, "mGroupName").get(group)); 930 json.put("rotate", getAccessibleField(groupClass, "mRotate").getFloat(group)); 931 json.put("pivotX", getAccessibleField(groupClass, "mPivotX").getFloat(group)); 932 json.put("pivotY", getAccessibleField(groupClass, "mPivotY").getFloat(group)); 933 json.put("scaleX", getAccessibleField(groupClass, "mScaleX").getFloat(group)); 934 json.put("scaleY", getAccessibleField(groupClass, "mScaleY").getFloat(group)); 935 json.put("translateX", getAccessibleField(groupClass, "mTranslateX").getFloat(group)); 936 json.put("translateY", getAccessibleField(groupClass, "mTranslateY").getFloat(group)); 937 938 ArrayList<Object> mChildren = (ArrayList<Object>) getAccessibleField(groupClass, "mChildren").get(group); 939 JSONArray children = new JSONArray(); 940 for (Object c: mChildren) { 941 if (groupClass.isInstance(c)) 942 children.put(getVGroup(c)); 943 else 944 children.put(getVPath(c)); 945 } 946 json.put("children", children); 947 return json; 948 } 949 getVectorDrawable(Object drawable, String filename, Rect padding)950 private JSONObject getVectorDrawable(Object drawable, String filename, Rect padding) 951 { 952 JSONObject json = new JSONObject(); 953 try { 954 json.put("type", "vector"); 955 final Object state = getAccessibleField(vectorDrawableClass, "mVectorState").get(drawable); 956 final Class<?> stateClass = state.getClass(); 957 final ColorStateList mTint = (ColorStateList) getAccessibleField(stateClass, "mTint").get(state); 958 if (mTint != null) { 959 json.put("tintList", getColorStateList(mTint)); 960 json.put("tintMode", (PorterDuff.Mode) getAccessibleField(stateClass, "mTintMode").get(state)); 961 } 962 final Object mVPathRenderer = getAccessibleField(stateClass, "mVPathRenderer").get(state); 963 final Class<?> VPathRendererClass = mVPathRenderer.getClass(); 964 json.put("baseWidth", getAccessibleField(VPathRendererClass, "mBaseWidth").getFloat(mVPathRenderer)); 965 json.put("baseHeight", getAccessibleField(VPathRendererClass, "mBaseHeight").getFloat(mVPathRenderer)); 966 json.put("viewportWidth", getAccessibleField(VPathRendererClass, "mViewportWidth").getFloat(mVPathRenderer)); 967 json.put("viewportHeight", getAccessibleField(VPathRendererClass, "mViewportHeight").getFloat(mVPathRenderer)); 968 json.put("rootAlpha", getAccessibleField(VPathRendererClass, "mRootAlpha").getInt(mVPathRenderer)); 969 json.put("rootName", getAccessibleField(VPathRendererClass, "mRootName").get(mVPathRenderer)); 970 json.put("rootGroup", getVGroup(getAccessibleField(mVPathRenderer.getClass(), "mRootGroup").get(mVPathRenderer))); 971 } catch(Exception e) { 972 e.printStackTrace(); 973 } 974 return json; 975 } 976 getDrawable(Object drawable, String filename, Rect padding)977 public JSONObject getDrawable(Object drawable, String filename, Rect padding) 978 { 979 if (drawable == null || m_minimal) 980 return null; 981 982 DrawableCache dc = m_drawableCache.get(filename); 983 if (dc != null) 984 { 985 if (dc.drawable.equals(drawable)) 986 return dc.object; 987 else 988 Log.e(QtNative.QtTAG, "Different drawable objects points to the same file name \"" + filename +"\""); 989 } 990 JSONObject json = new JSONObject(); 991 Bitmap bmp = null; 992 if (drawable instanceof Bitmap) 993 bmp = (Bitmap) drawable; 994 else 995 { 996 if (drawable instanceof BitmapDrawable) { 997 BitmapDrawable bitmapDrawable = (BitmapDrawable)drawable; 998 bmp = bitmapDrawable.getBitmap(); 999 try { 1000 json.put("gravity", bitmapDrawable.getGravity()); 1001 json.put("tileModeX", bitmapDrawable.getTileModeX()); 1002 json.put("tileModeY", bitmapDrawable.getTileModeY()); 1003 json.put("antialias", (Boolean) BitmapDrawable.class.getMethod("hasAntiAlias").invoke(bitmapDrawable)); 1004 json.put("mipMap", (Boolean) BitmapDrawable.class.getMethod("hasMipMap").invoke(bitmapDrawable)); 1005 json.put("tintMode", (PorterDuff.Mode) BitmapDrawable.class.getMethod("getTintMode").invoke(bitmapDrawable)); 1006 ColorStateList tintList = (ColorStateList) BitmapDrawable.class.getMethod("getTint").invoke(bitmapDrawable); 1007 if (tintList != null) 1008 json.put("tintList", getColorStateList(tintList)); 1009 } catch (Exception e) { 1010 e.printStackTrace(); 1011 } 1012 } 1013 else 1014 { 1015 1016 if (rippleDrawableClass != null && rippleDrawableClass.isInstance(drawable)) 1017 return getRippleDrawable(drawable, filename, padding); 1018 1019 if (animatedStateListDrawableClass != null && animatedStateListDrawableClass.isInstance(drawable)) 1020 return getAnimatedStateListDrawable(drawable, filename); 1021 1022 if (vectorDrawableClass != null && vectorDrawableClass.isInstance(drawable)) 1023 return getVectorDrawable(drawable, filename, padding); 1024 1025 if (drawable instanceof ScaleDrawable) 1026 { 1027 return getDrawable(((ScaleDrawable)drawable).getDrawable(), filename, null); 1028 } 1029 if (drawable instanceof LayerDrawable) 1030 { 1031 return getLayerDrawable(drawable, filename); 1032 } 1033 if (drawable instanceof StateListDrawable) 1034 { 1035 return getStateListDrawable(drawable, filename); 1036 } 1037 if (drawable instanceof GradientDrawable) 1038 { 1039 return getGradientDrawable((GradientDrawable) drawable); 1040 } 1041 if (drawable instanceof RotateDrawable) 1042 { 1043 return getRotateDrawable((RotateDrawable) drawable, filename); 1044 } 1045 if (drawable instanceof AnimationDrawable) 1046 { 1047 return getAnimationDrawable((AnimationDrawable) drawable, filename); 1048 } 1049 if (drawable instanceof ClipDrawable) 1050 { 1051 try { 1052 json.put("type", "clipDrawable"); 1053 Drawable.ConstantState dcs = ((ClipDrawable)drawable).getConstantState(); 1054 json.put("drawable", getDrawable(getAccessibleField(dcs.getClass(), "mDrawable").get(dcs), filename, null)); 1055 if (null != padding) 1056 json.put("padding", getJsonRect(padding)); 1057 else { 1058 Rect _padding = new Rect(); 1059 if (((Drawable) drawable).getPadding(_padding)) 1060 json.put("padding", getJsonRect(_padding)); 1061 } 1062 } catch (Exception e) { 1063 e.printStackTrace(); 1064 } 1065 return json; 1066 } 1067 if (drawable instanceof ColorDrawable) 1068 { 1069 bmp = Bitmap.createBitmap(1, 1, Config.ARGB_8888); 1070 Drawable d = (Drawable) drawable; 1071 d.setBounds(0, 0, 1, 1); 1072 d.draw(new Canvas(bmp)); 1073 try { 1074 json.put("type", "color"); 1075 json.put("color", bmp.getPixel(0, 0)); 1076 if (null != padding) 1077 json.put("padding", getJsonRect(padding)); 1078 else { 1079 Rect _padding = new Rect(); 1080 if (d.getPadding(_padding)) 1081 json.put("padding", getJsonRect(_padding)); 1082 } 1083 } catch (JSONException e) { 1084 e.printStackTrace(); 1085 } 1086 return json; 1087 } 1088 if (drawable instanceof InsetDrawable) 1089 { 1090 try { 1091 InsetDrawable d = (InsetDrawable)drawable; 1092 // mInsetState changed to mState in Android 5.1 (22) 1093 Object mInsetStateObject = getAccessibleField(InsetDrawable.class, (Build.VERSION.SDK_INT > 21) ? "mState" 1094 : "mInsetState").get(d); 1095 Rect _padding = new Rect(); 1096 boolean hasPadding = d.getPadding(_padding); 1097 return getDrawable(getAccessibleField(mInsetStateObject.getClass(), "mDrawable").get(mInsetStateObject), filename, hasPadding ? _padding : null); 1098 } catch (Exception e) { 1099 e.printStackTrace(); 1100 } 1101 } 1102 else 1103 { 1104 Drawable d = (Drawable) drawable; 1105 int w=d.getIntrinsicWidth(); 1106 int h=d.getIntrinsicHeight(); 1107 d.setLevel(10000); 1108 if (w<1 || h< 1) 1109 { 1110 w=100; 1111 h=100; 1112 } 1113 bmp = Bitmap.createBitmap(w, h, Config.ARGB_8888); 1114 d.setBounds(0, 0, w, h); 1115 d.draw(new Canvas(bmp)); 1116 if (drawable instanceof NinePatchDrawable) 1117 { 1118 NinePatchDrawable npd = (NinePatchDrawable) drawable; 1119 try { 1120 json.put("type", "9patch"); 1121 json.put("drawable", getDrawable(bmp, filename, null)); 1122 if (padding != null) 1123 json.put("padding", getJsonRect(padding)); 1124 else { 1125 Rect _padding = new Rect(); 1126 if (npd.getPadding(_padding)) 1127 json.put("padding", getJsonRect(_padding)); 1128 } 1129 1130 json.put("chunkInfo", findPatchesMarings(d)); 1131 return json; 1132 } catch (Exception e) { 1133 e.printStackTrace(); 1134 } 1135 } 1136 } 1137 } 1138 } 1139 FileOutputStream out; 1140 try { 1141 filename = m_extractPath+filename+".png"; 1142 out = new FileOutputStream(filename); 1143 bmp.compress(Bitmap.CompressFormat.PNG, 100, out); 1144 out.close(); 1145 } catch (FileNotFoundException e) { 1146 e.printStackTrace(); 1147 } catch (IOException e) { 1148 e.printStackTrace(); 1149 } 1150 try { 1151 json.put("type", "image"); 1152 json.put("path", filename); 1153 json.put("width", bmp.getWidth()); 1154 json.put("height", bmp.getHeight()); 1155 m_drawableCache.put(filename, new DrawableCache(json, drawable)); 1156 // MinistroActivity.nativeChmode(filename, 0644); 1157 } catch (JSONException e) { 1158 e.printStackTrace(); 1159 } 1160 return json; 1161 } 1162 extractViewInformations(String styleName, int styleId, JSONObject json, String qtClassName, AttributeSet attribSet)1163 public void extractViewInformations(String styleName, int styleId, JSONObject json, String qtClassName, AttributeSet attribSet) 1164 { 1165 try { 1166 int[] viewAttrs; 1167 viewAttrs = (int[]) styleableClass.getDeclaredField("View").get(null); 1168 TypedArray a =m_theme.obtainStyledAttributes(attribSet, viewAttrs, styleId, 0); 1169 1170 if (null != qtClassName) 1171 json.put("qtClass", qtClassName); 1172 json.put("defaultBackgroundColor", defaultBackgroundColor); 1173 json.put("defaultTextColorPrimary", defaultTextColor); 1174 final int N = a.getIndexCount(); 1175 for (int i = 0; i < N; i++) { 1176 int attr = a.getIndex(i); 1177 if (attr == View_background) 1178 json.put("View_background", getDrawable(a.getDrawable(attr), styleName + "_View_background", null)); 1179 else if (attr == View_padding) 1180 json.put("View_padding", a.getDimensionPixelSize(attr, -1)); 1181 else if (attr == View_paddingLeft) 1182 json.put("View_paddingLeft", a.getDimensionPixelSize(attr, -1)); 1183 else if (attr == View_paddingTop) 1184 json.put("View_paddingTop", a.getDimensionPixelSize(attr, -1)); 1185 else if (attr == View_paddingRight) 1186 json.put("View_paddingRight", a.getDimensionPixelSize(attr, -1)); 1187 else if (attr == View_paddingBottom) 1188 json.put("View_paddingBottom", a.getDimensionPixelSize(attr, -1)); 1189 else if (attr == View_scrollX) 1190 json.put("View_paddingBottom", a.getDimensionPixelOffset(attr, 0)); 1191 else if (attr == View_scrollY) 1192 json.put("View_scrollY", a.getDimensionPixelOffset(attr, 0)); 1193 else if (attr == View_id) 1194 json.put("View_id", a.getResourceId(attr, -1)); 1195 else if (attr == View_tag) 1196 json.put("View_tag", a.getText(attr)); 1197 else if (attr == View_fitsSystemWindows) 1198 json.put("View_fitsSystemWindows", a.getBoolean(attr, false)); 1199 else if (attr == View_focusable) 1200 json.put("View_focusable", a.getBoolean(attr, false)); 1201 else if (attr == View_focusableInTouchMode) 1202 json.put("View_focusableInTouchMode", a.getBoolean(attr, false)); 1203 else if (attr == View_clickable) 1204 json.put("View_clickable", a.getBoolean(attr, false)); 1205 else if (attr == View_longClickable) 1206 json.put("View_longClickable", a.getBoolean(attr, false)); 1207 else if (attr == View_saveEnabled) 1208 json.put("View_saveEnabled", a.getBoolean(attr, true)); 1209 else if (attr == View_duplicateParentState) 1210 json.put("View_duplicateParentState", a.getBoolean(attr, false)); 1211 else if (attr == View_visibility) 1212 json.put("View_visibility", a.getInt(attr, 0)); 1213 else if (attr == View_drawingCacheQuality) 1214 json.put("View_drawingCacheQuality", a.getInt(attr, 0)); 1215 else if (attr == View_drawingCacheQuality) 1216 json.put("View_contentDescription", a.getString(attr)); 1217 else if (attr == View_soundEffectsEnabled) 1218 json.put("View_soundEffectsEnabled", a.getBoolean(attr, true)); 1219 else if (attr == View_hapticFeedbackEnabled) 1220 json.put("View_hapticFeedbackEnabled", a.getBoolean(attr, true)); 1221 else if (attr == View_scrollbars) 1222 json.put("View_scrollbars", a.getInt(attr, 0)); 1223 else if (attr == View_fadingEdge) 1224 json.put("View_fadingEdge", a.getInt(attr, 0)); 1225 else if (attr == View_scrollbarStyle) 1226 json.put("View_scrollbarStyle", a.getInt(attr, 0)); 1227 else if (attr == View_scrollbarFadeDuration) 1228 json.put("View_scrollbarFadeDuration", a.getInt(attr, 0)); 1229 else if (attr == View_scrollbarDefaultDelayBeforeFade) 1230 json.put("View_scrollbarDefaultDelayBeforeFade", a.getInt(attr, 0)); 1231 else if (attr == View_scrollbarSize) 1232 json.put("View_scrollbarSize", a.getDimensionPixelSize(attr, -1)); 1233 else if (attr == View_scrollbarThumbHorizontal) 1234 json.put("View_scrollbarThumbHorizontal", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarThumbHorizontal", null)); 1235 else if (attr == View_scrollbarThumbVertical) 1236 json.put("View_scrollbarThumbVertical", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarThumbVertical", null)); 1237 else if (attr == View_scrollbarTrackHorizontal) 1238 json.put("View_scrollbarTrackHorizontal", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarTrackHorizontal", null)); 1239 else if (attr == View_scrollbarTrackVertical) 1240 json.put("View_scrollbarTrackVertical", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarTrackVertical", null)); 1241 else if (attr == View_isScrollContainer) 1242 json.put("View_isScrollContainer", a.getBoolean(attr, false)); 1243 else if (attr == View_keepScreenOn) 1244 json.put("View_keepScreenOn", a.getBoolean(attr, false)); 1245 else if (attr == View_filterTouchesWhenObscured) 1246 json.put("View_filterTouchesWhenObscured", a.getBoolean(attr, false)); 1247 else if (attr == View_nextFocusLeft) 1248 json.put("View_nextFocusLeft", a.getResourceId(attr, -1)); 1249 else if (attr == View_nextFocusRight) 1250 json.put("View_nextFocusRight", a.getResourceId(attr, -1)); 1251 else if (attr == View_nextFocusUp) 1252 json.put("View_nextFocusUp", a.getResourceId(attr, -1)); 1253 else if (attr == View_nextFocusDown) 1254 json.put("View_nextFocusDown", a.getResourceId(attr, -1)); 1255 else if (attr == View_minWidth) 1256 json.put("View_minWidth", a.getDimensionPixelSize(attr, 0)); 1257 else if (attr == View_minHeight) 1258 json.put("View_minHeight", a.getDimensionPixelSize(attr, 0)); 1259 else if (attr == View_onClick) 1260 json.put("View_onClick", a.getString(attr)); 1261 else if (attr == View_overScrollMode) 1262 json.put("View_overScrollMode", a.getInt(attr, 1)); 1263 else if (attr == View_paddingStart) 1264 json.put("View_paddingStart", a.getDimensionPixelSize(attr, 0)); 1265 else if (attr == View_paddingEnd) 1266 json.put("View_paddingEnd", a.getDimensionPixelSize(attr, 0)); 1267 } 1268 a.recycle(); 1269 } catch (Exception e) { 1270 e.printStackTrace(); 1271 } 1272 } 1273 extractTextAppearance(int styleId)1274 public JSONObject extractTextAppearance(int styleId) 1275 { 1276 JSONObject json = new JSONObject(); 1277 try 1278 { 1279 TypedArray a = m_theme.obtainStyledAttributes(styleId, (int[]) styleableClass.getDeclaredField("TextAppearance").get(null)); 1280 int n = a.getIndexCount(); 1281 for (int i = 0; i < n; i++) 1282 { 1283 int attr = a.getIndex(i); 1284 if (attr == TextAppearance_textColorHighlight) 1285 json.put("TextAppearance_textColorHighlight", a.getColor(attr, 0)); 1286 else if (attr == TextAppearance_textColor) 1287 json.put("TextAppearance_textColor", getColorStateList(a.getColorStateList(attr))); 1288 else if (attr == TextAppearance_textColorHint) 1289 json.put("TextAppearance_textColorHint", getColorStateList(a.getColorStateList(attr))); 1290 else if (attr == TextAppearance_textColorLink) 1291 json.put("TextAppearance_textColorLink", getColorStateList(a.getColorStateList(attr))); 1292 else if (attr == TextAppearance_textSize) 1293 json.put("TextAppearance_textSize", a.getDimensionPixelSize(attr, 15)); 1294 else if (attr == TextAppearance_typeface) 1295 json.put("TextAppearance_typeface", a.getInt(attr, -1)); 1296 else if (attr == TextAppearance_textStyle) 1297 json.put("TextAppearance_textStyle", a.getInt(attr, -1)); 1298 else if (attr == TextAppearance_textAllCaps) 1299 json.put("TextAppearance_textAllCaps", a.getBoolean(attr, false)); 1300 } 1301 a.recycle(); 1302 } 1303 catch (Exception e) 1304 { 1305 e.printStackTrace(); 1306 } 1307 return json; 1308 } 1309 extractTextAppearanceInformations(String styleName, String qtClass, AttributeSet attribSet, int textAppearance)1310 public JSONObject extractTextAppearanceInformations(String styleName, String qtClass, AttributeSet attribSet, int textAppearance) 1311 { 1312 JSONObject json = new JSONObject(); 1313 try 1314 { 1315 int textColorHighlight = 0; // 1316 ColorStateList textColor = null; // 1317 ColorStateList textColorHint = null; // 1318 ColorStateList textColorLink = null; // 1319 int textSize = 15; // 1320 int typefaceIndex = -1; // 1321 int styleIndex = -1; 1322 boolean allCaps = false; 1323 1324 Class<?> attrClass= Class.forName("android.R$attr"); 1325 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1326 1327 extractViewInformations(styleName, styleId, json, qtClass, attribSet); 1328 1329 int[] textViewAttrs=(int[]) styleableClass.getDeclaredField("TextView").get(null); 1330 TypedArray a =m_theme.obtainStyledAttributes(null, textViewAttrs, styleId, 0); 1331 1332 TypedArray appearance = null; 1333 if (-1==textAppearance) 1334 textAppearance = a.getResourceId(styleableClass.getDeclaredField("TextView_textAppearance").getInt(null), -1); 1335 1336 if (textAppearance != -1) 1337 appearance = m_theme.obtainStyledAttributes(textAppearance, (int[]) styleableClass.getDeclaredField("TextAppearance").get(null)); 1338 1339 if (appearance != null) 1340 { 1341 int n = appearance.getIndexCount(); 1342 for (int i = 0; i < n; i++) 1343 { 1344 int attr = appearance.getIndex(i); 1345 if (attr == TextAppearance_textColorHighlight) 1346 textColorHighlight = appearance.getColor(attr, textColorHighlight); 1347 else if (attr == TextAppearance_textColor) 1348 textColor = appearance.getColorStateList(attr); 1349 else if (attr == TextAppearance_textColorHint) 1350 textColorHint = appearance.getColorStateList(attr); 1351 else if (attr == TextAppearance_textColorLink) 1352 textColorLink = appearance.getColorStateList(attr); 1353 else if (attr == TextAppearance_textSize) 1354 textSize = appearance.getDimensionPixelSize(attr, textSize); 1355 else if (attr == TextAppearance_typeface) 1356 typefaceIndex = appearance.getInt(attr, -1); 1357 else if (attr == TextAppearance_textStyle) 1358 styleIndex = appearance.getInt(attr, -1); 1359 else if (attr == TextAppearance_textAllCaps) 1360 allCaps = appearance.getBoolean(attr, false); 1361 } 1362 appearance.recycle(); 1363 } 1364 1365 int n = a.getIndexCount(); 1366 1367 for (int i = 0; i < n; i++) { 1368 int attr = a.getIndex(i); 1369 1370 if (attr == TextView_editable) 1371 json.put("TextView_editable", a.getBoolean(attr, false)); 1372 else if (attr == TextView_inputMethod) 1373 json.put("TextView_inputMethod", a.getText(attr)); 1374 else if (attr == TextView_numeric) 1375 json.put("TextView_numeric", a.getInt(attr, 0)); 1376 else if (attr == TextView_digits) 1377 json.put("TextView_digits", a.getText(attr)); 1378 else if (attr == TextView_phoneNumber) 1379 json.put("TextView_phoneNumber", a.getBoolean(attr, false)); 1380 else if (attr == TextView_autoText) 1381 json.put("TextView_autoText", a.getBoolean(attr, false)); 1382 else if (attr == TextView_capitalize) 1383 json.put("TextView_capitalize", a.getInt(attr, -1)); 1384 else if (attr == TextView_bufferType) 1385 json.put("TextView_bufferType", a.getInt(attr, 0)); 1386 else if (attr == TextView_selectAllOnFocus) 1387 json.put("TextView_selectAllOnFocus", a.getBoolean(attr, false)); 1388 else if (attr == TextView_autoLink) 1389 json.put("TextView_autoLink", a.getInt(attr, 0)); 1390 else if (attr == TextView_linksClickable) 1391 json.put("TextView_linksClickable", a.getBoolean(attr, true)); 1392 else if (attr == TextView_linksClickable) 1393 json.put("TextView_linksClickable", a.getBoolean(attr, true)); 1394 else if (attr == TextView_drawableLeft) 1395 json.put("TextView_drawableLeft", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableLeft", null)); 1396 else if (attr == TextView_drawableTop) 1397 json.put("TextView_drawableTop", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableTop", null)); 1398 else if (attr == TextView_drawableRight) 1399 json.put("TextView_drawableRight", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableRight", null)); 1400 else if (attr == TextView_drawableBottom) 1401 json.put("TextView_drawableBottom", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableBottom", null)); 1402 else if (attr == TextView_drawableStart) 1403 json.put("TextView_drawableStart", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableStart", null)); 1404 else if (attr == TextView_drawableEnd) 1405 json.put("TextView_drawableEnd", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableEnd", null)); 1406 else if (attr == TextView_drawablePadding) 1407 json.put("TextView_drawablePadding", a.getDimensionPixelSize(attr, 0)); 1408 else if (attr == TextView_textCursorDrawable) { 1409 try { 1410 json.put("TextView_textCursorDrawable", getDrawable(a.getDrawable(attr), styleName + "_TextView_textCursorDrawable", null)); 1411 } catch (Exception e_) { 1412 try { 1413 json.put("TextView_textCursorDrawable", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textCursorDrawable", null)); 1414 } catch (Exception e) { 1415 e.printStackTrace(); 1416 } 1417 } 1418 }else if (attr == TextView_maxLines) 1419 json.put("TextView_maxLines", a.getInt(attr, -1)); 1420 else if (attr == TextView_maxHeight) 1421 json.put("TextView_maxHeight", a.getDimensionPixelSize(attr, -1)); 1422 else if (attr == TextView_lines) 1423 json.put("TextView_lines", a.getInt(attr, -1)); 1424 else if (attr == TextView_height) 1425 json.put("TextView_height", a.getDimensionPixelSize(attr, -1)); 1426 else if (attr == TextView_minLines) 1427 json.put("TextView_minLines", a.getInt(attr, -1)); 1428 else if (attr == TextView_minHeight) 1429 json.put("TextView_minHeight", a.getDimensionPixelSize(attr, -1)); 1430 else if (attr == TextView_maxEms) 1431 json.put("TextView_maxEms", a.getInt(attr, -1)); 1432 else if (attr == TextView_maxWidth) 1433 json.put("TextView_maxWidth", a.getDimensionPixelSize(attr, -1)); 1434 else if (attr == TextView_ems) 1435 json.put("TextView_ems", a.getInt(attr, -1)); 1436 else if (attr == TextView_width) 1437 json.put("TextView_width", a.getDimensionPixelSize(attr, -1)); 1438 else if (attr == TextView_minEms) 1439 json.put("TextView_minEms", a.getInt(attr, -1)); 1440 else if (attr == TextView_minWidth) 1441 json.put("TextView_minWidth", a.getDimensionPixelSize(attr, -1)); 1442 else if (attr == TextView_gravity) 1443 json.put("TextView_gravity", a.getInt(attr, -1)); 1444 else if (attr == TextView_hint) 1445 json.put("TextView_hint", a.getText(attr)); 1446 else if (attr == TextView_text) 1447 json.put("TextView_text", a.getText(attr)); 1448 else if (attr == TextView_scrollHorizontally) 1449 json.put("TextView_scrollHorizontally", a.getBoolean(attr, false)); 1450 else if (attr == TextView_singleLine) 1451 json.put("TextView_singleLine", a.getBoolean(attr, false)); 1452 else if (attr == TextView_ellipsize) 1453 json.put("TextView_ellipsize", a.getInt(attr, -1)); 1454 else if (attr == TextView_marqueeRepeatLimit) 1455 json.put("TextView_marqueeRepeatLimit", a.getInt(attr, 3)); 1456 else if (attr == TextView_includeFontPadding) 1457 json.put("TextView_includeFontPadding", a.getBoolean(attr, true)); 1458 else if (attr == TextView_cursorVisible) 1459 json.put("TextView_cursorVisible", a.getBoolean(attr, true)); 1460 else if (attr == TextView_maxLength) 1461 json.put("TextView_maxLength", a.getInt(attr, -1)); 1462 else if (attr == TextView_textScaleX) 1463 json.put("TextView_textScaleX", a.getFloat(attr, 1.0f)); 1464 else if (attr == TextView_freezesText) 1465 json.put("TextView_freezesText", a.getBoolean(attr, false)); 1466 else if (attr == TextView_shadowColor) 1467 json.put("TextView_shadowColor", a.getInt(attr, 0)); 1468 else if (attr == TextView_shadowDx) 1469 json.put("TextView_shadowDx", a.getFloat(attr, 0)); 1470 else if (attr == TextView_shadowDy) 1471 json.put("TextView_shadowDy", a.getFloat(attr, 0)); 1472 else if (attr == TextView_shadowRadius) 1473 json.put("TextView_shadowRadius", a.getFloat(attr, 0)); 1474 else if (attr == TextView_enabled) 1475 json.put("TextView_enabled", a.getBoolean(attr,true)); 1476 else if (attr == TextView_textColorHighlight) 1477 textColorHighlight = a.getColor(attr, textColorHighlight); 1478 else if (attr == TextView_textColor) 1479 textColor = a.getColorStateList(attr); 1480 else if (attr == TextView_textColorHint) 1481 textColorHint = a.getColorStateList(attr); 1482 else if (attr == TextView_textColorLink) 1483 textColorLink = a.getColorStateList(attr); 1484 else if (attr == TextView_textSize) 1485 textSize = a.getDimensionPixelSize(attr, textSize); 1486 else if (attr == TextView_typeface) 1487 typefaceIndex = a.getInt(attr, typefaceIndex); 1488 else if (attr == TextView_textStyle) 1489 styleIndex = a.getInt(attr, styleIndex); 1490 else if (attr == TextView_password) 1491 json.put("TextView_password", a.getBoolean(attr,false)); 1492 else if (attr == TextView_lineSpacingExtra) 1493 json.put("TextView_lineSpacingExtra", a.getDimensionPixelSize(attr, 0)); 1494 else if (attr == TextView_lineSpacingMultiplier) 1495 json.put("TextView_lineSpacingMultiplier", a.getFloat(attr, 1.0f)); 1496 else if (attr == TextView_inputType) 1497 json.put("TextView_inputType", a.getInt(attr, EditorInfo.TYPE_NULL)); 1498 else if (attr == TextView_imeOptions) 1499 json.put("TextView_imeOptions", a.getInt(attr, EditorInfo.IME_NULL)); 1500 else if (attr == TextView_imeActionLabel) 1501 json.put("TextView_imeActionLabel", a.getText(attr)); 1502 else if (attr == TextView_imeActionId) 1503 json.put("TextView_imeActionId", a.getInt(attr,0)); 1504 else if (attr == TextView_privateImeOptions) 1505 json.put("TextView_privateImeOptions", a.getString(attr)); 1506 else if (attr == TextView_textSelectHandleLeft && styleName.equals("textViewStyle")) { 1507 try { 1508 json.put("TextView_textSelectHandleLeft", getDrawable(a.getDrawable(attr), styleName + "_TextView_textSelectHandleLeft", null)); 1509 } catch (Exception _e) { 1510 try { 1511 json.put("TextView_textSelectHandleLeft", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandleLeft", null)); 1512 } catch (Exception e) { 1513 e.printStackTrace(); 1514 } 1515 } 1516 } else if (attr == TextView_textSelectHandleRight && styleName.equals("textViewStyle")) { 1517 try { 1518 json.put("TextView_textSelectHandleRight", getDrawable(a.getDrawable(attr), styleName + "_TextView_textSelectHandleRight", null)); 1519 } catch (Exception _e) { 1520 try { 1521 json.put("TextView_textSelectHandleRight", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandleRight", null)); 1522 } catch (Exception e) { 1523 e.printStackTrace(); 1524 } 1525 } 1526 } else if (attr == TextView_textSelectHandle && styleName.equals("textViewStyle")) { 1527 try { 1528 json.put("TextView_textSelectHandle", getDrawable(a.getDrawable(attr), styleName + "_TextView_textSelectHandle", null)); 1529 } catch (Exception _e) { 1530 try { 1531 json.put("TextView_textSelectHandle", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandle", null)); 1532 } catch (Exception e) { 1533 e.printStackTrace(); 1534 } 1535 } 1536 } else if (attr == TextView_textIsSelectable) 1537 json.put("TextView_textIsSelectable", a.getBoolean(attr, false)); 1538 else if (attr == TextView_textAllCaps) 1539 allCaps = a.getBoolean(attr, false); 1540 } 1541 a.recycle(); 1542 1543 json.put("TextAppearance_textColorHighlight",textColorHighlight); 1544 json.put("TextAppearance_textColor", getColorStateList(textColor)); 1545 json.put("TextAppearance_textColorHint", getColorStateList(textColorHint)); 1546 json.put("TextAppearance_textColorLink", getColorStateList(textColorLink)); 1547 json.put("TextAppearance_textSize",textSize); 1548 json.put("TextAppearance_typeface",typefaceIndex); 1549 json.put("TextAppearance_textStyle",styleIndex); 1550 json.put("TextAppearance_textAllCaps",allCaps); 1551 } 1552 catch(Exception e) 1553 { 1554 e.printStackTrace(); 1555 } 1556 return json; 1557 } 1558 1559 final String[] sScaleTypeArray = { 1560 "MATRIX", 1561 "FIT_XY", 1562 "FIT_START", 1563 "FIT_CENTER", 1564 "FIT_END", 1565 "CENTER", 1566 "CENTER_CROP", 1567 "CENTER_INSIDE" 1568 }; 1569 extractImageViewInformations(String styleName, String qtClassName )1570 public JSONObject extractImageViewInformations(String styleName, String qtClassName ) 1571 { 1572 JSONObject json = new JSONObject(); 1573 try 1574 { 1575 Class<?> attrClass= Class.forName("android.R$attr"); 1576 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1577 1578 extractViewInformations(styleName, styleId, json, qtClassName, null); 1579 1580 int[] imageViewAttrs=(int[]) styleableClass.getDeclaredField("ImageView").get(null); 1581 TypedArray a =m_theme.obtainStyledAttributes(null, imageViewAttrs, styleId, 0); 1582 Drawable d = a.getDrawable(ImageView_src); 1583 if (d != null) 1584 json.put("ImageView_src", getDrawable(d, styleName + "_ImageView_src", null)); 1585 1586 json.put("ImageView_baselineAlignBottom", a.getBoolean(ImageView_baselineAlignBottom, false)); 1587 json.put("ImageView_adjustViewBounds", a.getBoolean(ImageView_adjustViewBounds, false)); 1588 json.put("ImageView_maxWidth", a.getDimensionPixelSize(ImageView_maxWidth, Integer.MAX_VALUE)); 1589 json.put("ImageView_maxHeight", a.getDimensionPixelSize(ImageView_maxHeight, Integer.MAX_VALUE)); 1590 int index = a.getInt(ImageView_scaleType, -1); 1591 if (index >= 0) 1592 json.put("ImageView_scaleType", sScaleTypeArray[index]); 1593 1594 int tint = a.getInt(ImageView_tint, 0); 1595 if (tint != 0) 1596 json.put("ImageView_tint", tint); 1597 1598 1599 json.put("ImageView_cropToPadding",a.getBoolean(ImageView_cropToPadding, false)); 1600 a.recycle(); 1601 } 1602 catch(Exception e) 1603 { 1604 e.printStackTrace(); 1605 } 1606 return json; 1607 1608 } 1609 extractCompoundButton(SimpleJsonWriter jsonWriter, String styleName, String qtClass)1610 void extractCompoundButton(SimpleJsonWriter jsonWriter, String styleName, String qtClass) 1611 { 1612 JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1); 1613 Class<?> attrClass; 1614 try { 1615 attrClass = Class.forName("android.R$attr"); 1616 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1617 int[] compoundButtonAttrs=(int[]) styleableClass.getDeclaredField("CompoundButton").get(null); 1618 1619 TypedArray a = m_theme.obtainStyledAttributes( 1620 null, compoundButtonAttrs, styleId, 0); 1621 1622 Drawable d = a.getDrawable(getField(styleableClass,"CompoundButton_button")); 1623 if (d != null) 1624 json.put("CompoundButton_button", getDrawable(d, styleName + "_CompoundButton_button", null)); 1625 1626 a.recycle(); 1627 jsonWriter.name(styleName).value(json); 1628 } catch (Exception e) { 1629 e.printStackTrace(); 1630 } 1631 } 1632 extractProgressBarInfo(JSONObject json, String styleName)1633 void extractProgressBarInfo(JSONObject json, String styleName) 1634 { 1635 Class<?> attrClass; 1636 try { 1637 attrClass = Class.forName("android.R$attr"); 1638 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1639 int[] progressBarAttrs=(int[]) styleableClass.getDeclaredField("ProgressBar").get(null); 1640 1641 TypedArray a = m_theme.obtainStyledAttributes(null, progressBarAttrs, styleId, 0); 1642 int mMinWidth = 24; 1643 int mMaxWidth = 48; 1644 int mMinHeight = 24; 1645 int mMaxHeight = 48; 1646 mMinWidth = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_minWidth"), mMinWidth); 1647 mMaxWidth = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_maxWidth"), mMaxWidth); 1648 mMinHeight = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_minHeight"), mMinHeight); 1649 mMaxHeight = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_maxHeight"), mMaxHeight); 1650 1651 json.put("ProgressBar_indeterminateDuration", a.getInt(getField(styleableClass, "ProgressBar_indeterminateDuration"), 4000)); 1652 json.put("ProgressBar_minWidth", mMinWidth); 1653 json.put("ProgressBar_maxWidth", mMaxWidth); 1654 json.put("ProgressBar_minHeight", mMinHeight); 1655 json.put("ProgressBar_maxHeight", mMaxHeight); 1656 json.put("ProgressBar_progress_id", android.R.id.progress); 1657 json.put("ProgressBar_secondaryProgress_id", android.R.id.secondaryProgress); 1658 1659 Drawable d = a.getDrawable(getField(styleableClass,"ProgressBar_progressDrawable")); 1660 if (d != null) 1661 json.put("ProgressBar_progressDrawable", getDrawable(d, styleName + "_ProgressBar_progressDrawable", null)); 1662 1663 d = a.getDrawable(getField(styleableClass,"ProgressBar_indeterminateDrawable")); 1664 if (d != null) 1665 json.put("ProgressBar_indeterminateDrawable", getDrawable(d, styleName + "_ProgressBar_indeterminateDrawable", null)); 1666 1667 a.recycle(); 1668 } catch (Exception e) { 1669 e.printStackTrace(); 1670 } 1671 } 1672 extractProgressBar(SimpleJsonWriter writer, String styleName, String qtClass)1673 void extractProgressBar(SimpleJsonWriter writer, String styleName, String qtClass) 1674 { 1675 JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1); 1676 try { 1677 extractProgressBarInfo(json, styleName); 1678 writer.name(styleName).value(json); 1679 } catch (Exception e) { 1680 e.printStackTrace(); 1681 } 1682 } 1683 extractAbsSeekBar(SimpleJsonWriter jsonWriter, String styleName, String qtClass)1684 void extractAbsSeekBar(SimpleJsonWriter jsonWriter, String styleName, String qtClass) 1685 { 1686 JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1); 1687 extractProgressBarInfo(json, styleName); 1688 Class<?> attrClass; 1689 try { 1690 attrClass = Class.forName("android.R$attr"); 1691 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1692 int[] compoundButtonAttrs=(int[]) styleableClass.getDeclaredField("SeekBar").get(null); 1693 1694 TypedArray a = m_theme.obtainStyledAttributes( 1695 null, compoundButtonAttrs, styleId, 0); 1696 1697 Drawable d = a.getDrawable(getField(styleableClass,"SeekBar_thumb")); 1698 if (d != null) 1699 json.put("SeekBar_thumb", getDrawable(d, styleName + "_SeekBar_thumb", null)); 1700 1701 try { 1702 json.put("SeekBar_thumbOffset", styleableClass.getDeclaredField("SeekBar_thumbOffset").getInt(null)); 1703 } catch (Exception e) { 1704 e.printStackTrace(); 1705 } 1706 1707 a.recycle(); 1708 jsonWriter.name(styleName).value(json); 1709 } catch (Exception e) { 1710 e.printStackTrace(); 1711 } 1712 } 1713 extractSwitch(SimpleJsonWriter jsonWriter, String styleName, String qtClass)1714 void extractSwitch(SimpleJsonWriter jsonWriter, String styleName, String qtClass) 1715 { 1716 JSONObject json = new JSONObject(); 1717 try { 1718 Class<?> attrClass = Class.forName("com.android.internal.R$attr"); 1719 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1720 1721 int[] switchAttrs = (int[]) styleableClass.getDeclaredField("Switch").get(null); 1722 TypedArray a = m_theme.obtainStyledAttributes(null, switchAttrs, styleId, 0); 1723 1724 Drawable thumb = a.getDrawable(getField(styleableClass,"Switch_thumb")); 1725 if (thumb != null) 1726 json.put("Switch_thumb", getDrawable(thumb, styleName + "_Switch_thumb", null)); 1727 1728 Drawable track = a.getDrawable(getField(styleableClass,"Switch_track")); 1729 if (track != null) 1730 json.put("Switch_track", getDrawable(track, styleName + "_Switch_track", null)); 1731 1732 int textAppearance = a.getResourceId(styleableClass.getDeclaredField("Switch_switchTextAppearance").getInt(null), -1); 1733 json.put("Switch_switchTextAppearance", extractTextAppearance(textAppearance)); 1734 1735 json.put("Switch_textOn", a.getText(getField(styleableClass, "Switch_textOn"))); 1736 json.put("Switch_textOff", a.getText(getField(styleableClass, "Switch_textOff"))); 1737 json.put("Switch_switchMinWidth", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchMinWidth"), 0)); 1738 json.put("Switch_switchPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchPadding"), 0)); 1739 json.put("Switch_thumbTextPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_thumbTextPadding"), 0)); 1740 1741 json.put("Switch_showText", a.getBoolean(getField(styleableClass, "Switch_showText"), true)); 1742 json.put("Switch_splitTrack", a.getBoolean(getField(styleableClass, "Switch_splitTrack"), false)); 1743 1744 a.recycle(); 1745 jsonWriter.name(styleName).value(json); 1746 } catch (Exception e) { 1747 e.printStackTrace(); 1748 } 1749 } 1750 extractCheckedTextView(AttributeSet attribSet, String itemName)1751 JSONObject extractCheckedTextView(AttributeSet attribSet, String itemName) 1752 { 1753 JSONObject json = extractTextAppearanceInformations("textViewStyle", itemName, attribSet, -1); 1754 try { 1755 Class<?> attrClass= Class.forName("android.R$attr"); 1756 int styleId = attrClass.getDeclaredField("textViewStyle").getInt(null); 1757 int[] compoundButtonAttrs=(int[]) styleableClass.getDeclaredField("CheckedTextView").get(null); 1758 1759 TypedArray a = m_theme.obtainStyledAttributes(attribSet, compoundButtonAttrs, styleId, 0); 1760 1761 Drawable d = a.getDrawable(getField(styleableClass,"CheckedTextView_checkMark")); 1762 if (d != null) 1763 json.put("CheckedTextView_checkMark", getDrawable(d, itemName+"_CheckedTextView_checkMark", null)); 1764 1765 a.recycle(); 1766 } catch (Exception e) { 1767 e.printStackTrace(); 1768 } 1769 return json; 1770 } 1771 extractItemStyle(int resourceId, String itemName, int textAppearance)1772 private JSONObject extractItemStyle(int resourceId, String itemName, int textAppearance) { 1773 try 1774 { 1775 XmlResourceParser parser = m_context.getResources().getLayout(resourceId); 1776 int type; 1777 while ((type = parser.next()) != XmlPullParser.START_TAG && 1778 type != XmlPullParser.END_DOCUMENT) { 1779 // Empty 1780 } 1781 1782 if (type != XmlPullParser.START_TAG) { 1783 return null; 1784 } 1785 1786 AttributeSet attributes = Xml.asAttributeSet(parser); 1787 String name = parser.getName(); 1788 if (name.equals("TextView")) 1789 return extractTextAppearanceInformations("textViewStyle", itemName, attributes, textAppearance); 1790 if (name.equals("CheckedTextView")) 1791 return extractCheckedTextView(attributes, itemName); 1792 } catch (Exception e) { 1793 e.printStackTrace(); 1794 } 1795 return null; 1796 } 1797 extractItemsStyle(SimpleJsonWriter jsonWriter)1798 private void extractItemsStyle(SimpleJsonWriter jsonWriter) { 1799 try 1800 { 1801 jsonWriter.name("simple_list_item").value(extractItemStyle(android.R.layout.simple_list_item_1, "simple_list_item", android.R.style.TextAppearance_Large)); 1802 jsonWriter.name("simple_list_item_checked").value(extractItemStyle(android.R.layout.simple_list_item_checked, "simple_list_item_checked", android.R.style.TextAppearance_Large)); 1803 jsonWriter.name("simple_list_item_multiple_choice").value(extractItemStyle(android.R.layout.simple_list_item_multiple_choice, "simple_list_item_multiple_choice", android.R.style.TextAppearance_Large)); 1804 jsonWriter.name("simple_list_item_single_choice").value(extractItemStyle(android.R.layout.simple_list_item_single_choice, "simple_list_item_single_choice", android.R.style.TextAppearance_Large)); 1805 jsonWriter.name("simple_spinner_item").value(extractItemStyle(android.R.layout.simple_spinner_item, "simple_spinner_item", -1)); 1806 jsonWriter.name("simple_spinner_dropdown_item").value(extractItemStyle(android.R.layout.simple_spinner_dropdown_item, "simple_spinner_dropdown_item",android.R.style.TextAppearance_Large)); 1807 jsonWriter.name("simple_dropdown_item_1line").value(extractItemStyle(android.R.layout.simple_dropdown_item_1line, "simple_dropdown_item_1line",android.R.style.TextAppearance_Large)); 1808 jsonWriter.name("simple_selectable_list_item").value(extractItemStyle(android.R.layout.simple_selectable_list_item, "simple_selectable_list_item",android.R.style.TextAppearance_Large)); 1809 } catch (Exception e) { 1810 e.printStackTrace(); 1811 } 1812 } 1813 extractListView(SimpleJsonWriter writer, String styleName, String qtClass)1814 void extractListView(SimpleJsonWriter writer, String styleName, String qtClass) 1815 { 1816 JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1); 1817 try { 1818 Class<?> attrClass = Class.forName("android.R$attr"); 1819 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1820 1821 int[] styleAttrs = (int[]) styleableClass.getDeclaredField("ListView").get(null); 1822 TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0); 1823 1824 Drawable divider = a.getDrawable(getField(styleableClass,"ListView_divider")); 1825 if (divider != null) 1826 json.put("ListView_divider", getDrawable(divider, styleName + "_ListView_divider", null)); 1827 1828 json.put("ListView_dividerHeight", a.getDimensionPixelSize(getField(styleableClass, "ListView_dividerHeight"), 0)); 1829 1830 a.recycle(); 1831 writer.name(styleName).value(json); 1832 } catch (Exception e) { 1833 e.printStackTrace(); 1834 } 1835 } 1836 extractCalendar(SimpleJsonWriter writer, String styleName, String qtClass)1837 void extractCalendar(SimpleJsonWriter writer, String styleName, String qtClass) 1838 { 1839 JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1); 1840 try { 1841 Class<?> attrClass = Class.forName("android.R$attr"); 1842 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1843 1844 int[] styleAttrs = (int[]) styleableClass.getDeclaredField("CalendarView").get(null); 1845 TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0); 1846 1847 Drawable d = a.getDrawable(getField(styleableClass,"CalendarView_selectedDateVerticalBar")); 1848 if (d != null) 1849 json.put("CalendarView_selectedDateVerticalBar", getDrawable(d, styleName + "_CalendarView_selectedDateVerticalBar", null)); 1850 1851 int dateTextAppearance = a.getResourceId(styleableClass.getDeclaredField("CalendarView_dateTextAppearance").getInt(null), -1); 1852 json.put("CalendarView_dateTextAppearance", extractTextAppearance(dateTextAppearance)); 1853 1854 int weekDayTextAppearance = a.getResourceId(styleableClass.getDeclaredField("CalendarView_weekDayTextAppearance").getInt(null), -1); 1855 json.put("CalendarView_weekDayTextAppearance", extractTextAppearance(weekDayTextAppearance)); 1856 1857 json.put("CalendarView_firstDayOfWeek", a.getInt(getField(styleableClass, "CalendarView_firstDayOfWeek"), 0)); 1858 json.put("CalendarView_focusedMonthDateColor", a.getColor(getField(styleableClass, "CalendarView_focusedMonthDateColor"), 0)); 1859 json.put("CalendarView_selectedWeekBackgroundColor", a.getColor(getField(styleableClass, "CalendarView_selectedWeekBackgroundColor"), 0)); 1860 json.put("CalendarView_showWeekNumber", a.getBoolean(getField(styleableClass, "CalendarView_showWeekNumber"), true)); 1861 json.put("CalendarView_shownWeekCount", a.getInt(getField(styleableClass, "CalendarView_shownWeekCount"), 6)); 1862 json.put("CalendarView_unfocusedMonthDateColor", a.getColor(getField(styleableClass, "CalendarView_unfocusedMonthDateColor"), 0)); 1863 json.put("CalendarView_weekNumberColor", a.getColor(getField(styleableClass, "CalendarView_weekNumberColor"), 0)); 1864 json.put("CalendarView_weekSeparatorLineColor", a.getColor(getField(styleableClass, "CalendarView_weekSeparatorLineColor"), 0)); 1865 1866 a.recycle(); 1867 writer.name(styleName).value(json); 1868 } catch (Exception e) { 1869 e.printStackTrace(); 1870 } 1871 } 1872 extractToolBar(SimpleJsonWriter writer, String styleName, String qtClass)1873 void extractToolBar(SimpleJsonWriter writer, String styleName, String qtClass) 1874 { 1875 JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1); 1876 try { 1877 Class<?> attrClass = Class.forName("com.android.internal.R$attr"); 1878 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1879 1880 int[] styleAttrs = (int[]) styleableClass.getDeclaredField("ActionBar").get(null); 1881 TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0); 1882 1883 Drawable d = a.getDrawable(getField(styleableClass,"ActionBar_background")); 1884 if (d != null) 1885 json.put("ActionBar_background", getDrawable(d, styleName + "_ActionBar_background", null)); 1886 1887 d = a.getDrawable(getField(styleableClass,"ActionBar_backgroundStacked")); 1888 if (d != null) 1889 json.put("ActionBar_backgroundStacked", getDrawable(d, styleName + "_ActionBar_backgroundStacked", null)); 1890 1891 d = a.getDrawable(getField(styleableClass,"ActionBar_backgroundSplit")); 1892 if (d != null) 1893 json.put("ActionBar_backgroundSplit", getDrawable(d, styleName + "_ActionBar_backgroundSplit", null)); 1894 1895 d = a.getDrawable(getField(styleableClass,"ActionBar_divider")); 1896 if (d != null) 1897 json.put("ActionBar_divider", getDrawable(d, styleName + "_ActionBar_divider", null)); 1898 1899 json.put("ActionBar_itemPadding", a.getDimensionPixelSize(getField(styleableClass, "ActionBar_itemPadding"), 0)); 1900 1901 a.recycle(); 1902 writer.name(styleName).value(json); 1903 } catch (Exception e) { 1904 e.printStackTrace(); 1905 } 1906 } 1907 extractTabBar(SimpleJsonWriter writer, String styleName, String qtClass)1908 void extractTabBar(SimpleJsonWriter writer, String styleName, String qtClass) 1909 { 1910 JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1); 1911 try { 1912 Class<?> attrClass = Class.forName("android.R$attr"); 1913 int styleId = attrClass.getDeclaredField(styleName).getInt(null); 1914 1915 int[] styleAttrs = (int[]) styleableClass.getDeclaredField("LinearLayout").get(null); 1916 TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0); 1917 1918 Drawable d = a.getDrawable(getField(styleableClass,"LinearLayout_divider")); 1919 if (d != null) 1920 json.put("LinearLayout_divider", getDrawable(d, styleName + "_LinearLayout_divider", null)); 1921 json.put("LinearLayout_showDividers", a.getInt(getField(styleableClass, "LinearLayout_showDividers"), 0)); 1922 json.put("LinearLayout_dividerPadding", a.getDimensionPixelSize(getField(styleableClass, "LinearLayout_dividerPadding"), 0)); 1923 1924 a.recycle(); 1925 writer.name(styleName).value(json); 1926 } catch (Exception e) { 1927 e.printStackTrace(); 1928 } 1929 } 1930 extractWindow(SimpleJsonWriter writer, String styleName)1931 private void extractWindow(SimpleJsonWriter writer, String styleName) { 1932 JSONObject json = new JSONObject(); 1933 try 1934 { 1935 Class<?> attrClass = Class.forName("android.R$attr"); 1936 int[] windowAttrs = (int[]) styleableClass.getDeclaredField("Window").get(null); 1937 1938 int backgroundId = attrClass.getDeclaredField("windowBackground").getInt(null); 1939 TypedArray a = m_theme.obtainStyledAttributes(null, windowAttrs, backgroundId, 0); 1940 Drawable background = a.getDrawable(getField(styleableClass, "Window_windowBackground")); 1941 if (background != null) 1942 json.put("Window_windowBackground", getDrawable(background, styleName + "_Window_windowBackground", null)); 1943 a.recycle(); 1944 1945 int frameId = attrClass.getDeclaredField("windowFrame").getInt(null); 1946 a = m_theme.obtainStyledAttributes(null, windowAttrs, frameId, 0); 1947 Drawable frame = a.getDrawable(getField(styleableClass, "Window_windowFrame")); 1948 if (frame != null) 1949 json.put("Window_windowFrame", getDrawable(frame, styleName + "_Window_windowFrame", null)); 1950 a.recycle(); 1951 1952 writer.name(styleName).value(json); 1953 } catch (Exception e) { 1954 e.printStackTrace(); 1955 } 1956 } 1957 extractDefaultPalette()1958 private JSONObject extractDefaultPalette() 1959 { 1960 TypedArray array = m_theme.obtainStyledAttributes(new int[]{ 1961 android.R.attr.textAppearance 1962 }); 1963 int pos = 0; 1964 JSONObject json = extractTextAppearance(array.getResourceId(pos++, -1)); 1965 try { 1966 json.put("defaultBackgroundColor", defaultBackgroundColor); 1967 json.put("defaultTextColorPrimary", defaultTextColor); 1968 } catch (Exception e) { 1969 e.printStackTrace(); 1970 } 1971 array.recycle(); 1972 return json; 1973 } 1974 ExtractStyle(Context context, String extractPath, boolean minimal)1975 public ExtractStyle(Context context, String extractPath, boolean minimal) 1976 { 1977 // Log.i(MinistroService.TAG, "Extract " + extractPath); 1978 m_minimal = minimal; 1979 m_extractPath = extractPath + "/"; 1980 new File(m_extractPath).mkdirs(); 1981 // MinistroActivity.nativeChmode(m_extractPath, 0755); 1982 m_context = context; 1983 m_theme = context.getTheme(); 1984 TypedArray array = m_theme.obtainStyledAttributes(new int[]{ 1985 android.R.attr.colorBackground, 1986 android.R.attr.textColorPrimary, 1987 android.R.attr.textColor 1988 }); 1989 defaultBackgroundColor = array.getColor(0, 0); 1990 int textColor = array.getColor(1, 0xFFFFFF); 1991 if (textColor == 0xFFFFFF) 1992 textColor = array.getColor(2, 0xFFFFFF); 1993 defaultTextColor = textColor; 1994 array.recycle(); 1995 1996 try 1997 { 1998 SimpleJsonWriter jsonWriter = new SimpleJsonWriter(m_extractPath+"style.json"); 1999 jsonWriter.beginObject(); 2000 try { 2001 jsonWriter.name("defaultStyle").value(extractDefaultPalette()); 2002 extractWindow(jsonWriter, "windowStyle"); 2003 jsonWriter.name("buttonStyle").value(extractTextAppearanceInformations("buttonStyle", "QPushButton", null, -1)); 2004 jsonWriter.name("spinnerStyle").value(extractTextAppearanceInformations("spinnerStyle", "QComboBox", null, -1)); 2005 extractProgressBar(jsonWriter, "progressBarStyleHorizontal", "QProgressBar"); 2006 extractProgressBar(jsonWriter, "progressBarStyleLarge", null); 2007 extractProgressBar(jsonWriter, "progressBarStyleSmall", null); 2008 extractProgressBar(jsonWriter, "progressBarStyle", null); 2009 extractAbsSeekBar(jsonWriter, "seekBarStyle", "QSlider"); 2010 extractSwitch(jsonWriter, "switchStyle", null); 2011 extractCompoundButton(jsonWriter, "checkboxStyle", "QCheckBox"); 2012 jsonWriter.name("editTextStyle").value(extractTextAppearanceInformations("editTextStyle", "QLineEdit", null, -1)); 2013 extractCompoundButton(jsonWriter, "radioButtonStyle", "QRadioButton"); 2014 jsonWriter.name("textViewStyle").value(extractTextAppearanceInformations("textViewStyle", "QWidget", null, -1)); 2015 jsonWriter.name("scrollViewStyle").value(extractTextAppearanceInformations("scrollViewStyle", "QAbstractScrollArea", null, -1)); 2016 extractListView(jsonWriter, "listViewStyle", "QListView"); 2017 jsonWriter.name("listSeparatorTextViewStyle").value(extractTextAppearanceInformations("listSeparatorTextViewStyle", null, null, -1)); 2018 extractItemsStyle(jsonWriter); 2019 extractCompoundButton(jsonWriter, "buttonStyleToggle", null); 2020 extractCalendar(jsonWriter, "calendarViewStyle", "QCalendarWidget"); 2021 extractToolBar(jsonWriter, "actionBarStyle", "QToolBar"); 2022 jsonWriter.name("actionButtonStyle").value(extractTextAppearanceInformations("actionButtonStyle", "QToolButton", null, -1)); 2023 jsonWriter.name("actionBarTabTextStyle").value(extractTextAppearanceInformations("actionBarTabTextStyle", null, null, -1)); 2024 jsonWriter.name("actionBarTabStyle").value(extractTextAppearanceInformations("actionBarTabStyle", null, null, -1)); 2025 jsonWriter.name("actionOverflowButtonStyle").value(extractImageViewInformations("actionOverflowButtonStyle", null)); 2026 extractTabBar(jsonWriter, "actionBarTabBarStyle", "QTabBar"); 2027 } catch (Exception e) { 2028 e.printStackTrace(); 2029 } 2030 jsonWriter.endObject(); 2031 jsonWriter.close(); 2032 // MinistroActivity.nativeChmode(m_extractPath+"style.json", 0644); 2033 } 2034 catch (Exception e) { 2035 e.printStackTrace(); 2036 } 2037 } 2038 } 2039