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

Commit b36c04ad authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Delete FinancialSmsService and friends."

parents 8dfaccfc f4dcc552
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -8095,16 +8095,6 @@ package android.service.settings.suggestions {
}
package android.service.sms {
  public abstract class FinancialSmsService extends android.app.Service {
    method public android.os.IBinder onBind(android.content.Intent);
    method @Nullable public abstract android.database.CursorWindow onGetSmsMessages(@NonNull android.os.Bundle);
    field public static final String ACTION_FINANCIAL_SERVICE_INTENT = "android.service.sms.action.FINANCIAL_SERVICE_INTENT";
  }
}
package android.service.storage {
  public abstract class ExternalStorageService extends android.app.Service {
+0 −104
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.service.sms;

import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.database.CursorWindow;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteCallback;
import android.os.RemoteException;

/**
 * A service to support sms messages read for financial apps.
 *
 * {@hide}
 */
@SystemApi
public abstract class FinancialSmsService extends Service {

    private static final String TAG = "FinancialSmsService";

    /**
     * The {@link Intent} action that must be declared as handled by a service
     * in its manifest for the system to recognize it as a quota providing
     * service.
     */
    public static final String ACTION_FINANCIAL_SERVICE_INTENT =
            "android.service.sms.action.FINANCIAL_SERVICE_INTENT";

    /** {@hide} **/
    public static final String EXTRA_SMS_MSGS = "sms_messages";

    private FinancialSmsServiceWrapper mWrapper;

    private void getSmsMessages(RemoteCallback callback, Bundle params) {
        final Bundle data = new Bundle();
        CursorWindow smsMessages = onGetSmsMessages(params);
        if (smsMessages != null) {
            data.putParcelable(EXTRA_SMS_MSGS, smsMessages);
        }
        callback.sendResult(data);
    }

    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);

    /** @hide */
    public FinancialSmsService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mWrapper = new FinancialSmsServiceWrapper();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mWrapper;
    }

    /**
     * Get sms messages for financial apps.
     *
     * @param params parameters passed in by the calling app.
     * @return the {@code CursorWindow} with all sms messages for the app to read.
     *
     * {@hide}
     */
    @Nullable
    @SystemApi
    public abstract CursorWindow onGetSmsMessages(@NonNull Bundle params);

    private final class FinancialSmsServiceWrapper extends IFinancialSmsService.Stub {
        @Override
        public void getSmsMessages(RemoteCallback callback, Bundle params) throws RemoteException {
            mHandler.sendMessage(obtainMessage(
                    FinancialSmsService::getSmsMessages,
                    FinancialSmsService.this,
                    callback, params));
        }
    }

}
+0 −30
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.service.sms;

import android.os.Bundle;
import android.os.RemoteCallback;

/**
 * Service used by financial apps to read sms messages.
 *
 * @hide
 */
oneway interface IFinancialSmsService
{
    void getSmsMessages(in RemoteCallback callback, in Bundle params);
}
 No newline at end of file
+0 −7
Original line number Diff line number Diff line
@@ -3264,13 +3264,6 @@
    <permission android:name="android.permission.BIND_TV_INPUT"
        android:protectionLevel="signature|privileged" />

    <!-- Must be required by an {@link android.service.sms.FinancialSmsService}
         to ensure that only the system can bind to it.
         @hide This is not a third-party API (intended for OEMs and system apps).
    -->
    <permission android:name="android.permission.BIND_FINANCIAL_SMS_SERVICE"
                android:protectionLevel="signature" />

    <!-- @SystemApi
         Must be required by a {@link com.android.media.tv.remoteprovider.TvRemoteProvider}
         to ensure that only the system can bind to it.
+0 −218
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.server.role;

import android.Manifest;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.sms.FinancialSmsService;
import android.service.sms.IFinancialSmsService;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * This class binds to {@code FinancialSmsService}.
 */
final class FinancialSmsManager {

    private static final String TAG = "FinancialSmsManager";

    private final Context mContext;
    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private ServiceConnection mServiceConnection;

    @GuardedBy("mLock")
    private IFinancialSmsService mRemoteService;

    @GuardedBy("mLock")
    private ArrayList<Command> mQueuedCommands;

    FinancialSmsManager(Context context) {
        mContext = context;
    }

