| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.share; | 5 package org.chromium.chrome.browser.share; |
| 6 | 6 |
| 7 import android.annotation.TargetApi; | 7 import android.annotation.TargetApi; |
| 8 import android.app.Activity; | 8 import android.app.Activity; |
| 9 import android.app.PendingIntent; | 9 import android.app.PendingIntent; |
| 10 import android.content.BroadcastReceiver; | 10 import android.content.BroadcastReceiver; |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 278 |
| 279 /** | 279 /** |
| 280 * Creates and shows a share intent picker dialog or starts a share intent d
irectly with the | 280 * Creates and shows a share intent picker dialog or starts a share intent d
irectly with the |
| 281 * activity that was most recently used to share based on shareDirectly valu
e. | 281 * activity that was most recently used to share based on shareDirectly valu
e. |
| 282 * | 282 * |
| 283 * This function will save |screenshot| under {app's root}/files/images/scre
enshot (or | 283 * This function will save |screenshot| under {app's root}/files/images/scre
enshot (or |
| 284 * /sdcard/DCIM/browser-images/screenshot if ADK is lower than JB MR2). | 284 * /sdcard/DCIM/browser-images/screenshot if ADK is lower than JB MR2). |
| 285 * Cleaning up doesn't happen automatically, and so an app should call clear
SharedScreenshots() | 285 * Cleaning up doesn't happen automatically, and so an app should call clear
SharedScreenshots() |
| 286 * explicitly when needed. | 286 * explicitly when needed. |
| 287 * | 287 * |
| 288 * @param shareDirectly Whether it should share directly with the activity t
hat was most | 288 * @param params The container holding the share parameters. |
| 289 * recently used to share. | |
| 290 * @param saveLastUsed Whether to save the chosen activity for future direct
sharing. | |
| 291 * @param activity Activity that is used to access package manager. | |
| 292 * @param title Title of the page to be shared. | |
| 293 * @param text Text to be shared. If both |text| and |url| are supplied, the
y are concatenated | |
| 294 * with a space. | |
| 295 * @param url URL of the page to be shared. | |
| 296 * @param offlineUri URI to the offline MHTML file to be shared. | |
| 297 * @param screenshotUri Uri of the screenshot of the page to be shared. | |
| 298 * @param callback Optional callback to be called when user makes a choice.
Will not be called | |
| 299 * if receiving a response when the user makes a choice is n
ot supported (on | |
| 300 * older Android versions). | |
| 301 */ | 289 */ |
| 302 public static void share(boolean shareDirectly, boolean saveLastUsed, Activi
ty activity, | 290 public static void share(ShareParams params) { |
| 303 String title, String text, String url, @Nullable Uri offlineUri, Uri
screenshotUri, | 291 if (params.isShareDirectly()) { |
| 304 @Nullable TargetChosenCallback callback) { | 292 ComponentName component = getLastShareComponentName(); |
| 305 if (shareDirectly) { | 293 if (component == null) return; |
| 306 shareWithLastUsed(activity, title, text, url, offlineUri, screenshot
Uri); | 294 assert params.getCallback() == null; |
| 295 makeIntentAndShare(params, component); |
| 307 } else if (TargetChosenReceiver.isSupported()) { | 296 } else if (TargetChosenReceiver.isSupported()) { |
| 308 makeIntentAndShare(saveLastUsed, activity, title, text, url, offline
Uri, screenshotUri, | 297 makeIntentAndShare(params, null); |
| 309 null, callback); | |
| 310 } else { | 298 } else { |
| 311 showShareDialog( | 299 showShareDialog(params); |
| 312 saveLastUsed, activity, title, text, url, offlineUri, screen
shotUri, callback); | |
| 313 } | 300 } |
| 314 } | 301 } |
| 315 | 302 |
| 316 /** | 303 /** |
| 317 * Trigger the share action for the given image data. | 304 * Trigger the share action for the given image data. |
| 318 * @param activity The activity used to trigger the share action. | 305 * @param activity The activity used to trigger the share action. |
| 319 * @param jpegImageData The image data to be shared in jpeg format. | 306 * @param jpegImageData The image data to be shared in jpeg format. |
| 320 * @param name When this is not null, it will share the image directly with
the | 307 * @param name When this is not null, it will share the image directly with
the |
| 321 * {@link ComponentName} | 308 * {@link ComponentName} |
| 322 */ | 309 */ |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 fileUri = ApiCompatibilityUtils.getUriForImageCaptureFile(sa
vedFile); | 420 fileUri = ApiCompatibilityUtils.getUriForImageCaptureFile(sa
vedFile); |
| 434 } | 421 } |
| 435 callback.onResult(fileUri); | 422 callback.onResult(fileUri); |
| 436 } | 423 } |
| 437 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | 424 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
| 438 } | 425 } |
| 439 | 426 |
| 440 /** | 427 /** |
| 441 * Creates and shows a share intent picker dialog. | 428 * Creates and shows a share intent picker dialog. |
| 442 * | 429 * |
| 443 * @param saveLastUsed Whether to save the chosen activity for future direct
sharing. | 430 * @param params The container holding the share parameters. |
| 444 * @param activity Activity that is used to access package manager. | |
| 445 * @param title Title of the page to be shared. | |
| 446 * @param text Text to be shared. If both |text| and |url| are supplied, the
y are concatenated | |
| 447 * with a space. | |
| 448 * @param url URL of the page to be shared. | |
| 449 * @oaram offlineUri URI of the offline page to be shared. | |
| 450 * @param screenshotUri Uri of the screenshot of the page to be shared. | |
| 451 * @param callback Optional callback to be called when user makes a choice.
Will not be called | |
| 452 * if receiving a response when the user makes a choice is n
ot supported (on | |
| 453 * older Android versions). | |
| 454 */ | 431 */ |
| 455 private static void showShareDialog(final boolean saveLastUsed, final Activi
ty activity, | 432 private static void showShareDialog(final ShareParams params) { |
| 456 final String title, final String text, final String url, final Uri o
fflineUri, | 433 Activity activity = params.getActivity(); |
| 457 final Uri screenshotUri, @Nullable final TargetChosenCallback callba
ck) { | 434 final TargetChosenCallback callback = params.getCallback(); |
| 458 Intent intent = getShareIntent(activity, title, text, url, null, null); | 435 Intent intent = getShareLinkAppCompatibilityIntent(); |
| 459 PackageManager manager = activity.getPackageManager(); | 436 PackageManager manager = activity.getPackageManager(); |
| 460 List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent
, 0); | 437 List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent
, 0); |
| 461 assert resolveInfoList.size() > 0; | 438 assert resolveInfoList.size() > 0; |
| 462 if (resolveInfoList.size() == 0) return; | 439 if (resolveInfoList.size() == 0) return; |
| 463 Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator(
manager)); | 440 Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator(
manager)); |
| 464 | 441 |
| 465 final ShareDialogAdapter adapter = | 442 final ShareDialogAdapter adapter = |
| 466 new ShareDialogAdapter(activity, manager, resolveInfoList); | 443 new ShareDialogAdapter(activity, manager, resolveInfoList); |
| 467 AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.
AlertDialogTheme); | 444 AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.
AlertDialogTheme); |
| 468 builder.setTitle(activity.getString(R.string.share_link_chooser_title)); | 445 builder.setTitle(activity.getString(R.string.share_link_chooser_title)); |
| 469 builder.setAdapter(adapter, null); | 446 builder.setAdapter(adapter, null); |
| 470 | 447 |
| 471 // Need a mutable object to record whether the callback has been fired. | 448 // Need a mutable object to record whether the callback has been fired. |
| 472 final boolean[] callbackCalled = new boolean[1]; | 449 final boolean[] callbackCalled = new boolean[1]; |
| 473 | 450 |
| 474 final AlertDialog dialog = builder.create(); | 451 final AlertDialog dialog = builder.create(); |
| 475 dialog.show(); | 452 dialog.show(); |
| 476 dialog.getListView().setOnItemClickListener(new OnItemClickListener() { | 453 dialog.getListView().setOnItemClickListener(new OnItemClickListener() { |
| 477 @Override | 454 @Override |
| 478 public void onItemClick(AdapterView<?> parent, View view, int positi
on, long id) { | 455 public void onItemClick(AdapterView<?> parent, View view, int positi
on, long id) { |
| 479 ResolveInfo info = adapter.getItem(position); | 456 ResolveInfo info = adapter.getItem(position); |
| 480 ActivityInfo ai = info.activityInfo; | 457 ActivityInfo ai = info.activityInfo; |
| 481 ComponentName component = | 458 ComponentName component = |
| 482 new ComponentName(ai.applicationInfo.packageName, ai.nam
e); | 459 new ComponentName(ai.applicationInfo.packageName, ai.nam
e); |
| 460 |
| 483 if (callback != null && !callbackCalled[0]) { | 461 if (callback != null && !callbackCalled[0]) { |
| 484 callback.onTargetChosen(component); | 462 callback.onTargetChosen(component); |
| 485 callbackCalled[0] = true; | 463 callbackCalled[0] = true; |
| 486 } | 464 } |
| 487 if (saveLastUsed) setLastShareComponentName(component); | 465 if (params.isSaveLastUsed()) setLastShareComponentName(component
); |
| 488 makeIntentAndShare(false, activity, title, text, url, offlineUri
, screenshotUri, | 466 makeIntentAndShare(params, component); |
| 489 component, null); | |
| 490 dialog.dismiss(); | 467 dialog.dismiss(); |
| 491 } | 468 } |
| 492 }); | 469 }); |
| 493 | 470 |
| 494 if (callback != null) { | 471 if (callback != null) { |
| 495 dialog.setOnDismissListener(new OnDismissListener() { | 472 dialog.setOnDismissListener(new OnDismissListener() { |
| 496 @Override | 473 @Override |
| 497 public void onDismiss(DialogInterface dialog) { | 474 public void onDismiss(DialogInterface dialog) { |
| 498 if (!callbackCalled[0]) { | 475 if (!callbackCalled[0]) { |
| 499 callback.onCancel(); | 476 callback.onCancel(); |
| 500 callbackCalled[0] = true; | 477 callbackCalled[0] = true; |
| 501 } | 478 } |
| 502 } | 479 } |
| 503 }); | 480 }); |
| 504 } | 481 } |
| 505 | 482 |
| 506 if (sFakeIntentReceiverForTesting != null) { | 483 if (sFakeIntentReceiverForTesting != null) { |
| 507 sFakeIntentReceiverForTesting.onCustomChooserShown(dialog); | 484 sFakeIntentReceiverForTesting.onCustomChooserShown(dialog); |
| 508 } | 485 } |
| 509 } | 486 } |
| 510 | 487 |
| 511 /** | 488 private static void makeIntentAndShare(ShareParams params, @Nullable Compone
ntName component) { |
| 512 * Starts a share intent with the activity that was most recently used to sh
are. | 489 Intent intent = getShareLinkIntent(params); |
| 513 * If there is no most recently used activity, it does nothing. | 490 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVI
TY_PREVIOUS_IS_TOP); |
| 514 * @param activity Activity that is used to start the share intent. | 491 intent.setComponent(component); |
| 515 * @param title Title of the page to be shared. | 492 if (intent.getComponent() != null) { |
| 516 * @param text Text to be shared. If both |text| and |url| are supplied, the
y are concatenated | 493 fireIntent(params.getActivity(), intent); |
| 517 * with a space. | |
| 518 * @param url URL of the page to be shared. | |
| 519 * @oaram offlineUri URI of the offline page to be shared. | |
| 520 * @param screenshotUri Uri of the screenshot of the page to be shared. | |
| 521 */ | |
| 522 private static void shareWithLastUsed(Activity activity, String title, Strin
g text, String url, | |
| 523 Uri offlineUri, Uri screenshotUri) { | |
| 524 ComponentName component = getLastShareComponentName(); | |
| 525 if (component == null) return; | |
| 526 makeIntentAndShare( | |
| 527 false, activity, title, text, url, offlineUri, screenshotUri, co
mponent, null); | |
| 528 } | |
| 529 | |
| 530 private static void shareIntent(boolean saveLastUsed, Activity activity, Int
ent sharingIntent, | |
| 531 @Nullable TargetChosenCallback callback) { | |
| 532 if (sharingIntent.getComponent() != null) { | |
| 533 // If a component was specified, there should not also be a callback
. | |
| 534 assert callback == null; | |
| 535 fireIntent(activity, sharingIntent); | |
| 536 } else { | 494 } else { |
| 537 assert TargetChosenReceiver.isSupported(); | 495 assert TargetChosenReceiver.isSupported(); |
| 538 TargetChosenReceiver.sendChooserIntent(saveLastUsed, activity, shari
ngIntent, callback); | 496 TargetChosenReceiver.sendChooserIntent( |
| 497 params.isSaveLastUsed(), params.getActivity(), intent, param
s.getCallback()); |
| 539 } | 498 } |
| 540 } | 499 } |
| 541 | 500 |
| 542 private static void makeIntentAndShare(final boolean saveLastUsed, final Act
ivity activity, | |
| 543 final String title, final String text, final String url, final Uri o
fflineUri, | |
| 544 final Uri screenshotUri, final ComponentName component, | |
| 545 @Nullable final TargetChosenCallback callback) { | |
| 546 Intent intent = getDirectShareIntentForComponent( | |
| 547 activity, title, text, url, offlineUri, screenshotUri, component
); | |
| 548 shareIntent(saveLastUsed, activity, intent, callback); | |
| 549 } | |
| 550 | |
| 551 /** | 501 /** |
| 552 * Set the icon and the title for the menu item used for direct share. | 502 * Set the icon and the title for the menu item used for direct share. |
| 553 * | 503 * |
| 554 * @param activity Activity that is used to access the package manager. | 504 * @param activity Activity that is used to access the package manager. |
| 555 * @param item The menu item that is used for direct share | 505 * @param item The menu item that is used for direct share |
| 556 */ | 506 */ |
| 557 public static void configureDirectShareMenuItem(Activity activity, MenuItem
item) { | 507 public static void configureDirectShareMenuItem(Activity activity, MenuItem
item) { |
| 558 Intent shareIntent = getShareIntent(activity, "", "", "", null, null); | 508 Intent shareIntent = getShareLinkAppCompatibilityIntent(); |
| 559 Pair<Drawable, CharSequence> directShare = getShareableIconAndName(activ
ity, shareIntent); | 509 Pair<Drawable, CharSequence> directShare = getShareableIconAndName(activ
ity, shareIntent); |
| 560 Drawable directShareIcon = directShare.first; | 510 Drawable directShareIcon = directShare.first; |
| 561 CharSequence directShareTitle = directShare.second; | 511 CharSequence directShareTitle = directShare.second; |
| 562 | 512 |
| 563 item.setIcon(directShareIcon); | 513 item.setIcon(directShareIcon); |
| 564 if (directShareTitle != null) { | 514 if (directShareTitle != null) { |
| 565 item.setTitle( | 515 item.setTitle( |
| 566 activity.getString(R.string.accessibility_menu_share_via, di
rectShareTitle)); | 516 activity.getString(R.string.accessibility_menu_share_via, di
rectShareTitle)); |
| 567 } | 517 } |
| 568 } | 518 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 @VisibleForTesting | 592 @VisibleForTesting |
| 643 public static void setLastShareComponentName(ComponentName component) { | 593 public static void setLastShareComponentName(ComponentName component) { |
| 644 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); | 594 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); |
| 645 SharedPreferences.Editor editor = preferences.edit(); | 595 SharedPreferences.Editor editor = preferences.edit(); |
| 646 editor.putString(PACKAGE_NAME_KEY, component.getPackageName()); | 596 editor.putString(PACKAGE_NAME_KEY, component.getPackageName()); |
| 647 editor.putString(CLASS_NAME_KEY, component.getClassName()); | 597 editor.putString(CLASS_NAME_KEY, component.getClassName()); |
| 648 editor.apply(); | 598 editor.apply(); |
| 649 } | 599 } |
| 650 | 600 |
| 651 @VisibleForTesting | 601 @VisibleForTesting |
| 652 public static Intent getShareIntent(Activity activity, String title, String
text, String url, | 602 public static Intent getShareLinkIntent(ShareParams params) { |
| 653 Uri offlineUri, Uri screenshotUri) { | 603 String url = params.getUrl(); |
| 604 String text = params.getText(); |
| 654 if (!TextUtils.isEmpty(url)) { | 605 if (!TextUtils.isEmpty(url)) { |
| 655 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); | 606 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); |
| 656 if (!TextUtils.isEmpty(text)) { | 607 if (!TextUtils.isEmpty(text)) { |
| 657 // Concatenate text and URL with a space. | 608 // Concatenate text and URL with a space. |
| 658 text = text + " " + url; | 609 text = text + " " + url; |
| 659 } else { | 610 } else { |
| 660 text = url; | 611 text = url; |
| 661 } | 612 } |
| 662 } | 613 } |
| 663 | 614 |
| 664 Intent intent = new Intent(Intent.ACTION_SEND); | 615 Intent intent = new Intent(Intent.ACTION_SEND); |
| 665 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag()); | 616 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag()); |
| 666 intent.putExtra(Intent.EXTRA_SUBJECT, title); | 617 intent.putExtra(Intent.EXTRA_SUBJECT, params.getTitle()); |
| 667 intent.putExtra(Intent.EXTRA_TEXT, text); | 618 intent.putExtra(Intent.EXTRA_TEXT, text); |
| 668 intent.putExtra(EXTRA_TASK_ID, activity.getTaskId()); | 619 intent.putExtra(EXTRA_TASK_ID, params.getActivity().getTaskId()); |
| 669 | 620 |
| 621 Uri screenshotUri = params.getScreenshotUri(); |
| 670 if (screenshotUri != null) { | 622 if (screenshotUri != null) { |
| 671 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | 623 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
| 672 } | |
| 673 if (screenshotUri != null) { | |
| 674 // To give read access to an Intent target, we need to put |screensh
otUri| in clipData | 624 // To give read access to an Intent target, we need to put |screensh
otUri| in clipData |
| 675 // because adding Intent.FLAG_GRANT_READ_URI_PERMISSION doesn't work
for | 625 // because adding Intent.FLAG_GRANT_READ_URI_PERMISSION doesn't work
for |
| 676 // EXTRA_SHARE_SCREENSHOT_AS_STREAM. | 626 // EXTRA_SHARE_SCREENSHOT_AS_STREAM. |
| 677 intent.setClipData(ClipData.newRawUri("", screenshotUri)); | 627 intent.setClipData(ClipData.newRawUri("", screenshotUri)); |
| 678 intent.putExtra(EXTRA_SHARE_SCREENSHOT_AS_STREAM, screenshotUri); | 628 intent.putExtra(EXTRA_SHARE_SCREENSHOT_AS_STREAM, screenshotUri); |
| 679 } | 629 } |
| 680 if (offlineUri == null) { | 630 if (params.getOfflineUri() == null) { |
| 681 intent.setType("text/plain"); | 631 intent.setType("text/plain"); |
| 682 } else { | 632 } else { |
| 683 intent.setType("multipart/related"); | 633 intent.setType("multipart/related"); |
| 684 intent.putExtra(Intent.EXTRA_STREAM, offlineUri); | 634 intent.putExtra(Intent.EXTRA_STREAM, params.getOfflineUri()); |
| 685 } | 635 } |
| 686 return intent; | 636 return intent; |
| 687 } | 637 } |
| 688 | 638 |
| 689 /** | 639 /** |
| 690 * Creates an Intent to share an image. | 640 * Creates an Intent to share an image. |
| 691 * @param imageUri The Uri of the image. | 641 * @param imageUri The Uri of the image. |
| 692 * @return The Intent used to share the image. | 642 * @return The Intent used to share the image. |
| 693 */ | 643 */ |
| 694 public static Intent getShareImageIntent(Uri imageUri) { | 644 public static Intent getShareImageIntent(Uri imageUri) { |
| 695 Intent intent = new Intent(Intent.ACTION_SEND); | 645 Intent intent = new Intent(Intent.ACTION_SEND); |
| 696 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag()); | 646 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag()); |
| 697 intent.setType("image/jpeg"); | 647 intent.setType("image/jpeg"); |
| 698 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | 648 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
| 699 intent.putExtra(Intent.EXTRA_STREAM, imageUri); | 649 intent.putExtra(Intent.EXTRA_STREAM, imageUri); |
| 700 return intent; | 650 return intent; |
| 701 } | 651 } |
| 702 | 652 |
| 703 private static Intent getDirectShareIntentForComponent(Activity activity, St
ring title, | 653 /** |
| 704 String text, String url, Uri offlineUri, Uri screenshotUri, Componen
tName component) { | 654 * Convenience method to create an Intent to retrieve all the apps support s
haring text. |
| 705 Intent intent = getShareIntent(activity, title, text, url, offlineUri, s
creenshotUri); | 655 */ |
| 706 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | 656 public static Intent getShareLinkAppCompatibilityIntent() { |
| 707 | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); | 657 Intent intent = new Intent(Intent.ACTION_SEND); |
| 708 intent.setComponent(component); | 658 intent.addFlags(ApiCompatibilityUtils.getActivityNewDocumentFlag()); |
| 659 intent.putExtra(Intent.EXTRA_SUBJECT, ""); |
| 660 intent.putExtra(Intent.EXTRA_TEXT, ""); |
| 661 intent.setType("text/plain"); |
| 709 return intent; | 662 return intent; |
| 710 } | 663 } |
| 711 | 664 |
| 712 /** | 665 /** |
| 713 * Gets the {@link ComponentName} of the app that was used to last share. | 666 * Gets the {@link ComponentName} of the app that was used to last share. |
| 714 */ | 667 */ |
| 715 @Nullable | 668 @Nullable |
| 716 public static ComponentName getLastShareComponentName() { | 669 public static ComponentName getLastShareComponentName() { |
| 717 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); | 670 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); |
| 718 String packageName = preferences.getString(PACKAGE_NAME_KEY, null); | 671 String packageName = preferences.getString(PACKAGE_NAME_KEY, null); |
| 719 String className = preferences.getString(CLASS_NAME_KEY, null); | 672 String className = preferences.getString(CLASS_NAME_KEY, null); |
| 720 if (packageName == null || className == null) return null; | 673 if (packageName == null || className == null) return null; |
| 721 return new ComponentName(packageName, className); | 674 return new ComponentName(packageName, className); |
| 722 } | 675 } |
| 723 } | 676 } |
| OLD | NEW |