OnboardingActivity.java revision 38fef3bf253578f518d1bc727da4afb263194398
1/* 2 * Copyright (C) 2015 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 17package com.android.tv.onboarding; 18 19import android.app.Fragment; 20import android.content.ActivityNotFoundException; 21import android.content.ComponentName; 22import android.content.Context; 23import android.content.Intent; 24import android.content.pm.PackageManager; 25import android.media.tv.TvInputInfo; 26import android.os.Bundle; 27import android.support.annotation.NonNull; 28import android.widget.Toast; 29import com.android.tv.ApplicationSingletons; 30import com.android.tv.R; 31import com.android.tv.SetupPassthroughActivity; 32import com.android.tv.TvApplication; 33import com.android.tv.common.TvCommonUtils; 34import com.android.tv.common.ui.setup.SetupActivity; 35import com.android.tv.common.ui.setup.SetupMultiPaneFragment; 36import com.android.tv.data.ChannelDataManager; 37import com.android.tv.util.OnboardingUtils; 38import com.android.tv.util.PermissionUtils; 39import com.android.tv.util.SetupUtils; 40import com.android.tv.util.TvInputManagerHelper; 41 42public class OnboardingActivity extends SetupActivity { 43 private static final String KEY_INTENT_AFTER_COMPLETION = "key_intent_after_completion"; 44 45 private static final int PERMISSIONS_REQUEST_READ_TV_LISTINGS = 1; 46 47 private static final int SHOW_RIPPLE_DURATION_MS = 266; 48 49 private static final int REQUEST_CODE_START_SETUP_ACTIVITY = 1; 50 51 private ChannelDataManager mChannelDataManager; 52 private TvInputManagerHelper mInputManager; 53 private final ChannelDataManager.Listener mChannelListener = 54 new ChannelDataManager.Listener() { 55 @Override 56 public void onLoadFinished() { 57 mChannelDataManager.removeListener(this); 58 SetupUtils.getInstance(OnboardingActivity.this).markNewChannelsBrowsable(); 59 } 60 61 @Override 62 public void onChannelListUpdated() {} 63 64 @Override 65 public void onChannelBrowsableChanged() {} 66 }; 67 68 /** 69 * Returns an intent to start {@link OnboardingActivity}. 70 * 71 * @param context context to create an intent. Should not be {@code null}. 72 * @param intentAfterCompletion intent which will be used to start a new activity when this 73 * activity finishes. Should not be {@code null}. 74 */ 75 public static Intent buildIntent( 76 @NonNull Context context, @NonNull Intent intentAfterCompletion) { 77 return new Intent(context, OnboardingActivity.class) 78 .putExtra(OnboardingActivity.KEY_INTENT_AFTER_COMPLETION, intentAfterCompletion); 79 } 80 81 @Override 82 protected void onCreate(Bundle savedInstanceState) { 83 super.onCreate(savedInstanceState); 84 ApplicationSingletons singletons = TvApplication.getSingletons(this); 85 mInputManager = singletons.getTvInputManagerHelper(); 86 if (PermissionUtils.hasAccessAllEpg(this) || PermissionUtils.hasReadTvListings(this)) { 87 mChannelDataManager = singletons.getChannelDataManager(); 88 // Make the channels of the new inputs which have been setup outside Live TV 89 // browsable. 90 if (mChannelDataManager.isDbLoadFinished()) { 91 SetupUtils.getInstance(this).markNewChannelsBrowsable(); 92 } else { 93 mChannelDataManager.addListener(mChannelListener); 94 } 95 } else { 96 requestPermissions( 97 new String[] {PermissionUtils.PERMISSION_READ_TV_LISTINGS}, 98 PERMISSIONS_REQUEST_READ_TV_LISTINGS); 99 } 100 } 101 102 @Override 103 protected void onDestroy() { 104 if (mChannelDataManager != null) { 105 mChannelDataManager.removeListener(mChannelListener); 106 } 107 super.onDestroy(); 108 } 109 110 @Override 111 protected Fragment onCreateInitialFragment() { 112 if (PermissionUtils.hasAccessAllEpg(this) || PermissionUtils.hasReadTvListings(this)) { 113 return OnboardingUtils.isFirstRunWithCurrentVersion(this) 114 ? new WelcomeFragment() 115 : new SetupSourcesFragment(); 116 } 117 return null; 118 } 119 120 @Override 121 public void onRequestPermissionsResult( 122 int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 123 if (requestCode == PERMISSIONS_REQUEST_READ_TV_LISTINGS) { 124 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 125 finish(); 126 Intent intentForNextActivity = 127 getIntent().getParcelableExtra(KEY_INTENT_AFTER_COMPLETION); 128 startActivity(buildIntent(this, intentForNextActivity)); 129 } else { 130 Toast.makeText( 131 this, 132 R.string.msg_read_tv_listing_permission_denied, 133 Toast.LENGTH_LONG) 134 .show(); 135 finish(); 136 } 137 } 138 } 139 140 private void finishActivity() { 141 Intent intentForNextActivity = getIntent().getParcelableExtra(KEY_INTENT_AFTER_COMPLETION); 142 if (intentForNextActivity != null) { 143 startActivity(intentForNextActivity); 144 } 145 finish(); 146 } 147 148 private void showMerchantCollection() { 149 executeActionWithDelay( 150 new Runnable() { 151 @Override 152 public void run() { 153 startActivity(OnboardingUtils.ONLINE_STORE_INTENT); 154 } 155 }, 156 SHOW_RIPPLE_DURATION_MS); 157 } 158 159 @Override 160 protected boolean executeAction(String category, int actionId, Bundle params) { 161 switch (category) { 162 case WelcomeFragment.ACTION_CATEGORY: 163 switch (actionId) { 164 case WelcomeFragment.ACTION_NEXT: 165 OnboardingUtils.setFirstRunWithCurrentVersionCompleted( 166 OnboardingActivity.this); 167 showFragment(new SetupSourcesFragment(), false); 168 return true; 169 } 170 break; 171 case SetupSourcesFragment.ACTION_CATEGORY: 172 switch (actionId) { 173 case SetupSourcesFragment.ACTION_ONLINE_STORE: 174 showMerchantCollection(); 175 return true; 176 case SetupSourcesFragment.ACTION_SETUP_INPUT: 177 { 178 String inputId = 179 params.getString( 180 SetupSourcesFragment.ACTION_PARAM_KEY_INPUT_ID); 181 TvInputInfo input = mInputManager.getTvInputInfo(inputId); 182 Intent intent = TvCommonUtils.createSetupIntent(input); 183 if (intent == null) { 184 Toast.makeText( 185 this, 186 R.string.msg_no_setup_activity, 187 Toast.LENGTH_SHORT) 188 .show(); 189 return true; 190 } 191 // Even though other app can handle the intent, the setup launched by 192 // Live 193 // channels should go through Live channels SetupPassthroughActivity. 194 intent.setComponent( 195 new ComponentName(this, SetupPassthroughActivity.class)); 196 try { 197 // Now we know that the user intends to set up this input. Grant 198 // permission for writing EPG data. 199 SetupUtils.grantEpgPermission( 200 this, input.getServiceInfo().packageName); 201 startActivityForResult(intent, REQUEST_CODE_START_SETUP_ACTIVITY); 202 } catch (ActivityNotFoundException e) { 203 Toast.makeText( 204 this, 205 getString( 206 R.string.msg_unable_to_start_setup_activity, 207 input.loadLabel(this)), 208 Toast.LENGTH_SHORT) 209 .show(); 210 } 211 return true; 212 } 213 case SetupMultiPaneFragment.ACTION_DONE: 214 { 215 ChannelDataManager manager = 216 TvApplication.getSingletons(OnboardingActivity.this) 217 .getChannelDataManager(); 218 if (manager.getChannelCount() == 0) { 219 finish(); 220 } else { 221 finishActivity(); 222 } 223 return true; 224 } 225 } 226 break; 227 } 228 return false; 229 } 230} 231