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 UiFlags mUiFlags;
57 
58     @Override
onCreate(Bundle savedInstanceState)59     protected void onCreate(Bundle savedInstanceState) {
60         AndroidInjection.inject(this);
61         super.onCreate(savedInstanceState);
62         Intent intent = getIntent();
63         if (!SYSTEM_SETUP.equals(intent.getAction())) {
64             finish();
65             return;
66         }
67     }
68 
69     @Override
onCreateInitialFragment()70     protected Fragment onCreateInitialFragment() {
71         return new SetupSourcesFragment();
72     }
73 
showMerchantCollection()74     private void showMerchantCollection() {
75         Intent onlineStoreIntent = OnboardingUtils.createOnlineStoreIntent(mUiFlags);
76         if (onlineStoreIntent != null) {
77             executeActionWithDelay(() -> startActivity(onlineStoreIntent), SHOW_RIPPLE_DURATION_MS);
78         } else {
79             Log.w(
80                     TAG,
81                     "Unable to show merchant collection, more channels url is not valid. url is "
82                             + mUiFlags.moreChannelsUrl());
83         }
84     }
85 
86     @Override
executeAction(String category, int actionId, Bundle params)87     public boolean executeAction(String category, int actionId, Bundle params) {
88         switch (category) {
89             case SetupSourcesFragment.ACTION_CATEGORY:
90                 switch (actionId) {
91                     case SetupSourcesFragment.ACTION_ONLINE_STORE:
92                         showMerchantCollection();
93                         return true;
94                     case SetupSourcesFragment.ACTION_SETUP_INPUT:
95                         {
96                             String inputId =
97                                     params.getString(
98                                             SetupSourcesFragment.ACTION_PARAM_KEY_INPUT_ID);
99                             TvInputInfo input = mInputManager.getTvInputInfo(inputId);
100                             Intent intent = CommonUtils.createSetupIntent(input);
101                             if (intent == null) {
102                                 Toast.makeText(
103                                                 this,
104                                                 R.string.msg_no_setup_activity,
105                                                 Toast.LENGTH_SHORT)
106                                         .show();
107                                 return true;
108                             }
109                             // Even though other app can handle the intent, the setup launched by
110                             // Live
111                             // channels should go through TV app SetupPassthroughActivity.
112                             intent.setComponent(
113                                     new ComponentName(this, SetupPassthroughActivity.class));
114                             try {
115                                 // Now we know that the user intends to set up this input. Grant
116                                 // permission for writing EPG data.
117                                 SetupUtils.grantEpgPermission(
118                                         this, input.getServiceInfo().packageName);
119                                 startActivityForResult(intent, REQUEST_CODE_START_SETUP_ACTIVITY);
120                             } catch (ActivityNotFoundException e) {
121                                 Toast.makeText(
122                                                 this,
123                                                 getString(
124                                                         R.string.msg_unable_to_start_setup_activity,
125                                                         input.loadLabel(this)),
126                                                 Toast.LENGTH_SHORT)
127                                         .show();
128                             }
129                             return true;
130                         }
131                     case SetupMultiPaneFragment.ACTION_DONE:
132                         {
133                             // To make sure user can finish setup flow, set result as RESULT_OK.
134                             setResult(Activity.RESULT_OK);
135                             finish();
136                             return true;
137                         }
138                 }
139                 break;
140         }
141         return false;
142     }
143 
144     /**
145      * Exports {@link SystemSetupActivity} for Dagger codegen to create the appropriate injector.
146      */
147     @dagger.Module
148     public abstract static class Module {
149         @ContributesAndroidInjector
contributeSystemSetupActivity()150         abstract SystemSetupActivity contributeSystemSetupActivity();
151     }
152 }
153