• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.settings.gestures;
18 
19 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
20 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
21 
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.ApplicationInfo;
26 import android.content.pm.PackageManager;
27 
28 import com.android.settings.R;
29 import com.android.settings.core.BasePreferenceController;
30 
31 import java.util.ArrayList;
32 
33 public class SystemNavigationPreferenceController extends BasePreferenceController {
34 
35     static final String PREF_KEY_SYSTEM_NAVIGATION = "gesture_system_navigation";
36     private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
37 
SystemNavigationPreferenceController(Context context, String key)38     public SystemNavigationPreferenceController(Context context, String key) {
39         super(context, key);
40     }
41 
42     @Override
getAvailabilityStatus()43     public int getAvailabilityStatus() {
44         return isGestureAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
45     }
46 
47     @Override
getSummary()48     public CharSequence getSummary() {
49         if (isEdgeToEdgeEnabled(mContext)) {
50             return mContext.getText(R.string.edge_to_edge_navigation_title);
51         } else if (isSwipeUpEnabled(mContext)) {
52             return mContext.getText(R.string.swipe_up_to_switch_apps_title);
53         } else {
54             return mContext.getText(R.string.legacy_navigation_title);
55         }
56     }
57 
isGestureAvailable(Context context)58     static boolean isGestureAvailable(Context context) {
59         // Skip if the swipe up settings are not available
60         if (!context.getResources().getBoolean(
61                 com.android.internal.R.bool.config_swipe_up_gesture_setting_available)) {
62             return false;
63         }
64 
65         // Skip if the recents component is not defined
66         final ComponentName recentsComponentName = ComponentName.unflattenFromString(
67                 context.getString(com.android.internal.R.string.config_recentsComponentName));
68         if (recentsComponentName == null) {
69             return false;
70         }
71 
72         // Skip if the overview proxy service exists
73         final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
74                 .setPackage(recentsComponentName.getPackageName());
75         if (context.getPackageManager().resolveService(quickStepIntent,
76                 PackageManager.MATCH_SYSTEM_ONLY) == null) {
77             return false;
78         }
79 
80         return true;
81     }
82 
isOverlayPackageAvailable(Context context, String overlayPackage)83     static boolean isOverlayPackageAvailable(Context context, String overlayPackage) {
84         try {
85             return context.getPackageManager().getPackageInfo(overlayPackage, 0) != null;
86         } catch (PackageManager.NameNotFoundException e) {
87             // Not found, just return unavailable
88             return false;
89         }
90     }
91 
isSwipeUpEnabled(Context context)92     static boolean isSwipeUpEnabled(Context context) {
93         if (isEdgeToEdgeEnabled(context)) {
94             return false;
95         }
96         return NAV_BAR_MODE_2BUTTON == context.getResources().getInteger(
97                 com.android.internal.R.integer.config_navBarInteractionMode);
98     }
99 
isEdgeToEdgeEnabled(Context context)100     static boolean isEdgeToEdgeEnabled(Context context) {
101         return NAV_BAR_MODE_GESTURAL == context.getResources().getInteger(
102                 com.android.internal.R.integer.config_navBarInteractionMode);
103     }
104 
isGestureNavSupportedByDefaultLauncher(Context context)105     static boolean isGestureNavSupportedByDefaultLauncher(Context context) {
106         final ComponentName cn = context.getPackageManager().getHomeActivities(new ArrayList<>());
107         if (cn == null) {
108             // There is no default home app set for the current user, don't make any changes yet.
109             return true;
110         }
111         ComponentName recentsComponentName = ComponentName.unflattenFromString(context.getString(
112                 com.android.internal.R.string.config_recentsComponentName));
113         return recentsComponentName.getPackageName().equals(cn.getPackageName());
114     }
115 
getDefaultHomeAppName(Context context)116     static String getDefaultHomeAppName(Context context) {
117         final PackageManager pm = context.getPackageManager();
118         final ComponentName cn = pm.getHomeActivities(new ArrayList<>());
119         if (cn != null) {
120             try {
121                 ApplicationInfo ai = pm.getApplicationInfo(cn.getPackageName(), 0);
122                 if (ai != null) {
123                     return pm.getApplicationLabel(ai).toString();
124                 }
125             } catch (final PackageManager.NameNotFoundException e) {
126                 // Do nothing
127             }
128         }
129         return "";
130     }
131 }
132