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