52659018908113f8230740c7ac4bda0bf101b024
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core / src / org / xwalk / core / 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;
6
7 import java.lang.Runnable;
8
9 import android.app.Activity;
10 import android.app.Dialog;
11 import android.content.BroadcastReceiver;
12 import android.content.Context;
13 import android.content.DialogInterface;
14 import android.content.Intent;
15 import android.content.IntentFilter;
16 import android.graphics.Bitmap;
17 import android.graphics.BitmapFactory;
18 import android.graphics.drawable.BitmapDrawable;
19 import android.graphics.drawable.Drawable;
20 import android.graphics.Rect;
21 import android.os.Bundle;
22 import android.util.Log;
23 import android.view.Gravity;
24 import android.view.KeyEvent;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.view.Window;
28 import android.view.WindowManager;
29 import android.widget.FrameLayout;
30 import android.widget.LinearLayout;
31
32 import org.chromium.content.browser.ContentViewRenderView.FirstRenderedFrameListener;
33
34 // Provisionally set it as public due to the use of launch screen extension.
35 // TODO(yongsheng): remove public modifier.
36 public class XWalkLaunchScreenManager
37         implements FirstRenderedFrameListener, DialogInterface.OnShowListener, PageLoadListener {
38     // This string will be initialized before extension initialized,
39     // and used by LaunchScreenExtension.
40     private static String mIntentFilterStr;
41
42     private XWalkView mXWalkView;
43     private Activity mActivity;
44     private Context mLibContext;
45     private Dialog mLaunchScreenDialog;
46     private boolean mPageLoadFinished;
47     private ReadyWhenType mReadyWhen;
48     private boolean mFirstFrameReceived;
49     private BroadcastReceiver mLaunchScreenReadyWhenReceiver;
50     private boolean mCustomHideLaunchScreen;
51
52     private enum ReadyWhenType {
53         FIRST_PAINT,
54         USER_INTERACTIVE,
55         COMPLETE,
56         CUSTOM
57     }
58
59     public XWalkLaunchScreenManager(Context context, XWalkView xwView) {
60         mXWalkView = xwView;
61         mLibContext = context;
62         mActivity = mXWalkView.getActivity();
63         mIntentFilterStr = mActivity.getPackageName() + ".hideLaunchScreen";
64     }
65
66     public void displayLaunchScreen(String readyWhen) {
67         if (mXWalkView == null) return;
68         setReadyWhen(readyWhen);
69
70         Runnable runnable = new Runnable() {
71            public void run(){
72                 int resId = mActivity.getResources().getIdentifier(
73                         "launchscreen", "drawable", mActivity.getPackageName());
74                 if (resId == 0) return;
75
76                 // Can not use the drawable directly in shared mode, need to decode it and create a new drawable.
77                 Bitmap bitmap = BitmapFactory.decodeResource(mActivity.getResources(), resId);
78                 Drawable finalDrawable = new BitmapDrawable(mActivity.getResources(), bitmap);
79
80                 mLaunchScreenDialog = new Dialog(mLibContext, android.R.style.Theme_Holo_Light_NoActionBar);
81                 if ((mActivity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) {
82                     mLaunchScreenDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
83                             WindowManager.LayoutParams.FLAG_FULLSCREEN);
84                 }
85                 mLaunchScreenDialog.getWindow().setBackgroundDrawable(finalDrawable);
86                 mLaunchScreenDialog.setOnKeyListener(new Dialog.OnKeyListener() {
87                     @Override
88                     public boolean onKey(DialogInterface arg0, int keyCode,
89                             KeyEvent event) {
90                         if (keyCode == KeyEvent.KEYCODE_BACK) {
91                             mLaunchScreenDialog.dismiss();
92                             mActivity.onBackPressed();
93                         }
94                         return true;
95                     }
96                 });
97                 mLaunchScreenDialog.setOnShowListener(XWalkLaunchScreenManager.this);
98                 mLaunchScreenDialog.show();
99                 if (mReadyWhen == ReadyWhenType.CUSTOM) registerBroadcastReceiver();
100             }
101         };
102         mActivity.runOnUiThread(runnable);
103     }
104
105     @Override
106     public void onFirstFrameReceived() {
107         mFirstFrameReceived = true;
108         hideLaunchScreenWhenReady();
109     }
110
111     @Override
112     public void onShow(DialogInterface dialog) {
113         mActivity.getWindow().setBackgroundDrawable(null);
114         if (mFirstFrameReceived) hideLaunchScreenWhenReady();
115     }
116
117     @Override
118     public void onPageFinished(String url) {
119         mPageLoadFinished = true;
120         hideLaunchScreenWhenReady();
121     }
122
123     public static String getHideLaunchScreenFilterStr() {
124         return mIntentFilterStr;
125     }
126
127     private void registerBroadcastReceiver() {
128         IntentFilter intentFilter = new IntentFilter(mIntentFilterStr);
129         mLaunchScreenReadyWhenReceiver = new BroadcastReceiver() {
130             @Override
131             public void onReceive(Context context, Intent intent) {
132                 mCustomHideLaunchScreen = true;
133                 hideLaunchScreenWhenReady();
134             }
135         };
136         mActivity.registerReceiver(mLaunchScreenReadyWhenReceiver, intentFilter);
137     }
138
139     private void hideLaunchScreenWhenReady() {
140         if (mLaunchScreenDialog == null || !mFirstFrameReceived) return;
141         if (mReadyWhen == ReadyWhenType.FIRST_PAINT) {
142             performHideLaunchScreen();
143         } else if (mReadyWhen == ReadyWhenType.USER_INTERACTIVE) {
144             // TODO: Need to listen js DOMContentLoaded event,
145             // will be implemented in the next step.
146             performHideLaunchScreen();
147         } else if (mReadyWhen == ReadyWhenType.COMPLETE) {
148             if (mPageLoadFinished) performHideLaunchScreen();
149         } else if (mReadyWhen == ReadyWhenType.CUSTOM) {
150             if (mCustomHideLaunchScreen) performHideLaunchScreen();
151         }
152     }
153
154     private void performHideLaunchScreen() {
155         mLaunchScreenDialog.dismiss();
156         mLaunchScreenDialog = null;
157         if (mReadyWhen == ReadyWhenType.CUSTOM) {
158             mActivity.unregisterReceiver(mLaunchScreenReadyWhenReceiver);
159         }
160     }
161
162     private void setReadyWhen(String readyWhen) {
163         if (readyWhen.equals("first-paint")) {
164             mReadyWhen = ReadyWhenType.FIRST_PAINT;
165         } else if (readyWhen.equals("user-interactive")) {
166             mReadyWhen = ReadyWhenType.USER_INTERACTIVE;
167         } else if (readyWhen.equals("complete")) {
168             mReadyWhen = ReadyWhenType.COMPLETE;
169         } else if (readyWhen.equals("custom")) {
170             mReadyWhen = ReadyWhenType.CUSTOM;
171         } else {
172             mReadyWhen = ReadyWhenType.FIRST_PAINT;
173         }
174     }
175 }