Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80c20442 authored by Daniel Nishi's avatar Daniel Nishi
Browse files

Add an automatic storage management job service.

This service runs once a day when plugged in when the device has
under 15% free space remaining. If the FeatureFactory has a
storage management job, it runs the job to begin to free up space
on the device.

This is a temporary landing place and will be refactored very
quickly out of Settings.

Bug: 28600825

Change-Id: Id2ebb42a333b3b4e3daef4e50cf985fe055b85c7
parent 74cc9772
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -2971,6 +2971,22 @@
                <action android:name="android.service.quicksettings.action.QS_TILE" />
            </intent-filter>
        </service>

        <!-- Automatic storage management tasks. -->
        <service
            android:name=".deletionhelper.AutomaticStorageManagementJobService"
            android:label="@string/automatic_storage_manager_service_label"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:enabled="@bool/enable_automatic_storage_management"
            android:exported="false"/>

        <receiver android:name=".deletionhelper.AutomaticStorageBroadcastReceiver"
                  android:enabled="@bool/enable_automatic_storage_management">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <!-- This is the longest AndroidManifest.xml ever. -->
    </application>
</manifest>
+3 −0
Original line number Diff line number Diff line
@@ -43,4 +43,7 @@

    <!--Whether the storage manager exists. -->
    <bool name="config_has_storage_manager">false</bool>

    <!-- Whether the automatic storage management job should be scheduled. -->
    <bool name="enable_automatic_storage_management">false</bool>
</resources>
+3 −0
Original line number Diff line number Diff line
@@ -7649,4 +7649,7 @@
    <!-- Preference title for the automatic storage manager toggle. [CHAR LIMIT=60]-->
    <string name="automatic_storage_manager_preference_title">Storage manager</string>
    <!-- Automatic storage management service label. [CHAR LIMIT=40]-->
    <string name="automatic_storage_manager_service_label">Automatic Storage Management Service</string>
</resources>
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.deletionhelper;

import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.text.format.DateUtils;

/**
 * A {@link BroadcastReceiver} listening for {@link Intent#ACTION_BOOT_COMPLETED} broadcasts to
 * schedule an automatic storage management job. Automatic storage management jobs are only
 * scheduled once a day for a plugged in device.
 */
public class AutomaticStorageBroadcastReceiver extends BroadcastReceiver {
    private static final int AUTOMATIC_STORAGE_JOB_ID = 0;
    private static final long PERIOD = DateUtils.DAY_IN_MILLIS;

    @Override
    public void onReceive(Context context, Intent intent) {
        JobScheduler jobScheduler =
                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
        ComponentName component = new ComponentName(context,
                AutomaticStorageManagementJobService.class);
        JobInfo job = new JobInfo.Builder(AUTOMATIC_STORAGE_JOB_ID, component)
                .setRequiresCharging(true)
                .setRequiresDeviceIdle(true)
                .setPeriodic(PERIOD)
                .build();
        jobScheduler.schedule(job);
    }
}
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.deletionhelper;

import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.provider.Settings;
import android.util.Log;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.overlay.StorageManagementJobProvider;

import java.io.File;

/**
 * {@link JobService} class to start automatic storage clearing jobs to free up space. The job only
 * starts if the device is under a certain percent of free storage.
 */
public class AutomaticStorageManagementJobService extends JobService {
    private static final String TAG = "AsmJobService";
    private static final String SHARED_PREFRENCES_NAME = "automatic_storage_manager_settings";
    private static final String KEY_DAYS_TO_RETAIN = "days_to_retain";

    private static final long DEFAULT_LOW_FREE_PERCENT = 15;

    private StorageManagementJobProvider mProvider;

    @Override
    public boolean onStartJob(JobParameters args) {
        boolean isEnabled =
                Settings.Secure.getInt(getContentResolver(),
                        Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0;
        if (!isEnabled) {
            return false;
        }

        StorageManager manager = getSystemService(StorageManager.class);
        VolumeInfo internalVolume = manager.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);

        final File dataPath = internalVolume.getPath();
        if (!volumeNeedsManagement(dataPath)) {
            Log.i(TAG, "Skipping automatic storage management.");
            return false;
        }
        mProvider = FeatureFactory.getFactory(this).getStorageManagementJobProvider();
        if (mProvider != null) {
            return mProvider.onStartJob(this, args, getDaysToRetain());
        }

        return false;
    }

    @Override
    public boolean onStopJob(JobParameters args) {
        if (mProvider != null) {
            return mProvider.onStopJob(this, args);
        }

        return false;
    }

    private int getDaysToRetain() {
        SharedPreferences sharedPreferences =
                getSharedPreferences(SHARED_PREFRENCES_NAME, Context.MODE_PRIVATE);
        return sharedPreferences.getInt(KEY_DAYS_TO_RETAIN,
                AutomaticStorageManagerSettings.DEFAULT_DAYS_TO_RETAIN);
    }

    private boolean volumeNeedsManagement(final File dataPath) {
        long lowStorageThreshold = (dataPath.getTotalSpace() * DEFAULT_LOW_FREE_PERCENT) / 100;
        return dataPath.getFreeSpace() < lowStorageThreshold;
    }
}
 No newline at end of file
Loading