1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.setup;
18 
19 import android.app.Activity;
20 import android.app.Fragment;
21 import android.content.ActivityNotFoundException;
22 import android.content.ComponentName;
23 import android.content.Intent;
24 import android.media.tv.TvInputInfo;
25 import android.os.Bundle;
26 import android.util.Log;
27 import android.widget.Toast;
28 
29 import com.android.tv.R;
30 import com.android.tv.SetupPassthroughActivity;
31 import com.android.tv.common.CommonConstants;
32 import com.android.tv.common.ui.setup.SetupActivity;
33 import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
34 import com.android.tv.common.util.CommonUtils;
35 import com.android.tv.onboarding.SetupSourcesFragment;
36 import com.android.tv.util.OnboardingUtils;
37 import com.android.tv.util.SetupUtils;
38 import com.android.tv.util.TvInputManagerHelper;
39 
40 import dagger.android.AndroidInjection;
41 import dagger.android.ContributesAndroidInjector;
42 
43 import com.android.tv.common.flags.UiFlags;
44 
45 import javax.inject.Inject;
46 
47 /** A activity to start input sources setup fragment for initial setup flow. */
48 public class SystemSetupActivity extends SetupActivity {
49     private static final String TAG = "SystemSetupActivity";
50     private static final String SYSTEM_SETUP =
51             CommonConstants.BASE_PACKAGE + ".action.LAUNCH_SYSTEM_SETUP";
52     private static final int SHOW_RIPPLE_DURATION_MS = 266;
53     private static final int REQUEST_CODE_START_SETUP_ACTIVITY = 1;
54 
55     @Inject TvInputManagerHelper mInputManager;
56     @Inject SetupUtils mSetupUtils;
57     @Inject UiFlags mUiFlags;
58 
59     @Override
onCreate(Bundle savedInstanceState)60     protected void onCreate(Bundle savedInstanceState) {
61         AndroidInjection.inject(this);
62         super.onCreate(savedInstanceState);
63         Intent intent = getIntent();
64         if (!SYSTEM_SETUP.equals(intent.getAction())) {
65             finish();
66             return;
67         }
68     }
69 
70     @Override
onCreateInitialFragment()71     protected Fragment onCreateInitialFragment() {
72         return new SetupSourcesFragment();
73     }
74 
showMerchantCollection()75     private void showMerchantCollection() {
76         Intent onlineStoreIntent = OnboardingUtils.createOnlineStoreIntent(mUiFlags);
77         if (onlineStoreIntent != null) {
78             executeActionWithDelay(() -> startActivity(onlineStoreIntent), SHOW_RIPPLE_DURATION_MS);
79         } else {
80             Log.w(
81                     TAG,
82                     "Unable to show merchant collection, more channels url is not valid. url is "
83                             + mUiFlags.moreChannelsUrl());
84         }
85     }
86 
87     @Override
executeAction(String category, int actionId, Bundle params)88     public boolean executeAction(String category, int actionId, Bundle params) {
89         switch (category) {
90             case SetupSourcesFragment.ACTION_CATEGORY:
91                 switch (actionId) {
92                     case SetupSourcesFragment.ACTION_ONLINE_STORE:
93                         showMerchantCollection();
94                         return true;
95                     case SetupSourcesFragment.ACTION_SETUP_INPUT:
96                         {
97                             String inputId =
98                                     params.getString(
99                                             SetupSourcesFragment.ACTION_PARAM_KEY_INPUT_ID);
100                             TvInputInfo input = mInputManager.getTvInputInfo(inputId);
101                             Intent intent = mSetupUtils.createSetupIntent(this, input);
102                             if (intent == null) {
103                                 Toast.makeText(
104                                                 this,
105                                                 R.string.msg_no_setup_activity,
106                                                 Toast.LENGTH_SHORT)
107                                         .show();
108                                 return true;
109                             }
110                             // Even though other app can handle the intent, the setup launched by
111                             // Live
112                             // channels should go through TV app SetupPassthroughActivity.
113                             intent.setComponent(
114                                     new ComponentName(this, SetupPassthroughActivity.class));
115                             try {
116                                 // Now we know that the user intends to set up this input. Grant
117                                 // permission for writing EPG data.
118                                 SetupUtils.grantEpgPermission(
119                                         this, input.getServiceInfo().packageName);
120                                 startActivityForResult(intent, REQUEST_CODE_START_SETUP_ACTIVITY);
121                             } catch (ActivityNotFoundException e) {
122                                 Toast.makeText(
123                                                 this,
124                                                 getString(
125                                                         R.string.msg_unable_to_start_setup_activity,
126                                                         input.loadLabel(this)),
127                                                 Toast.LENGTH_SHORT)
128                                         .show();
129                             }
130                             return true;
131                         }
132                     case SetupMultiPaneFragment.ACTION_DONE:
133                         {
134                             // To make sure user can finish setup flow, set result as RESULT_OK.
135                             setResult(Activity.RESULT_OK);
136                             finish();
137                             return true;
138                         }
139                 }
140                 break;
141         }
142         return false;
143     }
144 
145     /**
146      * Exports {@link SystemSetupActivity} for Dagger codegen to create the appropriate injector.
147      */
148     @dagger.Module
149     public abstract static class Module {
150         @ContributesAndroidInjector
contributeSystemSetupActivity()151         abstract SystemSetupActivity contributeSystemSetupActivity();
152     }
153 }
154