CallButtonFragment.java revision 39fed851cc58faa469b98943dd93df0c1ee7bcea
1/* 2 * Copyright (C) 2013 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 17package com.android.incallui; 18 19import android.content.Context; 20import android.graphics.drawable.LayerDrawable; 21import android.os.Bundle; 22import android.telecomm.AudioState; 23import android.view.ContextThemeWrapper; 24import android.view.LayoutInflater; 25import android.view.Menu; 26import android.view.MenuItem; 27import android.view.View; 28import android.view.ViewGroup; 29import android.view.accessibility.AccessibilityEvent; 30import android.view.accessibility.AccessibilityManager; 31import android.widget.CompoundButton; 32import android.widget.ImageButton; 33import android.widget.PopupMenu; 34import android.widget.PopupMenu.OnDismissListener; 35import android.widget.PopupMenu.OnMenuItemClickListener; 36 37/** 38 * Fragment for call control buttons 39 */ 40public class CallButtonFragment 41 extends BaseFragment<CallButtonPresenter, CallButtonPresenter.CallButtonUi> 42 implements CallButtonPresenter.CallButtonUi, OnMenuItemClickListener, OnDismissListener, 43 View.OnClickListener, CompoundButton.OnCheckedChangeListener { 44 45 private ImageButton mAudioButton; 46 private ImageButton mChangeToVoiceButton; 47 private ImageButton mMuteButton; 48 private ImageButton mShowDialpadButton; 49 private ImageButton mHoldButton; 50 private ImageButton mSwapButton; 51 private ImageButton mChangeToVideoButton; 52 private ImageButton mSwitchCameraButton; 53 private ImageButton mAddCallButton; 54 private ImageButton mMergeButton; 55 private ImageButton mPauseVideoButton; 56 private ImageButton mOverflowButton; 57 58 private PopupMenu mAudioModePopup; 59 private boolean mAudioModePopupVisible; 60 private PopupMenu mOverflowPopup; 61 62 private int mPrevAudioMode = 0; 63 64 // Constants for Drawable.setAlpha() 65 private static final int HIDDEN = 0; 66 private static final int VISIBLE = 255; 67 68 private boolean mIsEnabled; 69 70 @Override 71 CallButtonPresenter createPresenter() { 72 // TODO: find a cleaner way to include audio mode provider than having a singleton instance. 73 return new CallButtonPresenter(); 74 } 75 76 @Override 77 CallButtonPresenter.CallButtonUi getUi() { 78 return this; 79 } 80 81 @Override 82 public void onCreate(Bundle savedInstanceState) { 83 super.onCreate(savedInstanceState); 84 } 85 86 @Override 87 public View onCreateView(LayoutInflater inflater, ViewGroup container, 88 Bundle savedInstanceState) { 89 final View parent = inflater.inflate(R.layout.call_button_fragment, container, false); 90 91 mAudioButton = (ImageButton) parent.findViewById(R.id.audioButton); 92 mAudioButton.setOnClickListener(this); 93 mChangeToVoiceButton = (ImageButton) parent.findViewById(R.id.changeToVoiceButton); 94 mChangeToVoiceButton. setOnClickListener(this); 95 mMuteButton = (ImageButton) parent.findViewById(R.id.muteButton); 96 mMuteButton.setOnClickListener(this); 97 mShowDialpadButton = (ImageButton) parent.findViewById(R.id.dialpadButton); 98 mShowDialpadButton.setOnClickListener(this); 99 mHoldButton = (ImageButton) parent.findViewById(R.id.holdButton); 100 mHoldButton.setOnClickListener(this); 101 mSwapButton = (ImageButton) parent.findViewById(R.id.swapButton); 102 mSwapButton.setOnClickListener(this); 103 mChangeToVideoButton = (ImageButton) parent.findViewById(R.id.changeToVideoButton); 104 mChangeToVideoButton.setOnClickListener(this); 105 mSwitchCameraButton = (ImageButton) parent.findViewById(R.id.switchCameraButton); 106 mSwitchCameraButton.setOnClickListener(this); 107 mAddCallButton = (ImageButton) parent.findViewById(R.id.addButton); 108 mAddCallButton.setOnClickListener(this); 109 mMergeButton = (ImageButton) parent.findViewById(R.id.mergeButton); 110 mMergeButton.setOnClickListener(this); 111 mPauseVideoButton = (ImageButton) parent.findViewById(R.id.pauseVideoButton); 112 mPauseVideoButton.setOnClickListener(this); 113 mOverflowButton = (ImageButton) parent.findViewById(R.id.overflowButton); 114 mOverflowButton.setOnClickListener(this); 115 116 return parent; 117 } 118 119 @Override 120 public void onActivityCreated(Bundle savedInstanceState) { 121 super.onActivityCreated(savedInstanceState); 122 123 // set the buttons 124 updateAudioButtons(getPresenter().getSupportedAudio()); 125 } 126 127 @Override 128 public void onResume() { 129 if (getPresenter() != null) { 130 getPresenter().refreshMuteState(); 131 } 132 super.onResume(); 133 } 134 135 @Override 136 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 137 } 138 139 @Override 140 public void onClick(View view) { 141 int id = view.getId(); 142 Log.d(this, "onClick(View " + view + ", id " + id + ")..."); 143 144 switch(id) { 145 case R.id.audioButton: 146 onAudioButtonClicked(); 147 break; 148 case R.id.addButton: 149 getPresenter().addCallClicked(); 150 break; 151 case R.id.changeToVoiceButton: 152 getPresenter().changeToVoiceClicked(); 153 break; 154 case R.id.muteButton: { 155 final ImageButton button = (ImageButton) view; 156 getPresenter().muteClicked(!button.isSelected()); 157 break; 158 } 159 case R.id.mergeButton: 160 getPresenter().mergeClicked(); 161 break; 162 case R.id.holdButton: { 163 final ImageButton button = (ImageButton) view; 164 getPresenter().holdClicked(!button.isSelected()); 165 break; 166 } 167 case R.id.swapButton: 168 getPresenter().holdClicked(true /* checked */); 169 break; 170 case R.id.dialpadButton: 171 getPresenter().showDialpadClicked(!mShowDialpadButton.isSelected()); 172 break; 173 case R.id.changeToVideoButton: 174 getPresenter().changeToVideoClicked(); 175 break; 176 case R.id.switchCameraButton: 177 getPresenter().switchCameraClicked( 178 mSwitchCameraButton.isSelected() /* useFrontFacingCamera */); 179 break; 180 case R.id.pauseVideoButton: 181 getPresenter().pauseVideoClicked( 182 !mPauseVideoButton.isSelected() /* pause */); 183 break; 184 case R.id.overflowButton: 185 mOverflowPopup.show(); 186 break; 187 default: 188 Log.wtf(this, "onClick: unexpected"); 189 break; 190 } 191 } 192 193 @Override 194 public void setEnabled(boolean isEnabled) { 195 mIsEnabled = isEnabled; 196 View view = getView(); 197 if (view.getVisibility() != View.VISIBLE) { 198 view.setVisibility(View.VISIBLE); 199 } 200 201 mAudioButton.setEnabled(isEnabled); 202 mChangeToVoiceButton.setEnabled(isEnabled); 203 mMuteButton.setEnabled(isEnabled); 204 mShowDialpadButton.setEnabled(isEnabled); 205 mHoldButton.setEnabled(isEnabled); 206 mSwapButton.setEnabled(isEnabled); 207 mChangeToVideoButton.setEnabled(isEnabled); 208 mSwitchCameraButton.setEnabled(isEnabled); 209 mAddCallButton.setEnabled(isEnabled); 210 mMergeButton.setEnabled(isEnabled); 211 mPauseVideoButton.setEnabled(isEnabled); 212 mOverflowButton.setEnabled(isEnabled); 213 } 214 215 @Override 216 public void setMute(boolean value) { 217 if (mMuteButton.isSelected() != value) { 218 mMuteButton.setSelected(value); 219 maybeSendAccessibilityEvent(mMuteButton, value ? R.string.accessibility_call_muted 220 : R.string.accessibility_call_unmuted); 221 } 222 } 223 224 @Override 225 public void showAudioButton(boolean show) { 226 mAudioButton.setVisibility(show ? View.VISIBLE : View.GONE); 227 } 228 229 @Override 230 public void showChangeToVoiceButton(boolean show) { 231 mChangeToVoiceButton.setVisibility(show ? View.VISIBLE : View.GONE); 232 } 233 234 @Override 235 public void enableMute(boolean enabled) { 236 mMuteButton.setEnabled(enabled); 237 } 238 239 @Override 240 public void showDialpadButton(boolean show) { 241 mShowDialpadButton.setVisibility(show ? View.VISIBLE : View.GONE); 242 } 243 244 @Override 245 public void setHold(boolean value) { 246 if (mHoldButton.isSelected() != value) { 247 mHoldButton.setSelected(value); 248 maybeSendAccessibilityEvent(mHoldButton, 249 value ? R.string.accessibility_call_put_on_hold : 250 R.string.accessibility_call_removed_from_hold); 251 } 252 } 253 254 @Override 255 public void showHoldButton(boolean show) { 256 mHoldButton.setVisibility(show ? View.VISIBLE : View.GONE); 257 } 258 259 @Override 260 public void enableHold(boolean enabled) { 261 mHoldButton.setEnabled(enabled); 262 } 263 264 @Override 265 public void showSwapButton(boolean show) { 266 mSwapButton.setVisibility(show ? View.VISIBLE : View.GONE); 267 } 268 269 @Override 270 public void showChangeToVideoButton(boolean show) { 271 mChangeToVideoButton.setVisibility(show ? View.VISIBLE : View.GONE); 272 } 273 274 @Override 275 public void showSwitchCameraButton(boolean show) { 276 mSwitchCameraButton.setVisibility(show ? View.VISIBLE : View.GONE); 277 } 278 279 @Override 280 public void setSwitchCameraButton(boolean isBackFacingCamera) { 281 mSwitchCameraButton.setSelected(isBackFacingCamera); 282 } 283 284 @Override 285 public void showAddCallButton(boolean show) { 286 Log.d(this, "show Add call button: " + show); 287 mAddCallButton.setVisibility(show ? View.VISIBLE : View.GONE); 288 } 289 290 @Override 291 public void enableAddCall(boolean enabled) { 292 mAddCallButton.setEnabled(enabled); 293 } 294 295 @Override 296 public void showMergeButton(boolean show) { 297 mMergeButton.setVisibility(show ? View.VISIBLE : View.GONE); 298 } 299 300 @Override 301 public void showPauseVideoButton(boolean show) { 302 mPauseVideoButton.setVisibility(show ? View.VISIBLE : View.GONE); 303 } 304 305 @Override 306 public void setPauseVideoButton(boolean isPaused) { 307 mPauseVideoButton.setSelected(isPaused); 308 } 309 310 @Override 311 public void showOverflowButton(boolean show) { 312 mOverflowButton.setVisibility(show ? View.VISIBLE : View.GONE); 313 } 314 315 @Override 316 public void configureOverflowMenu(boolean showMergeMenuOption, boolean showAddMenuOption, 317 boolean showHoldMenuOption, boolean showSwapMenuOption) { 318 if (mOverflowPopup == null) { 319 final ContextThemeWrapper contextWrapper = new ContextThemeWrapper(getActivity(), 320 R.style.InCallPopupMenuStyle); 321 mOverflowPopup = new PopupMenu(contextWrapper, mOverflowButton); 322 mOverflowPopup.getMenuInflater().inflate(R.menu.incall_overflow_menu, 323 mOverflowPopup.getMenu()); 324 mOverflowPopup.setOnMenuItemClickListener(new OnMenuItemClickListener() { 325 @Override 326 public boolean onMenuItemClick(MenuItem item) { 327 switch (item.getItemId()) { 328 case R.id.overflow_merge_menu_item: 329 getPresenter().mergeClicked(); 330 break; 331 case R.id.overflow_add_menu_item: 332 getPresenter().addCallClicked(); 333 break; 334 case R.id.overflow_hold_menu_item: 335 getPresenter().holdClicked(true /* checked */); 336 break; 337 case R.id.overflow_resume_menu_item: 338 getPresenter().holdClicked(false /* checked */); 339 break; 340 case R.id.overflow_swap_menu_item: 341 getPresenter().addCallClicked(); 342 break; 343 default: 344 Log.wtf(this, "onMenuItemClick: unexpected overflow menu click"); 345 break; 346 } 347 return true; 348 } 349 }); 350 mOverflowPopup.setOnDismissListener(new OnDismissListener() { 351 @Override 352 public void onDismiss(PopupMenu popupMenu) { 353 popupMenu.dismiss(); 354 } 355 }); 356 } 357 358 final Menu menu = mOverflowPopup.getMenu(); 359 menu.findItem(R.id.overflow_merge_menu_item).setVisible(showMergeMenuOption); 360 menu.findItem(R.id.overflow_add_menu_item).setVisible(showAddMenuOption); 361 menu.findItem(R.id.overflow_hold_menu_item).setVisible( 362 showHoldMenuOption && !mHoldButton.isSelected()); 363 menu.findItem(R.id.overflow_resume_menu_item).setVisible( 364 showHoldMenuOption && mHoldButton.isSelected()); 365 menu.findItem(R.id.overflow_swap_menu_item).setVisible(showSwapMenuOption); 366 367 mOverflowButton.setEnabled(menu.hasVisibleItems()); 368 } 369 370 @Override 371 public void setAudio(int mode) { 372 updateAudioButtons(getPresenter().getSupportedAudio()); 373 refreshAudioModePopup(); 374 375 if (mPrevAudioMode != mode) { 376 if (mPrevAudioMode != 0) { 377 int stringId = 0; 378 switch (mode) { 379 case AudioState.ROUTE_EARPIECE: 380 stringId = R.string.accessibility_earpiece_selected; 381 break; 382 case AudioState.ROUTE_BLUETOOTH: 383 stringId = R.string.accessibility_bluetooth_headset_selected; 384 break; 385 case AudioState.ROUTE_WIRED_HEADSET: 386 stringId = R.string.accessibility_wired_headset_selected; 387 break; 388 case AudioState.ROUTE_SPEAKER: 389 stringId = R.string.accessibility_speakerphone_selected; 390 break; 391 } 392 if (stringId != 0) { 393 maybeSendAccessibilityEvent(mAudioButton, stringId); 394 } 395 } 396 mPrevAudioMode = mode; 397 } 398 } 399 400 @Override 401 public void setSupportedAudio(int modeMask) { 402 updateAudioButtons(modeMask); 403 refreshAudioModePopup(); 404 } 405 406 @Override 407 public boolean onMenuItemClick(MenuItem item) { 408 Log.d(this, "- onMenuItemClick: " + item); 409 Log.d(this, " id: " + item.getItemId()); 410 Log.d(this, " title: '" + item.getTitle() + "'"); 411 412 int mode = AudioState.ROUTE_WIRED_OR_EARPIECE; 413 414 switch (item.getItemId()) { 415 case R.id.audio_mode_speaker: 416 mode = AudioState.ROUTE_SPEAKER; 417 break; 418 case R.id.audio_mode_earpiece: 419 case R.id.audio_mode_wired_headset: 420 // InCallAudioState.ROUTE_EARPIECE means either the handset earpiece, 421 // or the wired headset (if connected.) 422 mode = AudioState.ROUTE_WIRED_OR_EARPIECE; 423 break; 424 case R.id.audio_mode_bluetooth: 425 mode = AudioState.ROUTE_BLUETOOTH; 426 break; 427 default: 428 Log.e(this, "onMenuItemClick: unexpected View ID " + item.getItemId() 429 + " (MenuItem = '" + item + "')"); 430 break; 431 } 432 433 getPresenter().setAudioMode(mode); 434 435 return true; 436 } 437 438 // PopupMenu.OnDismissListener implementation; see showAudioModePopup(). 439 // This gets called when the PopupMenu gets dismissed for *any* reason, like 440 // the user tapping outside its bounds, or pressing Back, or selecting one 441 // of the menu items. 442 @Override 443 public void onDismiss(PopupMenu menu) { 444 Log.d(this, "- onDismiss: " + menu); 445 mAudioModePopupVisible = false; 446 } 447 448 /** 449 * Checks for supporting modes. If bluetooth is supported, it uses the audio 450 * pop up menu. Otherwise, it toggles the speakerphone. 451 */ 452 private void onAudioButtonClicked() { 453 Log.d(this, "onAudioButtonClicked: " + 454 AudioState.audioRouteToString(getPresenter().getSupportedAudio())); 455 456 if (isSupported(AudioState.ROUTE_BLUETOOTH)) { 457 showAudioModePopup(); 458 } else { 459 getPresenter().toggleSpeakerphone(); 460 } 461 } 462 463 /** 464 * Refreshes the "Audio mode" popup if it's visible. This is useful 465 * (for example) when a wired headset is plugged or unplugged, 466 * since we need to switch back and forth between the "earpiece" 467 * and "wired headset" items. 468 * 469 * This is safe to call even if the popup is already dismissed, or even if 470 * you never called showAudioModePopup() in the first place. 471 */ 472 public void refreshAudioModePopup() { 473 if (mAudioModePopup != null && mAudioModePopupVisible) { 474 // Dismiss the previous one 475 mAudioModePopup.dismiss(); // safe even if already dismissed 476 // And bring up a fresh PopupMenu 477 showAudioModePopup(); 478 } 479 } 480 481 /** 482 * Updates the audio button so that the appriopriate visual layers 483 * are visible based on the supported audio formats. 484 */ 485 private void updateAudioButtons(int supportedModes) { 486 final boolean bluetoothSupported = isSupported(AudioState.ROUTE_BLUETOOTH); 487 final boolean speakerSupported = isSupported(AudioState.ROUTE_SPEAKER); 488 489 boolean audioButtonEnabled = false; 490 boolean audioButtonChecked = false; 491 boolean showMoreIndicator = false; 492 493 boolean showBluetoothIcon = false; 494 boolean showSpeakerphoneIcon = false; 495 boolean showHandsetIcon = false; 496 497 boolean showToggleIndicator = false; 498 499 if (bluetoothSupported) { 500 Log.d(this, "updateAudioButtons - popup menu mode"); 501 502 audioButtonEnabled = true; 503 showMoreIndicator = true; 504 // The audio button is NOT a toggle in this state. (And its 505 // setChecked() state is irrelevant since we completely hide the 506 // btn_compound_background layer anyway.) 507 508 // Update desired layers: 509 if (isAudio(AudioState.ROUTE_BLUETOOTH)) { 510 showBluetoothIcon = true; 511 } else if (isAudio(AudioState.ROUTE_SPEAKER)) { 512 showSpeakerphoneIcon = true; 513 } else { 514 showHandsetIcon = true; 515 // TODO: if a wired headset is plugged in, that takes precedence 516 // over the handset earpiece. If so, maybe we should show some 517 // sort of "wired headset" icon here instead of the "handset 518 // earpiece" icon. (Still need an asset for that, though.) 519 } 520 } else if (speakerSupported) { 521 Log.d(this, "updateAudioButtons - speaker toggle mode"); 522 523 audioButtonEnabled = true; 524 525 // The audio button *is* a toggle in this state, and indicated the 526 // current state of the speakerphone. 527 audioButtonChecked = isAudio(AudioState.ROUTE_SPEAKER); 528 529 // update desired layers: 530 showToggleIndicator = true; 531 showSpeakerphoneIcon = true; 532 } else { 533 Log.d(this, "updateAudioButtons - disabled..."); 534 535 // The audio button is a toggle in this state, but that's mostly 536 // irrelevant since it's always disabled and unchecked. 537 audioButtonEnabled = false; 538 audioButtonChecked = false; 539 540 // update desired layers: 541 showToggleIndicator = true; 542 showSpeakerphoneIcon = true; 543 } 544 545 // Finally, update it all! 546 547 Log.v(this, "audioButtonEnabled: " + audioButtonEnabled); 548 Log.v(this, "audioButtonChecked: " + audioButtonChecked); 549 Log.v(this, "showMoreIndicator: " + showMoreIndicator); 550 Log.v(this, "showBluetoothIcon: " + showBluetoothIcon); 551 Log.v(this, "showSpeakerphoneIcon: " + showSpeakerphoneIcon); 552 Log.v(this, "showHandsetIcon: " + showHandsetIcon); 553 554 // Only enable the audio button if the fragment is enabled. 555 mAudioButton.setEnabled(audioButtonEnabled && mIsEnabled); 556 mAudioButton.setSelected(audioButtonChecked); 557 558 final LayerDrawable layers = (LayerDrawable) mAudioButton.getBackground(); 559 Log.d(this, "'layers' drawable: " + layers); 560 561 layers.findDrawableByLayerId(R.id.compoundBackgroundItem) 562 .setAlpha(showToggleIndicator ? VISIBLE : HIDDEN); 563 564 layers.findDrawableByLayerId(R.id.moreIndicatorItem) 565 .setAlpha(showMoreIndicator ? VISIBLE : HIDDEN); 566 567 layers.findDrawableByLayerId(R.id.bluetoothItem) 568 .setAlpha(showBluetoothIcon ? VISIBLE : HIDDEN); 569 570 layers.findDrawableByLayerId(R.id.handsetItem) 571 .setAlpha(showHandsetIcon ? VISIBLE : HIDDEN); 572 573 layers.findDrawableByLayerId(R.id.speakerphoneItem) 574 .setAlpha(showSpeakerphoneIcon ? VISIBLE : HIDDEN); 575 576 } 577 578 private void showAudioModePopup() { 579 Log.d(this, "showAudioPopup()..."); 580 581 final ContextThemeWrapper contextWrapper = new ContextThemeWrapper(getActivity(), 582 R.style.InCallPopupMenuStyle); 583 mAudioModePopup = new PopupMenu(contextWrapper, mAudioButton /* anchorView */); 584 mAudioModePopup.getMenuInflater().inflate(R.menu.incall_audio_mode_menu, 585 mAudioModePopup.getMenu()); 586 mAudioModePopup.setOnMenuItemClickListener(this); 587 mAudioModePopup.setOnDismissListener(this); 588 589 final Menu menu = mAudioModePopup.getMenu(); 590 591 // TODO: Still need to have the "currently active" audio mode come 592 // up pre-selected (or focused?) with a blue highlight. Still 593 // need exact visual design, and possibly framework support for this. 594 // See comments below for the exact logic. 595 596 final MenuItem speakerItem = menu.findItem(R.id.audio_mode_speaker); 597 speakerItem.setEnabled(isSupported(AudioState.ROUTE_SPEAKER)); 598 // TODO: Show speakerItem as initially "selected" if 599 // speaker is on. 600 601 // We display *either* "earpiece" or "wired headset", never both, 602 // depending on whether a wired headset is physically plugged in. 603 final MenuItem earpieceItem = menu.findItem(R.id.audio_mode_earpiece); 604 final MenuItem wiredHeadsetItem = menu.findItem(R.id.audio_mode_wired_headset); 605 606 final boolean usingHeadset = isSupported(AudioState.ROUTE_WIRED_HEADSET); 607 earpieceItem.setVisible(!usingHeadset); 608 earpieceItem.setEnabled(!usingHeadset); 609 wiredHeadsetItem.setVisible(usingHeadset); 610 wiredHeadsetItem.setEnabled(usingHeadset); 611 // TODO: Show the above item (either earpieceItem or wiredHeadsetItem) 612 // as initially "selected" if speakerOn and 613 // bluetoothIndicatorOn are both false. 614 615 final MenuItem bluetoothItem = menu.findItem(R.id.audio_mode_bluetooth); 616 bluetoothItem.setEnabled(isSupported(AudioState.ROUTE_BLUETOOTH)); 617 // TODO: Show bluetoothItem as initially "selected" if 618 // bluetoothIndicatorOn is true. 619 620 mAudioModePopup.show(); 621 622 // Unfortunately we need to manually keep track of the popup menu's 623 // visiblity, since PopupMenu doesn't have an isShowing() method like 624 // Dialogs do. 625 mAudioModePopupVisible = true; 626 } 627 628 private boolean isSupported(int mode) { 629 return (mode == (getPresenter().getSupportedAudio() & mode)); 630 } 631 632 private boolean isAudio(int mode) { 633 return (mode == getPresenter().getAudioMode()); 634 } 635 636 @Override 637 public void displayDialpad(boolean value, boolean animate) { 638 mShowDialpadButton.setSelected(value); 639 if (getActivity() != null && getActivity() instanceof InCallActivity) { 640 ((InCallActivity) getActivity()).displayDialpad(value, animate); 641 } 642 } 643 644 @Override 645 public boolean isDialpadVisible() { 646 if (getActivity() != null && getActivity() instanceof InCallActivity) { 647 return ((InCallActivity) getActivity()).isDialpadVisible(); 648 } 649 return false; 650 } 651 652 @Override 653 public Context getContext() { 654 return getActivity(); 655 } 656 657 private void maybeSendAccessibilityEvent(View view, int stringId) { 658 final Context context = getActivity(); 659 AccessibilityManager manager = 660 (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE); 661 if (manager != null && manager.isEnabled()) { 662 AccessibilityEvent e = AccessibilityEvent.obtain(); 663 e.setSource(view); 664 e.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT); 665 e.setClassName(getClass().getName()); 666 e.setPackageName(context.getPackageName()); 667 e.getText().add(context.getResources().getString(stringId)); 668 manager.sendAccessibilityEvent(e); 669 } 670 } 671} 672