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