1 /*
2  * Copyright (C) 2017 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.accessibility;
18 
19 import android.app.Fragment;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.os.Bundle;
23 
24 import androidx.annotation.NonNull;
25 import androidx.leanback.app.GuidedStepFragment;
26 import androidx.leanback.widget.GuidanceStylist;
27 import androidx.leanback.widget.GuidedAction;
28 
29 import com.android.tv.settings.R;
30 
31 import java.util.List;
32 
33 /**
34  * Fragment for confirming [de]activation of accessibility service
35  */
36 public class AccessibilityServiceConfirmationFragment extends GuidedStepFragment {
37     private static final String ARG_LABEL = "label";
38     private static final String ARG_COMPONENT = "component";
39     private static final String ARG_ENABLING = "enabling";
40 
41     /**
42      * Callback for dialog completion
43      */
44     public interface OnAccessibilityServiceConfirmedListener {
45         /**
46          * Called when enabling/disabling was confirmed by the user, not called otherwise.
47          * @param componentName Service in question
48          * @param enabling True for enabling
49          */
onAccessibilityServiceConfirmed(ComponentName componentName, boolean enabling)50         void onAccessibilityServiceConfirmed(ComponentName componentName, boolean enabling);
51     }
52 
53     /**
54      * Create a new instance of the fragment
55      * @param cn Component of service
56      * @param label Human readable label
57      * @param enabling True for enabling
58      * @return new fragment instance
59      */
newInstance(ComponentName cn, CharSequence label, boolean enabling)60     public static AccessibilityServiceConfirmationFragment newInstance(ComponentName cn,
61             CharSequence label, boolean enabling) {
62         Bundle args = new Bundle(3);
63         prepareArgs(args, cn, label, enabling);
64         AccessibilityServiceConfirmationFragment fragment =
65                 new AccessibilityServiceConfirmationFragment();
66         fragment.setArguments(args);
67         return fragment;
68     }
69 
70     /**
71      * Put args in bundle
72      * @param args Bundle to prepare
73      * @param cn Component of service
74      * @param label Human readable label
75      * @param enabling True for enabling
76      */
prepareArgs(@onNull Bundle args, ComponentName cn, CharSequence label, boolean enabling)77     public static void prepareArgs(@NonNull Bundle args, ComponentName cn, CharSequence label,
78             boolean enabling) {
79         args.putParcelable(ARG_COMPONENT, cn);
80         args.putCharSequence(ARG_LABEL, label);
81         args.putBoolean(ARG_ENABLING, enabling);
82     }
83 
84     @NonNull
85     @Override
onCreateGuidance(Bundle savedInstanceState)86     public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
87         final CharSequence label = getArguments().getCharSequence(ARG_LABEL);
88         if (getArguments().getBoolean(ARG_ENABLING)) {
89             return new GuidanceStylist.Guidance(
90                     getString(R.string.system_accessibility_service_on_confirm_title,
91                             label),
92                     getString(R.string.system_accessibility_service_on_confirm_desc,
93                             label),
94                     null,
95                     getActivity().getDrawable(R.drawable.ic_accessibility_new_132dp)
96             );
97         } else {
98             return new GuidanceStylist.Guidance(
99                     getString(R.string.system_accessibility_service_off_confirm_title,
100                             label),
101                     getString(R.string.system_accessibility_service_off_confirm_desc,
102                             label),
103                     null,
104                     getActivity().getDrawable(R.drawable.ic_accessibility_new_132dp)
105             );
106         }
107     }
108 
109     @Override
onCreateActions(@onNull List<GuidedAction> actions, Bundle savedInstanceState)110     public void onCreateActions(@NonNull List<GuidedAction> actions,
111             Bundle savedInstanceState) {
112         final Context context = getActivity();
113         actions.add(new GuidedAction.Builder(context)
114                 .clickAction(GuidedAction.ACTION_ID_OK).build());
115         actions.add(new GuidedAction.Builder(context)
116                 .clickAction(GuidedAction.ACTION_ID_CANCEL).build());
117     }
118 
119     @Override
onGuidedActionClicked(GuidedAction action)120     public void onGuidedActionClicked(GuidedAction action) {
121         if (action.getId() == GuidedAction.ACTION_ID_OK) {
122             final ComponentName component = getArguments().getParcelable(ARG_COMPONENT);
123             final Fragment fragment = getTargetFragment();
124             final boolean enabling = getArguments().getBoolean(ARG_ENABLING);
125             if (fragment instanceof OnAccessibilityServiceConfirmedListener) {
126                 ((OnAccessibilityServiceConfirmedListener) fragment)
127                         .onAccessibilityServiceConfirmed(component, enabling);
128             } else {
129                 throw new IllegalStateException("Target fragment is not an "
130                         + "OnAccessibilityServiceConfirmedListener");
131             }
132             getFragmentManager().popBackStack();
133         } else if (action.getId() == GuidedAction.ACTION_ID_CANCEL) {
134             getFragmentManager().popBackStack();
135         } else {
136             super.onGuidedActionClicked(action);
137         }
138     }
139 }
140