    @Nullable
    ServiceInfo getServiceInfo() {
        final String packageName =
                mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
        if (packageName == null) {
            Slog.w(TAG, "no external services package!");
            return null;
        }

        final Intent intent = new Intent(FinancialSmsService.ACTION_FINANCIAL_SERVICE_INTENT);
        intent.setPackage(packageName);
        final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
                PackageManager.GET_SERVICES);
        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
            Slog.w(TAG, "No valid components found.");
            return null;
        }
        return resolveInfo.serviceInfo;
    }

    @Nullable
    private ComponentName getServiceComponentName() {
        final ServiceInfo serviceInfo = getServiceInfo();
        if (serviceInfo == null) return null;

        final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
        if (!Manifest.permission.BIND_FINANCIAL_SMS_SERVICE.equals(serviceInfo.permission)) {
            Slog.w(TAG, name.flattenToShortString() + " does not require permission "
                    + Manifest.permission.BIND_FINANCIAL_SMS_SERVICE);
            return null;
        }

        return name;
    }

    void reset() {
        synchronized (mLock) {
            if (mServiceConnection != null) {
                mContext.unbindService(mServiceConnection);
                mServiceConnection = null;
            } else {
                Slog.d(TAG, "reset(): service is not bound. Do nothing.");
            }
        }
    }

    /**
     * Run a command, starting the service connection if necessary.
     */
    private void connectAndRun(@NonNull Command command) {
        synchronized (mLock) {
            if (mRemoteService != null) {
                try {
                    command.run(mRemoteService);
                } catch (RemoteException e) {
                    Slog.w(TAG, "exception calling service: " + e);
                }
                return;
            } else {
                if (mQueuedCommands == null) {
                    mQueuedCommands = new ArrayList<>(1);
                }
                mQueuedCommands.add(command);
                // If we're already connected, don't create a new connection, just leave - the
                // command will be run when the service connects
                if (mServiceConnection != null) return;
            }

            // Create the connection
            mServiceConnection = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    synchronized (mLock) {
                        mRemoteService = IFinancialSmsService.Stub.asInterface(service);
                        if (mQueuedCommands != null) {
                            final int size = mQueuedCommands.size();
                            for (int i = 0; i < size; i++) {
                                final Command queuedCommand = mQueuedCommands.get(i);
                                try {
                                    queuedCommand.run(mRemoteService);
                                } catch (RemoteException e) {
                                    Slog.w(TAG, "exception calling " + name + ": " + e);
                                }
                            }
                            mQueuedCommands = null;
                        }
                    }
                }

                @Override
                @MainThread
                public void onServiceDisconnected(ComponentName name) {
                    synchronized (mLock) {
                        mRemoteService = null;
                    }
                }

                @Override
                public void onBindingDied(ComponentName name) {
                    synchronized (mLock) {
                        mRemoteService = null;
                    }
                }

                @Override
                public void onNullBinding(ComponentName name) {
                    synchronized (mLock) {
                        mRemoteService = null;
                    }
                }
            };

            final ComponentName component = getServiceComponentName();
            if (component != null) {
                final Intent intent = new Intent();
                intent.setComponent(component);
                final long token = Binder.clearCallingIdentity();
                try {
                    mContext.bindServiceAsUser(intent, mServiceConnection, Context.BIND_AUTO_CREATE,
                            UserHandle.getUserHandleForUid(UserHandle.getCallingUserId()));
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            }
        }
    }

    void getSmsMessages(RemoteCallback callback, @Nullable Bundle params) {
        connectAndRun((service) -> service.getSmsMessages(callback, params));
    }

    void dump(String prefix, PrintWriter pw) {
        final ComponentName impl = getServiceComponentName();
        pw.print(prefix); pw.print("User ID: "); pw.println(UserHandle.getCallingUserId());
        pw.print(prefix); pw.print("Queued commands: ");
        if (mQueuedCommands == null) {
            pw.println("N/A");
        } else {
            pw.println(mQueuedCommands.size());
        }
        pw.print(prefix); pw.print("Implementation: ");
        if (impl == null) {
            pw.println("N/A");
            return;
        }
        pw.println(impl.flattenToShortString());
    }

    private interface Command {
        void run(IFinancialSmsService service) throws RemoteException;
    }
}
Loading