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 24 matching lines...) Expand all Loading... | |
35 | 35 |
36 import org.chromium.base.ApiCompatibilityUtils; | 36 import org.chromium.base.ApiCompatibilityUtils; |
37 import org.chromium.base.ApplicationState; | 37 import org.chromium.base.ApplicationState; |
38 import org.chromium.base.ApplicationStatus; | 38 import org.chromium.base.ApplicationStatus; |
39 import org.chromium.base.ContextUtils; | 39 import org.chromium.base.ContextUtils; |
40 import org.chromium.base.Log; | 40 import org.chromium.base.Log; |
41 import org.chromium.base.VisibleForTesting; | 41 import org.chromium.base.VisibleForTesting; |
42 import org.chromium.base.annotations.SuppressFBWarnings; | 42 import org.chromium.base.annotations.SuppressFBWarnings; |
43 import org.chromium.base.metrics.RecordHistogram; | 43 import org.chromium.base.metrics.RecordHistogram; |
44 import org.chromium.chrome.R; | 44 import org.chromium.chrome.R; |
45 import org.chromium.chrome.browser.BlockingFileProvider; | |
45 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; | 46 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; |
46 import org.chromium.ui.UiUtils; | 47 import org.chromium.ui.UiUtils; |
47 | 48 |
48 import java.io.File; | 49 import java.io.File; |
49 import java.io.FileOutputStream; | 50 import java.io.FileOutputStream; |
50 import java.io.IOException; | 51 import java.io.IOException; |
51 import java.util.Collections; | 52 import java.util.Collections; |
52 import java.util.List; | 53 import java.util.List; |
53 import java.util.concurrent.ExecutionException; | 54 import java.util.concurrent.ExecutionException; |
54 import java.util.concurrent.TimeUnit; | 55 import java.util.concurrent.TimeUnit; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 * | 206 * |
206 * @param shareDirectly Whether it should share directly with the activity t hat was most | 207 * @param shareDirectly Whether it should share directly with the activity t hat was most |
207 * recently used to share. | 208 * recently used to share. |
208 * @param saveLastUsed Whether to save the chosen activity for future direct sharing. | 209 * @param saveLastUsed Whether to save the chosen activity for future direct sharing. |
209 * @param activity Activity that is used to access package manager. | 210 * @param activity Activity that is used to access package manager. |
210 * @param title Title of the page to be shared. | 211 * @param title Title of the page to be shared. |
211 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated | 212 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated |
212 * with a space. | 213 * with a space. |
213 * @param url URL of the page to be shared. | 214 * @param url URL of the page to be shared. |
214 * @param offlineUri URI to the offline MHTML file to be shared. | 215 * @param offlineUri URI to the offline MHTML file to be shared. |
215 * @param screenshot Screenshot of the page to be shared. | 216 * @param screenshotUri Uri of the screenshot of the page to be shared. |
216 * @param callback Optional callback to be called when user makes a choice. Will not be called | 217 * @param callback Optional callback to be called when user makes a choice. Will not be called |
217 * if receiving a response when the user makes a choice is n ot supported (on | 218 * if receiving a response when the user makes a choice is n ot supported (on |
218 * older Android versions). | 219 * older Android versions). |
219 */ | 220 */ |
220 public static void share(boolean shareDirectly, boolean saveLastUsed, Activi ty activity, | 221 public static void share(boolean shareDirectly, boolean saveLastUsed, Activi ty activity, |
221 String title, String text, String url, @Nullable Uri offlineUri, Bit map screenshot, | 222 String title, String text, String url, @Nullable Uri offlineUri, Uri screenshotUri, |
222 @Nullable TargetChosenCallback callback) { | 223 @Nullable TargetChosenCallback callback) { |
223 if (shareDirectly) { | 224 if (shareDirectly) { |
224 shareWithLastUsed(activity, title, text, url, offlineUri, screenshot ); | 225 shareWithLastUsed(activity, title, text, url, offlineUri, screenshot Uri); |
225 } else if (TargetChosenReceiver.isSupported()) { | 226 } else if (TargetChosenReceiver.isSupported()) { |
226 makeIntentAndShare(saveLastUsed, activity, title, text, url, offline Uri, screenshot, | 227 makeIntentAndShare(saveLastUsed, activity, title, text, url, offline Uri, screenshotUri, |
227 null, callback); | 228 null, callback); |
228 } else { | 229 } else { |
229 showShareDialog( | 230 showShareDialog( |
230 saveLastUsed, activity, title, text, url, offlineUri, screen shot, callback); | 231 saveLastUsed, activity, title, text, url, offlineUri, screen shotUri, callback); |
231 } | 232 } |
232 } | 233 } |
233 | 234 |
234 /** | 235 /** |
235 * Trigger the share action for the given image data. | 236 * Trigger the share action for the given image data. |
236 * @param activity The activity used to trigger the share action. | 237 * @param activity The activity used to trigger the share action. |
237 * @param jpegImageData The image data to be shared in jpeg format. | 238 * @param jpegImageData The image data to be shared in jpeg format. |
238 */ | 239 */ |
239 public static void shareImage(final Activity activity, final byte[] jpegImag eData) { | 240 public static void shareImage(final Activity activity, final byte[] jpegImag eData) { |
240 if (jpegImageData.length == 0) { | 241 if (jpegImageData.length == 0) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 | 285 |
285 Intent chooserIntent = Intent.createChooser(getShareImageInt ent(imageUri), | 286 Intent chooserIntent = Intent.createChooser(getShareImageInt ent(imageUri), |
286 activity.getString(R.string.share_link_chooser_title )); | 287 activity.getString(R.string.share_link_chooser_title )); |
287 activity.startActivity(chooserIntent); | 288 activity.startActivity(chooserIntent); |
288 } | 289 } |
289 } | 290 } |
290 }.execute(); | 291 }.execute(); |
291 } | 292 } |
292 | 293 |
293 /** | 294 /** |
295 * Writes the screenshot file and notifies the file provider that the file i s ready to be | |
296 * accessed by the client. | |
297 * | |
298 * The bitmap is compressed to JPEG before being written to the file. | |
299 * | |
300 * @param uuidUri The unique id given by the BlockingFileProvider for the sc reenshot. | |
Ted C
2016/08/27 00:22:12
you can use {@link BlockingFileProvider} or if you
ssid
2016/09/06 22:25:36
Done.
| |
301 * @param screenshot The screenshot bitmap to be written to file. | |
302 * @param activity Activity that is used to access package manager. | |
303 */ | |
304 public static void onScreenshotReady( | |
305 final Uri uuidUri, final Bitmap screenshot, final Activity activity) { | |
306 if (screenshot == null) { | |
307 BlockingFileProvider.notifyFileReady(uuidUri, null); | |
308 return; | |
309 } | |
310 | |
311 new AsyncTask<Void, Void, File>() { | |
312 @Override | |
313 protected File doInBackground(Void... params) { | |
314 FileOutputStream fOut = null; | |
315 try { | |
316 File path = new File(UiUtils.getDirectoryForImageCapture(act ivity) + "/" | |
317 + SHARE_IMAGES_DIRECTORY_NAME); | |
318 if (path.exists() || path.mkdir()) { | |
319 String fileName = String.valueOf(System.currentTimeMilli s()); | |
320 File saveFile = File.createTempFile(fileName, JPEG_EXTEN SION, path); | |
321 fOut = new FileOutputStream(saveFile); | |
322 screenshot.compress(Bitmap.CompressFormat.JPEG, 85, fOut ); | |
323 fOut.flush(); | |
324 fOut.close(); | |
325 return saveFile; | |
326 } | |
327 } catch (IOException ie) { | |
328 if (fOut != null) { | |
329 try { | |
330 fOut.close(); | |
331 } catch (IOException e) { | |
332 // Ignore exception. | |
333 } | |
334 } | |
335 } | |
336 | |
337 return null; | |
338 } | |
339 | |
340 @Override | |
341 protected void onPostExecute(File saveFile) { | |
342 Uri fileUri = null; | |
343 if (ApplicationStatus.getStateForApplication() | |
344 != ApplicationState.HAS_DESTROYED_ACTIVITIES | |
Ted C
2016/08/27 00:22:12
decrease indent, should be 8 from the previous lin
ssid
2016/09/06 22:25:36
Sorry, I fixed and git cl format changed back. Sto
| |
345 && saveFile != null) { | |
346 fileUri = UiUtils.getUriForImageCaptureFile(activity, saveFi le); | |
347 } | |
348 BlockingFileProvider.notifyFileReady(uuidUri, fileUri); | |
349 } | |
350 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | |
351 } | |
352 | |
353 /** | |
294 * Creates and shows a share intent picker dialog. | 354 * Creates and shows a share intent picker dialog. |
295 * | 355 * |
296 * @param saveLastUsed Whether to save the chosen activity for future direct sharing. | 356 * @param saveLastUsed Whether to save the chosen activity for future direct sharing. |
297 * @param activity Activity that is used to access package manager. | 357 * @param activity Activity that is used to access package manager. |
298 * @param title Title of the page to be shared. | 358 * @param title Title of the page to be shared. |
299 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated | 359 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated |
300 * with a space. | 360 * with a space. |
301 * @param url URL of the page to be shared. | 361 * @param url URL of the page to be shared. |
302 * @oaram Uri URI of the offline page to be shared. | 362 * @oaram offlineUri URI of the offline page to be shared. |
303 * @param screenshot Screenshot of the page to be shared. | 363 * @param screenshotUri Uri of the screenshot of the page to be shared. |
304 * @param callback Optional callback to be called when user makes a choice. Will not be called | 364 * @param callback Optional callback to be called when user makes a choice. Will not be called |
305 * if receiving a response when the user makes a choice is n ot supported (on | 365 * if receiving a response when the user makes a choice is n ot supported (on |
306 * older Android versions). | 366 * older Android versions). |
307 */ | 367 */ |
308 private static void showShareDialog(final boolean saveLastUsed, final Activi ty activity, | 368 private static void showShareDialog(final boolean saveLastUsed, final Activi ty activity, |
309 final String title, final String text, final String url, final Uri o fflineUri, | 369 final String title, final String text, final String url, final Uri o fflineUri, |
310 final Bitmap screenshot, @Nullable final TargetChosenCallback callba ck) { | 370 final Uri screenshotUri, @Nullable final TargetChosenCallback callba ck) { |
311 Intent intent = getShareIntent(activity, title, text, url, null, null); | 371 Intent intent = getShareIntent(activity, title, text, url, null, null); |
312 PackageManager manager = activity.getPackageManager(); | 372 PackageManager manager = activity.getPackageManager(); |
313 List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent , 0); | 373 List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent , 0); |
314 assert resolveInfoList.size() > 0; | 374 assert resolveInfoList.size() > 0; |
315 if (resolveInfoList.size() == 0) return; | 375 if (resolveInfoList.size() == 0) return; |
316 Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator( manager)); | 376 Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator( manager)); |
317 | 377 |
318 final ShareDialogAdapter adapter = | 378 final ShareDialogAdapter adapter = |
319 new ShareDialogAdapter(activity, manager, resolveInfoList); | 379 new ShareDialogAdapter(activity, manager, resolveInfoList); |
320 AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style. AlertDialogTheme); | 380 AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style. AlertDialogTheme); |
321 builder.setTitle(activity.getString(R.string.share_link_chooser_title)); | 381 builder.setTitle(activity.getString(R.string.share_link_chooser_title)); |
322 builder.setAdapter(adapter, null); | 382 builder.setAdapter(adapter, null); |
323 | 383 |
324 final AlertDialog dialog = builder.create(); | 384 final AlertDialog dialog = builder.create(); |
325 dialog.show(); | 385 dialog.show(); |
326 dialog.getListView().setOnItemClickListener(new OnItemClickListener() { | 386 dialog.getListView().setOnItemClickListener(new OnItemClickListener() { |
327 @Override | 387 @Override |
328 public void onItemClick(AdapterView<?> parent, View view, int positi on, long id) { | 388 public void onItemClick(AdapterView<?> parent, View view, int positi on, long id) { |
329 ResolveInfo info = adapter.getItem(position); | 389 ResolveInfo info = adapter.getItem(position); |
330 ActivityInfo ai = info.activityInfo; | 390 ActivityInfo ai = info.activityInfo; |
331 ComponentName component = | 391 ComponentName component = |
332 new ComponentName(ai.applicationInfo.packageName, ai.nam e); | 392 new ComponentName(ai.applicationInfo.packageName, ai.nam e); |
333 if (callback != null) callback.onTargetChosen(component); | 393 if (callback != null) callback.onTargetChosen(component); |
334 if (saveLastUsed) setLastShareComponentName(component); | 394 if (saveLastUsed) setLastShareComponentName(component); |
335 makeIntentAndShare( | 395 makeIntentAndShare(false, activity, title, text, url, offlineUri , screenshotUri, |
336 false, activity, title, text, url, offlineUri, screensho t, component, null); | 396 component, null); |
337 dialog.dismiss(); | 397 dialog.dismiss(); |
338 } | 398 } |
339 }); | 399 }); |
340 } | 400 } |
341 | 401 |
342 /** | 402 /** |
343 * Starts a share intent with the activity that was most recently used to sh are. | 403 * Starts a share intent with the activity that was most recently used to sh are. |
344 * If there is no most recently used activity, it does nothing. | 404 * If there is no most recently used activity, it does nothing. |
345 * @param activity Activity that is used to start the share intent. | 405 * @param activity Activity that is used to start the share intent. |
346 * @param title Title of the page to be shared. | 406 * @param title Title of the page to be shared. |
347 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated | 407 * @param text Text to be shared. If both |text| and |url| are supplied, the y are concatenated |
348 * with a space. | 408 * with a space. |
349 * @param url URL of the page to be shared. | 409 * @param url URL of the page to be shared. |
350 * @oaram Uri URI of the offline page to be shared. | 410 * @oaram offlineUri URI of the offline page to be shared. |
351 * @param screenshot Screenshot of the page to be shared. | 411 * @param screenshotUri Uri of the screenshot of the page to be shared. |
352 */ | 412 */ |
353 private static void shareWithLastUsed(Activity activity, String title, Strin g text, String url, | 413 private static void shareWithLastUsed(Activity activity, String title, Strin g text, String url, |
354 Uri offlineUri, Bitmap screenshot) { | 414 Uri offlineUri, Uri screenshotUri) { |
355 ComponentName component = getLastShareComponentName(); | 415 ComponentName component = getLastShareComponentName(); |
356 if (component == null) return; | 416 if (component == null) return; |
357 makeIntentAndShare( | 417 makeIntentAndShare( |
358 false, activity, title, text, url, offlineUri, screenshot, compo nent, null); | 418 false, activity, title, text, url, offlineUri, screenshotUri, co mponent, null); |
359 } | 419 } |
360 | 420 |
361 private static void shareIntent(boolean saveLastUsed, Activity activity, Int ent sharingIntent, | 421 private static void shareIntent(boolean saveLastUsed, Activity activity, Int ent sharingIntent, |
362 @Nullable TargetChosenCallback callback) { | 422 @Nullable TargetChosenCallback callback) { |
363 if (sharingIntent.getComponent() != null) { | 423 if (sharingIntent.getComponent() != null) { |
364 // If a component was specified, there should not also be a callback . | 424 // If a component was specified, there should not also be a callback . |
365 assert callback == null; | 425 assert callback == null; |
366 activity.startActivity(sharingIntent); | 426 activity.startActivity(sharingIntent); |
367 } else { | 427 } else { |
368 assert TargetChosenReceiver.isSupported(); | 428 assert TargetChosenReceiver.isSupported(); |
369 TargetChosenReceiver.sendChooserIntent(saveLastUsed, activity, shari ngIntent, callback); | 429 TargetChosenReceiver.sendChooserIntent(saveLastUsed, activity, shari ngIntent, callback); |
370 } | 430 } |
371 } | 431 } |
372 | 432 |
373 private static void makeIntentAndShare(final boolean saveLastUsed, final Act ivity activity, | 433 private static void makeIntentAndShare(final boolean saveLastUsed, final Act ivity activity, |
374 final String title, final String text, final String url, final Uri o fflineUri, | 434 final String title, final String text, final String url, final Uri o fflineUri, |
375 final Bitmap screenshot, final ComponentName component, | 435 final Uri screenshotUri, final ComponentName component, |
376 @Nullable final TargetChosenCallback callback) { | 436 @Nullable final TargetChosenCallback callback) { |
377 if (screenshot == null) { | 437 Intent intent = getDirectShareIntentForComponent( |
378 Intent intent = getDirectShareIntentForComponent( | 438 activity, title, text, url, offlineUri, screenshotUri, component ); |
379 activity, title, text, url, offlineUri, null, component); | 439 shareIntent(saveLastUsed, activity, intent, callback); |
380 shareIntent(saveLastUsed, activity, intent, callback); | |
381 } else { | |
382 new AsyncTask<Void, Void, File>() { | |
383 @Override | |
384 protected File doInBackground(Void... params) { | |
385 FileOutputStream fOut = null; | |
386 try { | |
387 File path = new File(UiUtils.getDirectoryForImageCapture (activity), | |
388 SHARE_IMAGES_DIRECTORY_NAME); | |
389 if (path.exists() || path.mkdir()) { | |
390 File saveFile = File.createTempFile( | |
391 String.valueOf(System.currentTimeMillis()), | |
392 JPEG_EXTENSION, path); | |
393 fOut = new FileOutputStream(saveFile); | |
394 screenshot.compress(Bitmap.CompressFormat.JPEG, 85, fOut); | |
395 fOut.flush(); | |
396 fOut.close(); | |
397 | |
398 return saveFile; | |
399 } | |
400 } catch (IOException ie) { | |
401 if (fOut != null) { | |
402 try { | |
403 fOut.close(); | |
404 } catch (IOException e) { | |
405 // Ignore exception. | |
406 } | |
407 } | |
408 } | |
409 | |
410 return null; | |
411 } | |
412 | |
413 @Override | |
414 protected void onPostExecute(File saveFile) { | |
415 if (ApplicationStatus.getStateForApplication() | |
416 != ApplicationState.HAS_DESTROYED_ACTIVITIES) { | |
417 Uri screenshotUri = saveFile == null | |
418 ? null : UiUtils.getUriForImageCaptureFile(activ ity, saveFile); | |
419 shareIntent(saveLastUsed, activity, | |
420 getDirectShareIntentForComponent(activity, title , text, url, | |
421 offlineUri, screenshotUri, component ), | |
422 callback); | |
423 } | |
424 } | |
425 }.execute(); | |
426 } | |
427 } | 440 } |
428 | 441 |
429 /** | 442 /** |
430 * Set the icon and the title for the menu item used for direct share. | 443 * Set the icon and the title for the menu item used for direct share. |
431 * | 444 * |
432 * @param activity Activity that is used to access the package manager. | 445 * @param activity Activity that is used to access the package manager. |
433 * @param item The menu item that is used for direct share | 446 * @param item The menu item that is used for direct share |
434 */ | 447 */ |
435 public static void configureDirectShareMenuItem(Activity activity, MenuItem item) { | 448 public static void configureDirectShareMenuItem(Activity activity, MenuItem item) { |
436 Drawable directShareIcon = null; | 449 Drawable directShareIcon = null; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 "Android.IsLastSharedAppInfoRetrieved", retrieved); | 503 "Android.IsLastSharedAppInfoRetrieved", retrieved); |
491 } | 504 } |
492 | 505 |
493 item.setIcon(directShareIcon); | 506 item.setIcon(directShareIcon); |
494 if (directShareTitle != null) { | 507 if (directShareTitle != null) { |
495 item.setTitle(activity.getString(R.string.accessibility_menu_share_v ia, | 508 item.setTitle(activity.getString(R.string.accessibility_menu_share_v ia, |
496 directShareTitle)); | 509 directShareTitle)); |
497 } | 510 } |
498 } | 511 } |
499 | 512 |
513 /* | |
514 * Stores the component selected for sharing last time share was called. | |
515 * | |
516 * This method is public since it is used in tests to avoid creating share d ialog. | |
517 */ | |
518 @VisibleForTesting | |
519 public static void setLastShareComponentName(ComponentName component) { | |
520 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); | |
521 SharedPreferences.Editor editor = preferences.edit(); | |
522 editor.putString(PACKAGE_NAME_KEY, component.getPackageName()); | |
523 editor.putString(CLASS_NAME_KEY, component.getClassName()); | |
524 editor.apply(); | |
525 } | |
526 | |
500 @VisibleForTesting | 527 @VisibleForTesting |
501 public static Intent getShareIntent(Activity activity, String title, String text, String url, | 528 public static Intent getShareIntent(Activity activity, String title, String text, String url, |
502 Uri offlineUri, Uri screenshotUri) { | 529 Uri offlineUri, Uri screenshotUri) { |
503 if (!TextUtils.isEmpty(url)) { | 530 if (!TextUtils.isEmpty(url)) { |
504 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); | 531 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); |
505 if (!TextUtils.isEmpty(text)) { | 532 if (!TextUtils.isEmpty(text)) { |
506 // Concatenate text and URL with a space. | 533 // Concatenate text and URL with a space. |
507 text = text + " " + url; | 534 text = text + " " + url; |
508 } else { | 535 } else { |
509 text = url; | 536 text = url; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
553 return intent; | 580 return intent; |
554 } | 581 } |
555 | 582 |
556 private static ComponentName getLastShareComponentName() { | 583 private static ComponentName getLastShareComponentName() { |
557 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); | 584 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); |
558 String packageName = preferences.getString(PACKAGE_NAME_KEY, null); | 585 String packageName = preferences.getString(PACKAGE_NAME_KEY, null); |
559 String className = preferences.getString(CLASS_NAME_KEY, null); | 586 String className = preferences.getString(CLASS_NAME_KEY, null); |
560 if (packageName == null || className == null) return null; | 587 if (packageName == null || className == null) return null; |
561 return new ComponentName(packageName, className); | 588 return new ComponentName(packageName, className); |
562 } | 589 } |
563 | |
564 private static void setLastShareComponentName(ComponentName component) { | |
565 SharedPreferences preferences = ContextUtils.getAppSharedPreferences(); | |
566 SharedPreferences.Editor editor = preferences.edit(); | |
567 editor.putString(PACKAGE_NAME_KEY, component.getPackageName()); | |
568 editor.putString(CLASS_NAME_KEY, component.getClassName()); | |
569 editor.apply(); | |
570 } | |
571 } | 590 } |
OLD | NEW |