Upstream version 8.36.169.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core_internal / src / org / xwalk / core / internal / XWalkLaunchScreenManager.java
1 // Copyright (c) 2014 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.xwalk.core.internal;
6
7 import java.lang.Runnable;
8 import java.util.ArrayList;
9
10 import android.app.Activity;
11 import android.app.Dialog;
12 import android.content.BroadcastReceiver;
13 import android.content.Context;
14 import android.content.DialogInterface;
15 import android.content.Intent;
16 import android.content.IntentFilter;
17 import android.content.res.Configuration;
18 import android.graphics.Bitmap;
19 import android.graphics.BitmapFactory;
20 import android.graphics.drawable.BitmapDrawable;
21 import android.graphics.drawable.Drawable;
22 import android.graphics.Point;
23 import android.graphics.Rect;
24 import android.graphics.Shader.TileMode;
25 import android.hardware.SensorManager;
26 import android.os.Bundle;
27 import android.util.DisplayMetrics;
28 import android.util.Log;
29 import android.util.TypedValue;
30 import android.view.Display;
31 import android.view.Gravity;
32 import android.view.KeyEvent;
33 import android.view.OrientationEventListener;
34 import android.view.View;
35 import android.view.ViewGroup;
36 import android.view.Window;
37 import android.view.WindowManager;
38 import android.widget.FrameLayout;
39 import android.widget.ImageView;
40 import android.widget.ImageView.ScaleType;
41 import android.widget.LinearLayout;
42 import android.widget.RelativeLayout;
43
44 import org.chromium.content.browser.ContentViewRenderView.FirstRenderedFrameListener;
45
46 /**
47  * Provisionally set it as public due to the use of launch screen extension.
48  * @hide
49  */
50 public class XWalkLaunchScreenManager
51         implements FirstRenderedFrameListener, DialogInterface.OnShowListener,
52                    DialogInterface.OnDismissListener, PageLoadListener {
53     // This string will be initialized before extension initialized,
54     // and used by LaunchScreenExtension.
55     private static String mIntentFilterStr;
56
57     private final static String BORDER_MODE_REPEAT = "repeat";
58     private final static String BORDER_MODE_STRETCH = "stretch";
59     private final static String BORDER_MODE_ROUND = "round";
60
61     private XWalkViewInternal mXWalkView;
62     private Activity mActivity;
63     private Context mLibContext;
64     private Dialog mLaunchScreenDialog;
65     private boolean mPageLoadFinished;
66     private ReadyWhenType mReadyWhen;
67     private boolean mFirstFrameReceived;
68     private BroadcastReceiver mLaunchScreenReadyWhenReceiver;
69     private boolean mCustomHideLaunchScreen;
70     private int mCurrentOrientation;
71     private OrientationEventListener mOrientationListener;
72
73     private enum ReadyWhenType {
74         FIRST_PAINT,
75         USER_INTERACTIVE,
76         COMPLETE,
77         CUSTOM
78     }
79
80     private enum BorderModeType {
81         REPEAT,
82         STRETCH,
83         ROUND,
84         NONE
85     }
86
87     public XWalkLaunchScreenManager(Context context, XWalkViewInternal xwView) {
88         mXWalkView = xwView;
89         mLibContext = context;
90         mActivity = mXWalkView.getActivity();
91         mIntentFilterStr = mActivity.getPackageName() + ".hideLaunchScreen";
92     }
93
94     public void displayLaunchScreen(String readyWhen, final String imageBorderList) {
95         if (mXWalkView == null) return;
96         setReadyWhen(readyWhen);
97
98         Runnable runnable = new Runnable() {
99            public void run() {
100                 int bgResId = mActivity.getResources().getIdentifier(
101                         "launchscreen_bg", "drawable", mActivity.getPackageName());
102                 if (bgResId == 0) return;
103                 Drawable bgDrawable = mActivity.getResources().getDrawable(bgResId);
104                 if (bgDrawable == null) return;
105
106                 mLaunchScreenDialog = new Dialog(mLibContext,
107                                                  android.R.style.Theme_Holo_Light_NoActionBar);
108                 if ((mActivity.getWindow().getAttributes().flags &
109                      WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) {
110                     mLaunchScreenDialog.getWindow().setFlags(
111                             WindowManager.LayoutParams.FLAG_FULLSCREEN,
112                             WindowManager.LayoutParams.FLAG_FULLSCREEN);
113                 }
114                 mLaunchScreenDialog.setOnKeyListener(new Dialog.OnKeyListener() {
115                     @Override
116                     public boolean onKey(DialogInterface arg0, int keyCode,
117                             KeyEvent event) {
118                         if (keyCode == KeyEvent.KEYCODE_BACK) {
119                             performHideLaunchScreen();
120                             mActivity.onBackPressed();
121                         }
122                         return true;
123                     }
124                 });
125                 mLaunchScreenDialog.setOnShowListener(XWalkLaunchScreenManager.this);
126                 mLaunchScreenDialog.setOnDismissListener(XWalkLaunchScreenManager.this);
127                 // Set background
128                 mLaunchScreenDialog.getWindow().setBackgroundDrawable(bgDrawable);
129                 // Set foreground image
130                 RelativeLayout root = getLaunchScreenLayout(imageBorderList);
131                 // The root layout can be null when there is no 'image' provided in the manifest.
132                 // We can just display the background instead of no launch screen dialog displayed.
133                 if (root != null) mLaunchScreenDialog.setContentView(root);
134                 mLaunchScreenDialog.show();
135
136                 // Change the layout depends on the orientation change.
137                 mOrientationListener = new OrientationEventListener(mActivity,
138                         SensorManager.SENSOR_DELAY_NORMAL) {
139                     public void onOrientationChanged(int ori) {
140                         if (mLaunchScreenDialog == null || !mLaunchScreenDialog.isShowing()) {
141                             return;
142                         }
143                         int orientation = getScreenOrientation();
144                         if (orientation != mCurrentOrientation) {
145                             RelativeLayout root = getLaunchScreenLayout(imageBorderList);
146                             if (root == null) return;
147                             mLaunchScreenDialog.setContentView(root);
148                         }
149                     }
150                 };
151                 mOrientationListener.enable();
152                 if (mReadyWhen == ReadyWhenType.CUSTOM) registerBroadcastReceiver();
153             }
154         };
155         mActivity.runOnUiThread(runnable);
156     }
157
158     @Override
159     public void onFirstFrameReceived() {
160         mFirstFrameReceived = true;
161         hideLaunchScreenWhenReady();
162     }
163
164     @Override
165     public void onShow(DialogInterface dialog) {
166         mActivity.getWindow().setBackgroundDrawable(null);
167         if (mFirstFrameReceived) hideLaunchScreenWhenReady();
168     }
169
170     @Override
171     public void onDismiss(DialogInterface dialog) {
172         mOrientationListener.disable();
173         mOrientationListener = null;
174     }
175
176     @Override
177     public void onPageFinished(String url) {
178         mPageLoadFinished = true;
179         hideLaunchScreenWhenReady();
180     }
181
182     public static String getHideLaunchScreenFilterStr() {
183         return mIntentFilterStr;
184     }
185
186     public int getScreenOrientation() {
187         // getResources().getConfiguration().orientation returns wrong value in some devices.
188         // Below is another way to calculate screen orientation.
189         Display display = mActivity.getWindowManager().getDefaultDisplay();
190         Point size = new Point();
191         display.getSize(size);
192         int orientation;
193         if (size.x < size.y) {
194             orientation = Configuration.ORIENTATION_PORTRAIT;
195         } else {
196             orientation = Configuration.ORIENTATION_LANDSCAPE;
197         }
198         return orientation;
199     }
200
201     private RelativeLayout getLaunchScreenLayout(String imageBorderList) {
202         // Parse the borders depends on orientation.
203         // imageBorderList format:"[default];[landscape];[portrait]"
204         String[] borders = imageBorderList.split(";");
205         // When there is no borders defined, display with no borders.
206         if (borders.length < 1) return parseImageBorder("");
207         int orientation = getScreenOrientation();
208         mCurrentOrientation = orientation;
209         if (borders.length >= 2 && orientation == Configuration.ORIENTATION_LANDSCAPE) {
210             if (borders[1].equals("empty")) {
211                 // Has launch_screen.landscape configured, but no image_border set.
212                 // Display the iamge with no borders.
213                 return parseImageBorder("");
214             } else if (borders[1].isEmpty()) {
215                 // No launch_screen.landscape configured.
216                 // Use launch_screen.default.
217                 return parseImageBorder(borders[0]);
218             } else {
219                 return parseImageBorder(borders[1]);
220             }
221         } else if (borders.length == 3 && orientation == Configuration.ORIENTATION_PORTRAIT) {
222             if (borders[2].equals("empty")) {
223                 // Has launch_screen.portrait configured, but no image_border set.
224                 // Display the iamge with no borders.
225                 return parseImageBorder("");
226             } else if (borders[2].isEmpty()) {
227                 // No launch_screen.portrait configured.
228                 // Use launch_screen.default.
229                 return parseImageBorder(borders[0]);
230             } else {
231                 return parseImageBorder(borders[2]);
232             }
233         }
234
235         return parseImageBorder(borders[0]);
236     }
237
238     private int getSuitableSize(int maxSize, int divider) {
239         int finalSize = divider;
240         float minMod = divider;
241         for (; divider > 1; divider--) {
242             int mod = maxSize % divider;
243             // Found the suitable size.
244             if (mod == 0) {
245                 finalSize = divider;
246                 break;
247             }
248             // Record the best suitable one.
249             // If there is no mod==0 found, return the divider which min(mod).
250             if (mod < minMod) {
251                 minMod = mod;
252                 finalSize = divider;
253             }
254         }
255         return finalSize;
256     }
257
258     /**
259      * Get each section from 9-piece format image depends on the spec defined
260      * @param img The foreground image.
261      * @param x The position where the section start.
262      * @param y The position where the section start.
263      * @param width The width of the section.
264      * @param height The height of the section.
265      * @param mode The border type for this section.
266      * @param maxWidth When mode == ROUND, this will be used.
267      * @param maxHeight When mode == ROUND, this will be used.
268      * @return The ImageView for this section.
269      */
270     private ImageView getSubImageView(Bitmap img, int x, int y, int width, int height,
271                                       BorderModeType mode, int maxWidth, int maxHeight) {
272         if (img == null) return null;
273
274         if (width <= 0 || height <= 0) return null;
275
276         // Check whether the section is inside the foreground image.
277         Rect imgRect = new Rect(0, 0, img.getWidth(), img.getHeight());
278         Rect subRect = new Rect(x, y, x + width, y + height);
279         if (!imgRect.contains(subRect)) return null;
280
281         Bitmap subImage = Bitmap.createBitmap(img, x, y, width, height);
282         ImageView subImageView = new ImageView(mActivity);
283         BitmapDrawable drawable;
284         if (mode == BorderModeType.ROUND) {
285             int originW = subImage.getWidth();
286             int originH = subImage.getHeight();
287             int newW = originW;
288             int newH = originH;
289             // Scale down the sub image to let the last image not cropped when it's repeated.
290             if (maxWidth > 0) newW = getSuitableSize(maxWidth, originW);
291             if (maxHeight > 0) newH = getSuitableSize(maxHeight, originH);
292             // recreate the new scaled bitmap.
293             Bitmap resizedBitmap = Bitmap.createScaledBitmap(subImage, newW, newH, true);
294             // Treat as repeat mode.
295             subImage = resizedBitmap;
296             mode = BorderModeType.REPEAT;
297         }
298         if (mode == BorderModeType.REPEAT) {
299             drawable = new BitmapDrawable(mActivity.getResources(), subImage);
300             drawable.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
301             subImageView.setImageDrawable(drawable);
302             subImageView.setScaleType(ScaleType.FIT_XY);
303         } else if (mode == BorderModeType.STRETCH) {
304             subImageView.setImageBitmap(subImage);
305             subImageView.setScaleType(ScaleType.FIT_XY);
306         } else {
307             subImageView.setImageBitmap(subImage);
308         }
309
310         return subImageView;
311     }
312
313     private int getStatusBarHeight() {
314         int resourceId = mActivity.getResources().getIdentifier(
315                 "status_bar_height", "dimen", "android");
316         if (resourceId > 0) {
317             return mActivity.getResources().getDimensionPixelSize(resourceId);
318         }
319         // If not found, return default one.
320         return 25;
321     }
322
323     private RelativeLayout parseImageBorder(String imageBorder) {
324         int topBorder = 0;
325         int rightBorder = 0;
326         int leftBorder = 0;
327         int bottomBorder = 0;
328         BorderModeType horizontalMode = BorderModeType.STRETCH;
329         BorderModeType verticalMode = BorderModeType.STRETCH;
330
331         if (imageBorder.equals("empty")) imageBorder = "";
332
333         // Parse the value of image_border.
334         String[] items = imageBorder.split(" ");
335         ArrayList<String> borders = new ArrayList<String>();
336         ArrayList<BorderModeType> modes = new ArrayList<BorderModeType>();
337         for (int i = 0; i < items.length; i++) {
338             String item = items[i];
339             if (item.endsWith("px")) {
340                 borders.add(item.replaceAll("px", ""));
341             } else if (item.equals(BORDER_MODE_REPEAT)) {
342                 modes.add(BorderModeType.REPEAT);
343             } else if (item.equals(BORDER_MODE_STRETCH)) {
344                 modes.add(BorderModeType.STRETCH);
345             } else if (item.equals(BORDER_MODE_ROUND)) {
346                 modes.add(BorderModeType.ROUND);
347             }
348         }
349         // Parse borders as defined by the spec.
350         try {
351             if (borders.size() == 1) {
352                 topBorder = rightBorder = leftBorder = bottomBorder =
353                         Integer.valueOf(borders.get(0));
354             } else if (borders.size() == 2) {
355                 topBorder = bottomBorder = Integer.valueOf(borders.get(0));
356                 rightBorder = leftBorder = Integer.valueOf(borders.get(1));
357             } else if (borders.size() == 3) {
358                 rightBorder = leftBorder = Integer.valueOf(borders.get(1));
359                 topBorder = Integer.valueOf(borders.get(0));
360                 bottomBorder = Integer.valueOf(borders.get(2));
361             } else if (borders.size() == 4) {
362                 topBorder = Integer.valueOf(borders.get(0));
363                 rightBorder = Integer.valueOf(borders.get(1));
364                 leftBorder = Integer.valueOf(borders.get(2));
365                 bottomBorder = Integer.valueOf(borders.get(3));
366             }
367         } catch (NumberFormatException e) {
368             topBorder = rightBorder = leftBorder = bottomBorder = 0;
369         }
370
371         // The border values are dpi from manifest.json, need to translate to px.
372         DisplayMetrics matrix = mActivity.getResources().getDisplayMetrics();
373         topBorder = (int)TypedValue.applyDimension(
374                 TypedValue.COMPLEX_UNIT_DIP, topBorder, matrix);
375         rightBorder = (int)TypedValue.applyDimension(
376                 TypedValue.COMPLEX_UNIT_DIP, rightBorder, matrix);
377         leftBorder = (int)TypedValue.applyDimension(
378                 TypedValue.COMPLEX_UNIT_DIP, leftBorder, matrix);
379         bottomBorder = (int)TypedValue.applyDimension(
380                 TypedValue.COMPLEX_UNIT_DIP, bottomBorder, matrix);
381
382         // Parse border mode as spec defined.
383         if (modes.size() == 1) {
384             horizontalMode = verticalMode = modes.get(0);
385         } else if (modes.size() == 2) {
386             horizontalMode = modes.get(0);
387             verticalMode = modes.get(1);
388         }
389
390         // Get foreground image
391         int imgResId = mActivity.getResources().getIdentifier(
392                        "launchscreen_img", "drawable", mActivity.getPackageName());
393         if (imgResId == 0) return null;
394         Bitmap img = BitmapFactory.decodeResource(mActivity.getResources(), imgResId);
395         if (img == null) return null;
396
397         RelativeLayout root = new RelativeLayout(mActivity);
398         root.setLayoutParams(new RelativeLayout.LayoutParams(
399                 ViewGroup.LayoutParams.MATCH_PARENT,
400                 ViewGroup.LayoutParams.MATCH_PARENT));
401         RelativeLayout.LayoutParams params;
402         ImageView subImageView;
403
404         // If no border specified, display the foreground image centered horizontally and vertically.
405         if (borders.size() == 0) {
406             subImageView = new ImageView(mActivity);
407             subImageView.setImageBitmap(img);
408             params = new RelativeLayout.LayoutParams(
409                     RelativeLayout.LayoutParams.WRAP_CONTENT,
410                     RelativeLayout.LayoutParams.WRAP_CONTENT);
411             params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
412             root.addView(subImageView, params);
413             return root;
414         }
415
416         // Create the 9-piece layout as spec defined.
417
418         // Get Screen width and height.
419         Display display = mActivity.getWindowManager().getDefaultDisplay();
420         Point size = new Point();
421         display.getSize(size);
422
423         // For non fullscreen, the height should substract status bar height
424         if ((mActivity.getWindow().getAttributes().flags &
425              WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0) {
426             size.y -= getStatusBarHeight();
427         }
428
429         // Image section-1 top left
430         subImageView = getSubImageView(img, 0, 0, leftBorder, topBorder, BorderModeType.NONE, 0, 0);
431         if (subImageView != null) {
432             params = new RelativeLayout.LayoutParams(
433                     RelativeLayout.LayoutParams.WRAP_CONTENT,
434                     RelativeLayout.LayoutParams.WRAP_CONTENT);
435             params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
436             params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
437             root.addView(subImageView, params);
438         }
439
440         // Image section-2 top
441         subImageView = getSubImageView(img, leftBorder, 0, img.getWidth() - leftBorder
442                 - rightBorder, topBorder, horizontalMode, size.x - leftBorder - rightBorder, 0);
443         if (subImageView != null) {
444             params = new RelativeLayout.LayoutParams(
445                     RelativeLayout.LayoutParams.MATCH_PARENT,
446                     RelativeLayout.LayoutParams.WRAP_CONTENT);
447             params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
448             params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
449             params.leftMargin = leftBorder;
450             params.rightMargin = rightBorder;
451             root.addView(subImageView, params);
452         }
453
454         // Image section-3 top right
455         subImageView = getSubImageView(img, img.getWidth() - rightBorder, 0,
456                 rightBorder, topBorder, BorderModeType.NONE, 0, 0);
457         if (subImageView != null) {
458             params = new RelativeLayout.LayoutParams(
459                     RelativeLayout.LayoutParams.WRAP_CONTENT,
460                     RelativeLayout.LayoutParams.WRAP_CONTENT);
461             params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
462             params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
463             root.addView(subImageView, params);
464         }
465
466         // Image section-4 left
467         subImageView = getSubImageView(img, 0, topBorder, leftBorder, img.getHeight()
468                 - topBorder - bottomBorder, verticalMode, 0, size.y - topBorder - bottomBorder);
469         if (subImageView != null) {
470             params = new RelativeLayout.LayoutParams(
471                     RelativeLayout.LayoutParams.WRAP_CONTENT,
472                     RelativeLayout.LayoutParams.MATCH_PARENT);
473             params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
474             params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
475             params.topMargin = topBorder;
476             params.bottomMargin = bottomBorder;
477             root.addView(subImageView, params);
478         }
479
480         // Image section-5 middle
481         subImageView = getSubImageView(img, leftBorder, topBorder, img.getWidth() - leftBorder - rightBorder,
482                 img.getHeight() - topBorder - bottomBorder, BorderModeType.NONE, 0, 0);
483         if (subImageView != null) {
484             subImageView.setScaleType(ScaleType.FIT_XY);
485             params = new RelativeLayout.LayoutParams(
486                     RelativeLayout.LayoutParams.MATCH_PARENT,
487                     RelativeLayout.LayoutParams.MATCH_PARENT);
488             params.leftMargin = leftBorder;
489             params.topMargin = topBorder;
490             params.rightMargin = rightBorder;
491             params.bottomMargin = bottomBorder;
492             root.addView(subImageView, params);
493         }
494
495         // Image section-6 right
496         subImageView = getSubImageView(img, img.getWidth() - rightBorder, topBorder, rightBorder,
497                 img.getHeight() - topBorder - bottomBorder, verticalMode, 0,
498                 size.y - topBorder - bottomBorder);
499         if (subImageView != null) {
500             params = new RelativeLayout.LayoutParams(
501                     RelativeLayout.LayoutParams.WRAP_CONTENT,
502                     RelativeLayout.LayoutParams.MATCH_PARENT);
503             params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
504             params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
505             params.topMargin = topBorder;
506             params.bottomMargin = bottomBorder;
507             root.addView(subImageView, params);
508         }
509
510         // Image section-7 bottom left
511         subImageView = getSubImageView(img, 0, img.getHeight() - bottomBorder,
512                 leftBorder, bottomBorder, BorderModeType.NONE, 0, 0);
513         if (subImageView != null) {
514             params = new RelativeLayout.LayoutParams(
515                     RelativeLayout.LayoutParams.WRAP_CONTENT,
516                     RelativeLayout.LayoutParams.WRAP_CONTENT);
517             params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
518             params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
519             root.addView(subImageView, params);
520         }
521
522         // Image section-8 bottom
523         subImageView = getSubImageView(img, leftBorder, img.getHeight() - bottomBorder,
524                 img.getWidth() - leftBorder - rightBorder, bottomBorder, horizontalMode,
525                 size.x - leftBorder - rightBorder, 0);
526         if (subImageView != null) {
527             params = new RelativeLayout.LayoutParams(
528                     RelativeLayout.LayoutParams.MATCH_PARENT,
529                     RelativeLayout.LayoutParams.WRAP_CONTENT);
530             params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
531             params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
532             params.leftMargin = leftBorder;
533             params.rightMargin = rightBorder;
534             root.addView(subImageView, params);
535         }
536
537         // Image section-9 bottom right
538         subImageView = getSubImageView(img, img.getWidth() - rightBorder,
539                 img.getHeight() - bottomBorder, rightBorder, bottomBorder,
540                 BorderModeType.NONE, 0, 0);
541         if (subImageView != null) {
542             params = new RelativeLayout.LayoutParams(
543                     RelativeLayout.LayoutParams.WRAP_CONTENT,
544                     RelativeLayout.LayoutParams.WRAP_CONTENT);
545             params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
546             params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
547             root.addView(subImageView, params);
548         }
549         return root;
550     }
551
552     private void registerBroadcastReceiver() {
553         IntentFilter intentFilter = new IntentFilter(mIntentFilterStr);
554         mLaunchScreenReadyWhenReceiver = new BroadcastReceiver() {
555             @Override
556             public void onReceive(Context context, Intent intent) {
557                 mCustomHideLaunchScreen = true;
558                 hideLaunchScreenWhenReady();
559             }
560         };
561         mActivity.registerReceiver(mLaunchScreenReadyWhenReceiver, intentFilter);
562     }
563
564     private void hideLaunchScreenWhenReady() {
565         if (mLaunchScreenDialog == null || !mFirstFrameReceived) return;
566         if (mReadyWhen == ReadyWhenType.FIRST_PAINT) {
567             performHideLaunchScreen();
568         } else if (mReadyWhen == ReadyWhenType.USER_INTERACTIVE) {
569             // TODO: Need to listen js DOMContentLoaded event,
570             // will be implemented in the next step.
571             performHideLaunchScreen();
572         } else if (mReadyWhen == ReadyWhenType.COMPLETE) {
573             if (mPageLoadFinished) performHideLaunchScreen();
574         } else if (mReadyWhen == ReadyWhenType.CUSTOM) {
575             if (mCustomHideLaunchScreen) performHideLaunchScreen();
576         }
577     }
578
579     private void performHideLaunchScreen() {
580         mLaunchScreenDialog.dismiss();
581         mLaunchScreenDialog = null;
582         if (mReadyWhen == ReadyWhenType.CUSTOM) {
583             mActivity.unregisterReceiver(mLaunchScreenReadyWhenReceiver);
584         }
585     }
586
587     private void setReadyWhen(String readyWhen) {
588         if (readyWhen.equals("first-paint")) {
589             mReadyWhen = ReadyWhenType.FIRST_PAINT;
590         } else if (readyWhen.equals("user-interactive")) {
591             mReadyWhen = ReadyWhenType.USER_INTERACTIVE;
592         } else if (readyWhen.equals("complete")) {
593             mReadyWhen = ReadyWhenType.COMPLETE;
594         } else if (readyWhen.equals("custom")) {
595             mReadyWhen = ReadyWhenType.CUSTOM;
596         } else {
597             mReadyWhen = ReadyWhenType.FIRST_PAINT;
598         }
599     }
600 }