Home | History | Annotate | Download | only in launcher3
      1 /*
      2  * Copyright (C) 2008 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.launcher3;
     18 
     19 import android.annotation.TargetApi;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.SharedPreferences;
     24 import android.content.pm.LauncherActivityInfo;
     25 import android.content.pm.PackageInstaller;
     26 import android.content.pm.PackageInstaller.SessionInfo;
     27 import android.content.pm.PackageManager;
     28 import android.content.pm.ResolveInfo;
     29 import android.database.Cursor;
     30 import android.net.Uri;
     31 import android.os.AsyncTask;
     32 import android.os.Build;
     33 import android.os.Process;
     34 import android.os.UserHandle;
     35 import android.provider.Settings;
     36 import android.text.TextUtils;
     37 import android.util.Log;
     38 
     39 import com.android.launcher3.compat.LauncherAppsCompat;
     40 
     41 import java.util.List;
     42 
     43 /**
     44  * BroadcastReceiver to handle session commit intent.
     45  */
     46 @TargetApi(Build.VERSION_CODES.O)
     47 public class SessionCommitReceiver extends BroadcastReceiver {
     48 
     49     private static final String TAG = "SessionCommitReceiver";
     50 
     51     // The content provider for the add to home screen setting. It should be of the format:
     52     // <package name>.addtohomescreen
     53     private static final String MARKER_PROVIDER_PREFIX = ".addtohomescreen";
     54 
     55     // Preference key for automatically adding icon to homescreen.
     56     public static final String ADD_ICON_PREFERENCE_KEY = "pref_add_icon_to_home";
     57     public static final String ADD_ICON_PREFERENCE_INITIALIZED_KEY =
     58             "pref_add_icon_to_home_initialized";
     59 
     60     @Override
     61     public void onReceive(Context context, Intent intent) {
     62         if (!isEnabled(context) || !Utilities.ATLEAST_OREO) {
     63             // User has decided to not add icons on homescreen.
     64             return;
     65         }
     66 
     67         SessionInfo info = intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
     68         UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
     69 
     70         if (Process.myUserHandle().equals(user)) {
     71             if (TextUtils.isEmpty(info.getAppPackageName()) ||
     72                     info.getInstallReason() != PackageManager.INSTALL_REASON_USER) {
     73                 return;
     74             }
     75         }
     76 
     77         queueAppIconAddition(context, info.getAppPackageName(), user);
     78     }
     79 
     80     public static void queueAppIconAddition(Context context, String packageName, UserHandle user) {
     81         List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(context)
     82                 .getActivityList(packageName, user);
     83         if (activities == null || activities.isEmpty()) {
     84             // no activity found
     85             return;
     86         }
     87         InstallShortcutReceiver.queueActivityInfo(activities.get(0), context);
     88     }
     89 
     90     public static boolean isEnabled(Context context) {
     91         return Utilities.getPrefs(context).getBoolean(ADD_ICON_PREFERENCE_KEY, true);
     92     }
     93 
     94     public static void applyDefaultUserPrefs(final Context context) {
     95         if (!Utilities.ATLEAST_OREO) {
     96             return;
     97         }
     98         SharedPreferences prefs = Utilities.getPrefs(context);
     99         if (prefs.getAll().isEmpty()) {
    100             // This logic assumes that the code is the first thing that is executed (before any
    101             // shared preference is written).
    102             // TODO: Move this logic to DB upgrade once we have proper support for db downgrade
    103             // If it is a fresh start, just apply the default value. We use prefs.isEmpty() to infer
    104             // a fresh start as put preferences always contain some values corresponding to current
    105             // grid.
    106             prefs.edit().putBoolean(ADD_ICON_PREFERENCE_KEY, true).apply();
    107         } else if (!prefs.contains(ADD_ICON_PREFERENCE_INITIALIZED_KEY)) {
    108             new PrefInitTask(context).executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR);
    109         }
    110     }
    111 
    112     private static class PrefInitTask extends AsyncTask<Void, Void, Void> {
    113         private final Context mContext;
    114 
    115         PrefInitTask(Context context) {
    116             mContext = context;
    117         }
    118 
    119         @Override
    120         protected Void doInBackground(Void... voids) {
    121             boolean addIconToHomeScreenEnabled = readValueFromMarketApp();
    122             Utilities.getPrefs(mContext).edit()
    123                     .putBoolean(ADD_ICON_PREFERENCE_KEY, addIconToHomeScreenEnabled)
    124                     .putBoolean(ADD_ICON_PREFERENCE_INITIALIZED_KEY, true)
    125                     .apply();
    126             return null;
    127         }
    128 
    129         public boolean readValueFromMarketApp() {
    130             // Get the marget package
    131             ResolveInfo ri = mContext.getPackageManager().resolveActivity(
    132                     new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET),
    133                     PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_SYSTEM_ONLY);
    134             if (ri == null) {
    135                 return true;
    136             }
    137 
    138             Cursor c = null;
    139             try {
    140                 c = mContext.getContentResolver().query(
    141                         Uri.parse("content://" + ri.activityInfo.packageName
    142                                 + MARKER_PROVIDER_PREFIX),
    143                         null, null, null, null);
    144                 if (c.moveToNext()) {
    145                     return c.getInt(c.getColumnIndexOrThrow(Settings.NameValueTable.VALUE)) != 0;
    146                 }
    147             } catch (Exception e) {
    148                 Log.d(TAG, "Error reading add to homescreen preference", e);
    149             } finally {
    150                 if (c != null) {
    151                     c.close();
    152                 }
    153             }
    154             return true;
    155         }
    156     }
    157 }
    158