• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.settings.applications.appinfo;
18 
19 import android.app.AlertDialog;
20 import android.content.Context;
21 import android.content.DialogInterface;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.ResolveInfo;
25 import android.net.Uri;
26 import android.os.Bundle;
27 import android.os.UserHandle;
28 import android.support.annotation.VisibleForTesting;
29 import android.support.v7.preference.PreferenceScreen;
30 import android.text.TextUtils;
31 import android.view.Menu;
32 import android.view.MenuInflater;
33 import android.view.MenuItem;
34 import android.view.View;
35 import android.widget.Button;
36 
37 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
38 import com.android.settings.R;
39 import com.android.settings.applications.AppStoreUtil;
40 import com.android.settings.applications.LayoutPreference;
41 import com.android.settings.core.BasePreferenceController;
42 import com.android.settings.overlay.FeatureFactory;
43 import com.android.settingslib.applications.AppUtils;
44 import com.android.settingslib.core.lifecycle.Lifecycle;
45 import com.android.settingslib.core.lifecycle.LifecycleObserver;
46 import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
47 import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
48 import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
49 import com.android.settingslib.wrapper.PackageManagerWrapper;
50 
51 import java.util.List;
52 
53 public class InstantAppButtonsPreferenceController extends BasePreferenceController implements
54         LifecycleObserver, OnCreateOptionsMenu, OnPrepareOptionsMenu, OnOptionsItemSelected,
55         DialogInterface.OnClickListener {
56 
57     private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons";
58     private static final String META_DATA_DEFAULT_URI = "default-url";
59 
60     private final AppInfoDashboardFragment mParent;
61     private final String mPackageName;
62     private final PackageManagerWrapper mPackageManagerWrapper;
63     private String mLaunchUri;
64     private LayoutPreference mPreference;
65     private MenuItem mInstallMenu;
66 
InstantAppButtonsPreferenceController(Context context, AppInfoDashboardFragment parent, String packageName, Lifecycle lifecycle)67     public InstantAppButtonsPreferenceController(Context context, AppInfoDashboardFragment parent,
68             String packageName, Lifecycle lifecycle) {
69         super(context, KEY_INSTANT_APP_BUTTONS);
70         mParent = parent;
71         mPackageName = packageName;
72         mPackageManagerWrapper = new PackageManagerWrapper(context.getPackageManager());
73         mLaunchUri = getDefaultLaunchUri();
74         if (lifecycle != null) {
75             lifecycle.addObserver(this);
76         }
77     }
78 
79     @Override
getAvailabilityStatus()80     public int getAvailabilityStatus() {
81         return AppUtils.isInstant(mParent.getPackageInfo().applicationInfo)
82                 ? AVAILABLE : DISABLED_FOR_USER;
83     }
84 
85     @Override
displayPreference(PreferenceScreen screen)86     public void displayPreference(PreferenceScreen screen) {
87         super.displayPreference(screen);
88         mPreference = (LayoutPreference) screen.findPreference(KEY_INSTANT_APP_BUTTONS);
89         initButtons(mPreference.findViewById(R.id.instant_app_button_container));
90     }
91 
92     @Override
onCreateOptionsMenu(Menu menu, MenuInflater inflater)93     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
94         if (!TextUtils.isEmpty(mLaunchUri)) {
95             menu.add(0, AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU, 2, R.string.install_text)
96                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
97         }
98     }
99 
100     @Override
onOptionsItemSelected(MenuItem menuItem)101     public boolean onOptionsItemSelected(MenuItem menuItem) {
102         if (menuItem.getItemId() == AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU) {
103             final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
104             if (appStoreIntent != null) {
105                 mParent.startActivity(appStoreIntent);
106             }
107             return true;
108         }
109         return false;
110     }
111 
112     @Override
onPrepareOptionsMenu(Menu menu)113     public void onPrepareOptionsMenu(Menu menu) {
114         mInstallMenu = menu.findItem(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU);
115         if (mInstallMenu != null) {
116             if (AppStoreUtil.getAppStoreLink(mContext, mPackageName) == null) {
117                 mInstallMenu.setEnabled(false);
118             }
119         }
120     }
121 
122     @Override
onClick(DialogInterface dialog, int which)123     public void onClick(DialogInterface dialog, int which) {
124         FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
125             .action(mContext, MetricsEvent.ACTION_SETTINGS_CLEAR_INSTANT_APP, mPackageName);
126         mPackageManagerWrapper.deletePackageAsUser(
127             mPackageName, null, 0, UserHandle.myUserId());
128     }
129 
createDialog(int id)130     AlertDialog createDialog(int id) {
131         if (id == AppInfoDashboardFragment.DLG_CLEAR_INSTANT_APP) {
132             AlertDialog confirmDialog = new AlertDialog.Builder(mContext)
133                 .setPositiveButton(R.string.clear_instant_app_data, this)
134                 .setNegativeButton(R.string.cancel, null)
135                 .setTitle(R.string.clear_instant_app_data)
136                 .setMessage(mContext.getString(R.string.clear_instant_app_confirmation))
137                 .create();
138             return confirmDialog;
139         }
140         return null;
141     }
142 
initButtons(View view)143     private void initButtons(View view) {
144         final Button installButton = view.findViewById(R.id.install);
145         final Button clearDataButton = view.findViewById(R.id.clear_data);
146         final Button launchButton = view.findViewById(R.id.launch);
147         if (!TextUtils.isEmpty(mLaunchUri)) {
148             installButton.setVisibility(View.GONE);
149             final Intent intent = new Intent(Intent.ACTION_VIEW);
150             intent.addCategory(Intent.CATEGORY_BROWSABLE);
151             intent.setPackage(mPackageName);
152             intent.setData(Uri.parse(mLaunchUri));
153             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
154             launchButton.setOnClickListener(v -> mParent.startActivity(intent));
155         } else {
156             launchButton.setVisibility(View.GONE);
157             final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
158             if (appStoreIntent != null) {
159                 installButton.setOnClickListener(v -> mParent.startActivity(appStoreIntent));
160             } else {
161                 installButton.setEnabled(false);
162             }
163         }
164         clearDataButton.setOnClickListener(
165             v -> mParent.showDialogInner(mParent.DLG_CLEAR_INSTANT_APP, 0));
166     }
167 
getDefaultLaunchUri()168     private String getDefaultLaunchUri() {
169         final PackageManager manager = mContext.getPackageManager();
170         final Intent intent = new Intent(Intent.ACTION_MAIN);
171         intent.addCategory(Intent.CATEGORY_LAUNCHER);
172         intent.setPackage(mPackageName);
173         final List<ResolveInfo> infos = manager.queryIntentActivities(
174             intent, PackageManager.GET_META_DATA | PackageManager.MATCH_INSTANT);
175         for (ResolveInfo info : infos) {
176             final Bundle metaData = info.activityInfo.metaData;
177             if (metaData != null) {
178                 final String launchUri = metaData.getString(META_DATA_DEFAULT_URI);
179                 if (!TextUtils.isEmpty(launchUri)) {
180                     return launchUri;
181                 }
182             }
183         }
184         return null;
185     }
186 }
187