1816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/* 2816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Copyright (C) 2015 The Android Open Source Project 3816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 4816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 5816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * you may not use this file except in compliance with the License. 6816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * You may obtain a copy of the License at 7816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 8816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 9816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 10816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Unless required by applicable law or agreed to in writing, software 11816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 12816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * See the License for the specific language governing permissions and 14816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * limitations under the License. 15816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 16816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 17816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopackage com.android.tv; 18816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 19816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.app.Activity; 20816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.ActivityNotFoundException; 21816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.Context; 22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.Intent; 23816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.os.Bundle; 24816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.util.Log; 25816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 26816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/** 27816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * An activity to launch a new activity. 28816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 2995961816a768da387f0b5523cf4363ace2044089Nick Chalko * <p>In the case when {@link MainActivity} starts a new activity using {@link 30944779887775bd950cf1abf348d2df461593f6abLive Channels Team * Activity#startActivity} or {@link Activity#startActivityForResult}, Live TV app is 31944779887775bd950cf1abf348d2df461593f6abLive Channels Team * terminated if the new activity crashes. That's because the {@link android.app.ActivityManager} 32944779887775bd950cf1abf348d2df461593f6abLive Channels Team * terminates the activity which is just below the crashed activity in the activity stack. To avoid 33944779887775bd950cf1abf348d2df461593f6abLive Channels Team * this, we need to locate an additional activity between these activities in the activity stack. 34816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 35816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopublic class LauncherActivity extends Activity { 36816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final String TAG = "LauncherActivity"; 37816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 38a1589bd48e05abbee991e0cdd27fa402a5dc5001Live Channels Team public static final String ERROR_MESSAGE = "com.android.tv.LauncherActivity.ErrorMessage"; 39816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 40816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final int REQUEST_CODE_DEFAULT = 0; 41816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final int REQUEST_START_ACTIVITY = 100; 42816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 43816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final String EXTRA_INTENT = "com.android.tv.LauncherActivity.INTENT"; 44816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final String EXTRA_REQUEST_RESULT = 45816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko "com.android.tv.LauncherActivity.REQUEST_RESULT"; 46816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 4795961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Starts an activity by calling {@link Activity#startActivity}. */ 48816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static void startActivitySafe(Activity baseActivity, Intent intentToLaunch) { 49816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // To avoid the app termination when the new activity crashes, LauncherActivity should be 50816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // started by calling startActivityForResult(). 5195961816a768da387f0b5523cf4363ace2044089Nick Chalko baseActivity.startActivityForResult( 5295961816a768da387f0b5523cf4363ace2044089Nick Chalko createIntent(baseActivity, intentToLaunch, false), REQUEST_CODE_DEFAULT); 53816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 54816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 5595961816a768da387f0b5523cf4363ace2044089Nick Chalko private static Intent createIntent( 5695961816a768da387f0b5523cf4363ace2044089Nick Chalko Context context, Intent intentToLaunch, boolean requestResult) { 57816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Intent intent = new Intent(context, LauncherActivity.class); 58816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko intent.putExtra(EXTRA_INTENT, intentToLaunch); 59816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (requestResult) { 60816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko intent.putExtra(EXTRA_REQUEST_RESULT, true); 61816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 62816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return intent; 63816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 64816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 65816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 66816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onCreate(Bundle savedInstanceState) { 67816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko super.onCreate(savedInstanceState); 68816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // We should launch the new activity in onCreate rather than in onStart. 69816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // That's because it is not guaranteed that onStart is called only once. 70816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Intent intent = getIntent().getParcelableExtra(EXTRA_INTENT); 7107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko boolean requestResult = getIntent().getBooleanExtra(EXTRA_REQUEST_RESULT, false); 72816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko try { 7307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko if (requestResult) { 74816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko startActivityForResult(intent, REQUEST_START_ACTIVITY); 75816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } else { 76816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko startActivity(intent); 77816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko setResult(Activity.RESULT_OK); 78816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko finish(); 79816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 80816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } catch (ActivityNotFoundException e) { 81816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Log.w(TAG, "Activity not found for " + intent); 8295961816a768da387f0b5523cf4363ace2044089Nick Chalko intent.putExtra(ERROR_MESSAGE, getResources().getString(R.string.msg_missing_app)); 83816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko setResult(Activity.RESULT_CANCELED, intent); 84816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko finish(); 85816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 86816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 87816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 88816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko @Override 89816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public void onActivityResult(int requestCode, int resultCode, Intent data) { 90816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko setResult(resultCode, data); 91816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko finish(); 92816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 93816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko} 94