1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.platform.helpers; 18 19 import static junit.framework.Assert.assertTrue; 20 21 import android.app.Instrumentation; 22 import android.content.ContentResolver; 23 import android.platform.helpers.ScrollUtility.ScrollActions; 24 import android.platform.helpers.ScrollUtility.ScrollDirection; 25 import android.text.format.DateFormat; 26 27 import androidx.test.uiautomator.By; 28 import androidx.test.uiautomator.BySelector; 29 import androidx.test.uiautomator.UiObject; 30 import androidx.test.uiautomator.UiObject2; 31 import androidx.test.uiautomator.UiScrollable; 32 import androidx.test.uiautomator.UiSelector; 33 34 import java.time.LocalDate; 35 import java.time.Month; 36 import java.time.format.TextStyle; 37 import java.util.List; 38 import java.util.Locale; 39 40 /** Helper file for Date&Time test */ 41 public class SettingsDateTimeHelperImpl extends AbstractStandardAppHelper 42 implements IAutoDateTimeSettingsHelper { 43 private static final Locale LOCALE = Locale.ENGLISH; 44 private static final TextStyle TEXT_STYLE = TextStyle.SHORT; 45 private static final String LOG_TAG = SettingsDateTimeHelperImpl.class.getSimpleName(); 46 private ScrollUtility mScrollUtility; 47 private ScrollActions mScrollAction; 48 private BySelector mBackwardButtonSelector; 49 private BySelector mForwardButtonSelector; 50 private BySelector mScrollableElementSelector; 51 private BySelector mSummarySelector; 52 private ScrollDirection mScrollDirection; 53 SettingsDateTimeHelperImpl(Instrumentation instr)54 public SettingsDateTimeHelperImpl(Instrumentation instr) { 55 super(instr); 56 mScrollUtility = ScrollUtility.getInstance(getSpectatioUiUtil()); 57 mScrollAction = 58 ScrollActions.valueOf( 59 getActionFromConfig( 60 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_ACTION)); 61 mBackwardButtonSelector = 62 getUiElementFromConfig( 63 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_BACKWARD_BUTTON); 64 mForwardButtonSelector = 65 getUiElementFromConfig( 66 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_FORWARD_BUTTON); 67 mScrollableElementSelector = 68 getUiElementFromConfig(AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_ELEMENT); 69 mSummarySelector = getUiElementFromConfig(AutomotiveConfigConstants.SETTINGS_SUMMARY); 70 mScrollDirection = 71 ScrollDirection.valueOf( 72 getActionFromConfig( 73 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_DIRECTION)); 74 mScrollUtility.setScrollValues( 75 Integer.valueOf( 76 getActionFromConfig( 77 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_MARGIN)), 78 Integer.valueOf( 79 getActionFromConfig( 80 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_WAIT_TIME))); 81 } 82 83 /** {@inheritDoc} */ 84 @Override getPackage()85 public String getPackage() { 86 return getPackageFromConfig(AutomotiveConfigConstants.SETTINGS_PACKAGE); 87 } 88 89 /** {@inheritDoc} */ 90 @Override getLauncherName()91 public String getLauncherName() { 92 throw new UnsupportedOperationException("Operation not supported."); 93 } 94 95 /** {@inheritDoc} */ 96 @Override dismissInitialDialogs()97 public void dismissInitialDialogs() { 98 // Nothing to dismiss 99 } 100 101 /** {@inheritDoc} */ 102 @Override setDate(LocalDate date)103 public void setDate(LocalDate date) { 104 UiObject2 autoDateTimeSwitchWidget = getAutoDateTimeSwitchWidget(); 105 UiObject2 autoDateTimeMenu = 106 getMenu( 107 getUiElementFromConfig( 108 AutomotiveConfigConstants 109 .DATE_TIME_SETTINGS_SET_TIME_AUTOMATICALLY)); 110 if (autoDateTimeSwitchWidget.isChecked()) { 111 getSpectatioUiUtil().clickAndWait(autoDateTimeMenu); 112 getSpectatioUiUtil().wait1Second(); 113 } 114 UiObject2 setDateMenu = getSetDateMenu(); 115 assertTrue("set date menu is not clickable", setDateMenu.isEnabled()); // from UI 116 getSpectatioUiUtil().clickAndWait(setDateMenu); 117 getSpectatioUiUtil().wait1Second(); 118 assertTrue( 119 "automatic date & time is not switched off", 120 !isAutomaticOn("auto_time")); // from API 121 int year = date.getYear(); 122 Month month = date.getMonth(); 123 int day = date.getDayOfMonth(); 124 String month_string = month.getDisplayName(TEXT_STYLE, LOCALE); 125 String day_string = ""; 126 if (day < 10) { 127 day_string = "0" + String.valueOf(day); 128 } else { 129 day_string = "" + String.valueOf(day); 130 } 131 String year_string = "" + year; 132 setCalendar(1, day_string); 133 setCalendar(0, month_string); 134 setCalendar(2, year_string); 135 getSpectatioUiUtil().pressBack(); 136 } 137 setCalendar(int index, String s)138 private void setCalendar(int index, String s) { 139 UiSelector selector = 140 new UiSelector() 141 .className( 142 getPackageFromConfig( 143 AutomotiveConfigConstants.NUMBER_PICKER_WIDGET_CLASS)) 144 .index(index); 145 boolean scrollForwards = true; 146 if (index == 2) { 147 UiSelector yearSelector = 148 selector.childSelector( 149 new UiSelector() 150 .className( 151 getPackageFromConfig( 152 AutomotiveConfigConstants 153 .EDIT_TEXT_WIDGET_CLASS))); 154 String curYear = ""; 155 try { 156 curYear = new UiObject(yearSelector).getText(); 157 } catch (Exception e) { 158 throw new RuntimeException(e); 159 } 160 if (Integer.valueOf(curYear) > Integer.valueOf(s)) scrollForwards = false; 161 } 162 scrollToObjectInPicker(index, s, scrollForwards); 163 } 164 165 /** {@inheritDoc} */ 166 @Override getDate()167 public LocalDate getDate() { 168 UiObject2 obj = getSetDateMenu(); 169 if (obj == null) { 170 throw new RuntimeException("Unable to find set date menu."); 171 } 172 String uiDate = getMenuSummaryText(obj); 173 String[] arr = uiDate.split(" "); 174 if (arr.length != 3) { 175 throw new RuntimeException("Cannot find date from UI"); 176 } 177 int year = Integer.valueOf(arr[2]); 178 int month = Month.valueOf(arr[0].toUpperCase()).getValue(); 179 int day = Integer.valueOf(arr[1].substring(0, arr[1].length() - 1)); 180 return LocalDate.of(year, month, day); 181 } 182 183 /** {@inheritDoc} */ 184 @Override setTimeInTwelveHourFormat(int hour, int minute, boolean am)185 public void setTimeInTwelveHourFormat(int hour, int minute, boolean am) { 186 // Get current time 187 String currentTime = getTime(); 188 189 // check Automatic date & time switch is turned off 190 UiObject2 autoDateTimeSwitchWidget = getAutoDateTimeSwitchWidget(); 191 UiObject2 autoDateTimeMenu = 192 getMenu( 193 getUiElementFromConfig( 194 AutomotiveConfigConstants 195 .DATE_TIME_SETTINGS_SET_TIME_AUTOMATICALLY)); 196 if (autoDateTimeSwitchWidget.isChecked()) { 197 getSpectatioUiUtil().clickAndWait(autoDateTimeMenu); 198 getSpectatioUiUtil().wait1Second(); 199 } 200 // check 24-hour format switch is turned off 201 if (isTwentyFourHourFormatEnabled()) { 202 toggleTwentyFourHourFormatSwitch(); 203 } 204 205 UiObject2 setTimeMenu = getSetTimeMenu(); 206 assertTrue("set time menu is not clickable", setTimeMenu.isEnabled()); // from UI 207 getSpectatioUiUtil().clickAndWait(setTimeMenu); 208 assertTrue( 209 "automatic date & time is not switched off", 210 !isAutomaticOn("auto_time")); // from API 211 String minute_string = "" + minute; 212 String am_pm = ""; 213 am_pm = am ? "AM" : "PM"; 214 if (minute < 10) { 215 minute_string = "0" + minute; 216 } 217 setTime(2, minute_string, currentTime); 218 setTime(0, String.valueOf(hour), currentTime); 219 setTime(1, am_pm, currentTime); 220 getSpectatioUiUtil().pressBack(); 221 } 222 223 /** {@inheritDoc} */ 224 @Override setTimeInTwentyFourHourFormat(int hour, int minute)225 public void setTimeInTwentyFourHourFormat(int hour, int minute) { 226 // Get current time 227 String currentTime = getTime(); 228 229 // check Automatic date & time switch is turned off 230 UiObject2 autoDateTimeSwitchWidget = getAutoDateTimeSwitchWidget(); 231 UiObject2 autoDateTimeMenu = 232 getMenu( 233 getUiElementFromConfig( 234 AutomotiveConfigConstants 235 .DATE_TIME_SETTINGS_SET_TIME_AUTOMATICALLY)); 236 if (autoDateTimeSwitchWidget.isChecked()) { 237 getSpectatioUiUtil().clickAndWait(autoDateTimeMenu); 238 } 239 // check 24-hour format switch is turned on 240 if (!isTwentyFourHourFormatEnabled()) { 241 toggleTwentyFourHourFormatSwitch(); 242 } 243 244 UiObject2 setTimeMenu = getSetTimeMenu(); 245 assertTrue("set time menu is not clickable", setTimeMenu.isEnabled()); // from UI 246 getSpectatioUiUtil().clickAndWait(setTimeMenu); 247 assertTrue( 248 "automatic date & time is not switched off", 249 !isAutomaticOn("auto_time")); // from API 250 String minute_string = "" + minute; 251 if (minute < 10) { 252 minute_string = "0" + minute; 253 } 254 String hour_string = "" + hour; 255 if (hour < 10) { 256 hour_string = "0" + hour; 257 } 258 setTime(2, minute_string, currentTime); 259 setTime(0, hour_string, currentTime); 260 getSpectatioUiUtil().pressBack(); 261 } 262 setTime(int index, String s, String currentTime)263 private void setTime(int index, String s, String currentTime) { 264 UiSelector selector = 265 new UiSelector() 266 .className( 267 getPackageFromConfig( 268 AutomotiveConfigConstants.NUMBER_PICKER_WIDGET_CLASS)) 269 .index(index); 270 boolean scrollForwards = true; 271 String curAM_PM; 272 if (index == 1) { 273 UiSelector am_pm_Selector = 274 selector.childSelector( 275 new UiSelector() 276 .className( 277 getPackageFromConfig( 278 AutomotiveConfigConstants 279 .EDIT_TEXT_WIDGET_CLASS))); 280 try { 281 curAM_PM = new UiObject(am_pm_Selector).getText(); 282 } catch (Exception e) { 283 throw new RuntimeException(e); 284 } 285 if (curAM_PM.equals("PM")) scrollForwards = false; 286 } else if (index == 2) { 287 int currentMinute = Integer.parseInt(currentTime.split(":")[1].split("\\s+")[0]); 288 int setMinute = Integer.parseInt(s); 289 290 /* Set scrollForwards such that the minute is scrolled a max of 30 times */ 291 if (currentMinute > setMinute) { 292 if (currentMinute - setMinute <= 30) scrollForwards = false; 293 } else if (setMinute > currentMinute) { 294 if (setMinute - currentMinute > 30) scrollForwards = false; 295 } 296 } else { 297 int currentHour = Integer.parseInt(currentTime.split(":")[0]); 298 int setHour = Integer.parseInt(s); 299 300 /* Set max scrolls based on whether we're in 12 or 24 hour format */ 301 int maxScrolls = 302 (currentTime.trim().endsWith("AM") || currentTime.trim().endsWith("PM")) 303 ? 6 304 : 12; 305 306 /* Calculate forward or backward like we did for minutes */ 307 if (currentHour > setHour) { 308 if (currentHour - setHour <= maxScrolls) scrollForwards = false; 309 } else if (setHour > currentHour) { 310 if (setHour - currentHour > maxScrolls) scrollForwards = false; 311 } 312 } 313 scrollToObjectInPicker(index, s, scrollForwards); 314 } 315 scrollToObjectInPicker(int index, String s, boolean scrollForwards)316 private void scrollToObjectInPicker(int index, String s, boolean scrollForwards) { 317 UiSelector selector = 318 new UiSelector() 319 .className( 320 getPackageFromConfig( 321 AutomotiveConfigConstants.NUMBER_PICKER_WIDGET_CLASS)) 322 .index(index); 323 UiScrollable scrollable = new UiScrollable(selector); 324 scrollable.setAsVerticalList(); 325 UiObject2 obj = 326 getSpectatioUiUtil() 327 .findUiObject( 328 By.text(s) 329 .clazz( 330 getPackageFromConfig( 331 AutomotiveConfigConstants 332 .EDIT_TEXT_WIDGET_CLASS))); 333 334 /* For hour and minute, search by child object instead of text */ 335 if (index == 0 || index == 2) { 336 UiSelector dayOrMonthSelector = 337 selector.childSelector( 338 new UiSelector() 339 .className( 340 getPackageFromConfig( 341 AutomotiveConfigConstants 342 .EDIT_TEXT_WIDGET_CLASS))); 343 344 /* Once we have the child selector, search for text within that selector */ 345 String currentValue = ""; 346 try { 347 currentValue = new UiObject(dayOrMonthSelector).getText().trim(); 348 } catch (Exception e) { 349 throw new RuntimeException(e); 350 } 351 352 while (!currentValue.equals(s.trim())) { 353 try { 354 if (scrollForwards) { 355 scrollable.scrollForward(); 356 } else { 357 scrollable.scrollBackward(); 358 } 359 } catch (Exception e) { 360 throw new RuntimeException(e); 361 } 362 363 dayOrMonthSelector = 364 selector.childSelector( 365 new UiSelector() 366 .className( 367 getPackageFromConfig( 368 AutomotiveConfigConstants 369 .EDIT_TEXT_WIDGET_CLASS))); 370 371 try { 372 currentValue = new UiObject(dayOrMonthSelector).getText().trim(); 373 } catch (Exception e) { 374 throw new RuntimeException(e); 375 } 376 } 377 } else { 378 while (obj == null) { 379 try { 380 if (scrollForwards) { 381 scrollable.scrollForward(); 382 } else { 383 scrollable.scrollBackward(); 384 } 385 } catch (Exception e) { 386 throw new RuntimeException(e); 387 } 388 obj = 389 getSpectatioUiUtil() 390 .findUiObject( 391 By.text(s) 392 .clazz( 393 getPackageFromConfig( 394 AutomotiveConfigConstants 395 .EDIT_TEXT_WIDGET_CLASS))); 396 } 397 398 if (obj == null) throw new RuntimeException("cannot find value in the picker"); 399 } 400 } 401 402 /** {@inheritDoc} */ 403 @Override getTime()404 public String getTime() { 405 UiObject2 obj = getSetTimeMenu(); 406 if (obj == null) { 407 throw new RuntimeException("Unable to find time menu."); 408 } 409 String uiTime = getMenuSummaryText(obj); 410 return uiTime; 411 } 412 413 /** {@inheritDoc} */ 414 @Override setTimeZone(String timezone)415 public void setTimeZone(String timezone) { 416 UiObject2 autoTimeZoneSwitchWidget = getAutoTimeZoneSwitchWidget(); 417 UiObject2 autoTimeZoneMenu = 418 getMenu( 419 getUiElementFromConfig( 420 AutomotiveConfigConstants 421 .DATE_TIME_SETTINGS_SET_TIME_ZONE_AUTOMATICALLY)); 422 if (getAutoTimeZoneSwitchWidget().isChecked()) { 423 getSpectatioUiUtil().clickAndWait(autoTimeZoneMenu); 424 } 425 UiObject2 selectTimeZoneMenu = getSelectTimeZoneMenu(); 426 assertTrue( 427 "select time zone menu is not clickable", 428 selectTimeZoneMenu.isEnabled()); // from UI 429 assertTrue( 430 "automatic time zone is not switched off", 431 !isAutomaticOn("auto_time_zone")); // from API 432 getSpectatioUiUtil().clickAndWait(selectTimeZoneMenu); 433 BySelector selector = By.clickable(true).hasDescendant(By.text(timezone)); 434 ScrollActions scrollAction = 435 ScrollActions.valueOf( 436 getActionFromConfig( 437 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_ACTION)); 438 BySelector backwardButtonSelector = 439 getUiElementFromConfig( 440 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_BACKWARD_BUTTON); 441 BySelector forwardButtonSelector = 442 getUiElementFromConfig( 443 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_FORWARD_BUTTON); 444 BySelector scrollElementSelector = 445 getUiElementFromConfig(AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_ELEMENT); 446 ScrollDirection scrollDirection = 447 ScrollDirection.valueOf( 448 getActionFromConfig( 449 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_DIRECTION)); 450 UiObject2 object = 451 mScrollUtility.scrollAndFindUiObject( 452 scrollAction, 453 scrollDirection, 454 forwardButtonSelector, 455 backwardButtonSelector, 456 scrollElementSelector, 457 selector, 458 String.format("Scroll on date & time to find %s", timezone)); 459 getSpectatioUiUtil() 460 .validateUiObject(object, String.format("Unable to find timezone %s", timezone)); 461 getSpectatioUiUtil().clickAndWait(object); 462 } 463 464 /** {@inheritDoc} */ 465 @Override toggleTwentyFourHourFormatSwitch()466 public boolean toggleTwentyFourHourFormatSwitch() { 467 UiObject2 twentyFourHourFormatSwitch = getUseTwentyFourHourFormatSwitchWidget(); 468 if (twentyFourHourFormatSwitch.isChecked()) { 469 assertTrue( 470 "System time format is different from UI format", 471 DateFormat.is24HourFormat(mInstrumentation.getContext())); 472 } else { 473 assertTrue( 474 "System time format is different from UI format", 475 !DateFormat.is24HourFormat(mInstrumentation.getContext())); 476 } 477 getSpectatioUiUtil().clickAndWait(twentyFourHourFormatSwitch); 478 return true; 479 } 480 481 /** {@inheritDoc} */ 482 @Override getTimeZone()483 public String getTimeZone() { 484 UiObject2 obj = getSelectTimeZoneMenu(); 485 if (obj == null) { 486 throw new RuntimeException("Unable to find timezone menu."); 487 } 488 String timeZone = getMenuSummaryText(obj); 489 return timeZone; 490 } 491 492 /** {@inheritDoc} */ 493 @Override isTwentyFourHourFormatEnabled()494 public boolean isTwentyFourHourFormatEnabled() { 495 UiObject2 twentyFourHourFormatSwitchWidget = getUseTwentyFourHourFormatSwitchWidget(); 496 return twentyFourHourFormatSwitchWidget.isChecked(); 497 } 498 getSetDateMenu()499 private UiObject2 getSetDateMenu() { 500 return getMenu( 501 getUiElementFromConfig(AutomotiveConfigConstants.DATE_TIME_SETTINGS_SET_DATE)); 502 } 503 getSetTimeMenu()504 private UiObject2 getSetTimeMenu() { 505 return getMenu( 506 getUiElementFromConfig(AutomotiveConfigConstants.DATE_TIME_SETTINGS_SET_TIME)); 507 } 508 getTwentyFourFormatMenu()509 private UiObject2 getTwentyFourFormatMenu() { 510 return getMenu( 511 getUiElementFromConfig( 512 AutomotiveConfigConstants.DATE_TIME_SETTINGS_USE_24_HOUR_FORMAT)); 513 } 514 getSelectTimeZoneMenu()515 private UiObject2 getSelectTimeZoneMenu() { 516 return getMenu( 517 getUiElementFromConfig( 518 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SELECT_TIME_ZONE)); 519 } 520 getMenu(BySelector bySelector)521 private UiObject2 getMenu(BySelector bySelector) { 522 BySelector selector = By.clickable(true).hasDescendant(bySelector); 523 ScrollActions scrollAction = 524 ScrollActions.valueOf( 525 getActionFromConfig( 526 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_ACTION)); 527 BySelector backwardButtonSelector = 528 getUiElementFromConfig( 529 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_BACKWARD_BUTTON); 530 BySelector forwardButtonSelector = 531 getUiElementFromConfig( 532 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_FORWARD_BUTTON); 533 BySelector scrollElementSelector = 534 getUiElementFromConfig(AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_ELEMENT); 535 ScrollDirection scrollDirection = 536 ScrollDirection.valueOf( 537 getActionFromConfig( 538 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SCROLL_DIRECTION)); 539 UiObject2 object = 540 mScrollUtility.scrollAndFindUiObject( 541 scrollAction, 542 scrollDirection, 543 forwardButtonSelector, 544 backwardButtonSelector, 545 scrollElementSelector, 546 selector, 547 String.format("Scroll on date & time to find %s", selector)); 548 return object; 549 } 550 getAutoDateTimeSwitchWidget()551 private UiObject2 getAutoDateTimeSwitchWidget() { 552 return getSwitchWidget( 553 getUiElementFromConfig( 554 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SET_TIME_AUTOMATICALLY)); 555 } 556 getAutoTimeZoneSwitchWidget()557 private UiObject2 getAutoTimeZoneSwitchWidget() { 558 return getSwitchWidget( 559 getUiElementFromConfig( 560 AutomotiveConfigConstants.DATE_TIME_SETTINGS_SET_TIME_ZONE_AUTOMATICALLY)); 561 } 562 getUseTwentyFourHourFormatSwitchWidget()563 private UiObject2 getUseTwentyFourHourFormatSwitchWidget() { 564 return getSwitchWidget( 565 getUiElementFromConfig( 566 AutomotiveConfigConstants.DATE_TIME_SETTINGS_USE_24_HOUR_FORMAT)); 567 } 568 getSwitchWidget(BySelector bySelector)569 private UiObject2 getSwitchWidget(BySelector bySelector) { 570 BySelector selector = By.hasDescendant(bySelector); 571 UiObject2 object = 572 mScrollUtility.scrollAndFindUiObject( 573 mScrollAction, 574 mScrollDirection, 575 mForwardButtonSelector, 576 mBackwardButtonSelector, 577 mScrollableElementSelector, 578 selector, 579 String.format("Scroll on date & time to find %s", selector)); 580 List<UiObject2> list = object.getParent().getChildren(); 581 UiObject2 switchWidget = list.get(1).getChildren().get(0).getChildren().get(0); 582 return switchWidget; 583 } 584 getMenuSummaryText(UiObject2 obj)585 private String getMenuSummaryText(UiObject2 obj) { 586 return obj.findObject(mSummarySelector).getText(); 587 } 588 isAutomaticOn(String name)589 private boolean isAutomaticOn(String name) { 590 ContentResolver cr = mInstrumentation.getContext().getContentResolver(); 591 int status = 0; 592 try { 593 status = android.provider.Settings.Global.getInt(cr, name); 594 } catch (Exception e) { 595 throw new RuntimeException(e); 596 } 597 return status == 1 ? true : false; 598 } 599 600 } 601