1 /* 2 * Copyright (C) 2020 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.settings.basic; 18 19 import android.app.Activity; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.ResolveInfo; 24 import android.database.Cursor; 25 import android.net.Uri; 26 import android.text.TextUtils; 27 import android.util.Log; 28 29 import androidx.annotation.NonNull; 30 31 import com.android.tv.settings.R; 32 33 import java.util.List; 34 35 /** Implementation of {@link BasicModeFeatureProvider}. */ 36 public class BasicModeFeatureProviderImplX implements BasicModeFeatureProvider { 37 38 private static final String TAG = "BasicModeFeatureX"; 39 40 // The string "offline_mode" is a static protocol and should not be changed in general. 41 private static final String KEY_BASIC_MODE = "offline_mode"; 42 43 @Override isBasicMode(@onNull Context context)44 public boolean isBasicMode(@NonNull Context context) { 45 final String providerUriString = context.getString(R.string.basic_mode_provider_uri); 46 if (TextUtils.isEmpty(providerUriString)) { 47 Log.e(TAG, "ContentProvider for basic mode is undefined."); 48 return false; 49 } 50 try { 51 Uri contentUri = Uri.parse(providerUriString); 52 Cursor cursor = context.getContentResolver().query(contentUri, null, null, null); 53 if (cursor != null && cursor.getCount() != 0) { 54 cursor.moveToFirst(); 55 String basicMode = cursor.getString(cursor.getColumnIndex(KEY_BASIC_MODE)); 56 return "1".equals(basicMode); 57 } 58 } catch (IllegalArgumentException | NullPointerException e) { 59 Log.e(TAG, "Unable to query the ContentProvider for basic mode.", e); 60 return false; 61 } 62 return false; 63 } 64 65 @Override startBasicModeExitActivity(@onNull Activity activity)66 public void startBasicModeExitActivity(@NonNull Activity activity) { 67 final String basicModeExitPackage = activity.getString(R.string.basic_mode_exit_package); 68 final String basicModeExitComponent = 69 activity.getString(R.string.basic_mode_exit_component); 70 final String basicModeExitData = activity.getString(R.string.basic_mode_exit_data); 71 if (TextUtils.isEmpty(basicModeExitPackage) || TextUtils.isEmpty(basicModeExitComponent) 72 || TextUtils.isEmpty(basicModeExitData)) { 73 Log.e(TAG, "Basic mode exit activity undefined."); 74 return; 75 } 76 ComponentName componentName = 77 new ComponentName(basicModeExitPackage, basicModeExitComponent); 78 Uri dataUri = Uri.parse(basicModeExitData); 79 Intent intent = new Intent().setComponent(componentName).setData(dataUri); 80 List<ResolveInfo> intentHandlingActivities = 81 activity.getPackageManager().queryIntentActivities(intent, 0); 82 for (ResolveInfo info : intentHandlingActivities) { 83 if (info.activityInfo != null && info.activityInfo.enabled) { 84 Log.d(TAG, "Starting basic mode exit activity."); 85 activity.startActivity(intent); 86 if (!activity.isFinishing()) { 87 // We finish TvSettings instead of leaving it dangling in the activity stack 88 // as the expected Activity for handling basic mode exit is a HOME that also 89 // intercepts BACK key pressing. 90 activity.finish(); 91 } 92 } 93 } 94 Log.e(TAG, "Basic mode exit activity not found."); 95 } 96 } 97